Note
この記事でいう「初級・中級・上級」は、この解説記事を3段階に分けた読み物としての順番です。Signal本体が問題ごとに表示する初級・中級・上級のラベル(difficulty.level)とは判定基準が異なるため、同一視しないでください。もっとも、初級編で使う実例は、Signal側のラベルでも実際に「初級」と判定された問題です(後述)。
結論。Signalの合法手は「タイルを1回タップして時計回りに90°回転させる」ことだけ。盤の端に近いタイルほど、置ける向きの数が形状によって早い段階で1通りに決まり、そこから隣接マスとの整合性を辿るだけで、多くのマスが「試さずに」確定する。 この記事の実例(4×4・16マス)は、この境界+隣接の確定だけで最後の1マスまで解け、一度も「仮に置いてみる」判断を必要としません。
タイルの見方: 5つの形と、回転してもしなくても形は変わらない
各タイルは、上下左右のどこに線が伸びているかで見た目が決まります。伸びている方向の数によって、次の5形状のどれかになります(4×4盤の場合)。
| 形状 | 伸びる方向の数 | 回転でできる見た目の種類 |
|---|---|---|
| 端点 | 1方向 | 4種類(上/右/下/左) |
| 直線 | 2方向(向かい合う) | 2種類(縦/横) |
| エルボー(L字) | 2方向(隣り合う) | 4種類 |
| T字 | 3方向 | 4種類 |
| 十字 | 4方向 | 1種類(回転しても変わらない) |
タップしても形状そのものは変わりません。 1回タップするたびに、接続方向の集合全体が時計回り90°分ずれるだけです(直線なら縦↔横の2状態、十字なら常に同じ見た目、というように)。つまり、あるマスに「端点」タイルが置かれているなら、そのマスの答えは最後まで「どこか1方向に伸びる端点」であり、直線や十字に変わることは絶対にありません。解くとは、形状を変えることではなく、すでに決まっている形状の向きを当てることです。
盤中央には少し大きい丸(信号源)があるマスが1つあり、そこから実際につながっている(=「点灯」している)マスが色で示されます。画面下の「◯ / 総マス数 接続」という表示が、今つながっているマスの数です。全マスが点灯し、かつ「接続完了」の表示が出たときだけがクリアです。 部分的に多く点灯していても、途中で線が枝分かれしていたり輪(ループ)ができていたりすると、その形はクリア条件を満たしません(Signalの完成条件は「輪がなく、全マスが1本の木でつながっている」ことです)。
使える操作(合法手)
- タイルをタップ: そのタイル1つだけを時計回りに90°回転。これが唯一の「手」です。同じタイルを4回タップすると元の向きに戻ります(形状によっては1〜2回で元に戻って見えることもありますが、内部的には4回転で1周です)。
- 「一手戻す」: 直前の回転を1回分取り消します。
- 「1マスの答え」: まだ答えと違う向きのマスを1つだけ、自動で正しい向きに直します(この記事では以下「ヒント」と呼びます)。
- 「答えを見る」: 残り全マスを一括で正しい向きに直します(「1マスの答え」「答えを見る」のどちらを使っても、クリア自体はできますが「解答補助あり」の扱いになります)。
回転以外の操作(タイルの入れ替え・削除など)はありません。
実例: 4×4盤を境界+隣接だけで解く
n=4・シード"notes-solve-easy"・難度指定easyで生成した盤面です(E.generate(4, 'notes-solve-easy', 'easy')、1回目の試行でこの条件を満たし、実際にSignal側の難度判定でもlevel: "easy"でした)。出題時点(タップ前)の各マスの形状と、伸びている方向は次のとおりです(行1列1が左上)。
| 列1 | 列2 | 列3 | 列4 | |
|---|---|---|---|---|
| 行1 | 端点(上) | 端点(下) | T字(右下左) | エルボー(上左) |
| 行2 | T字(上右左) | 直線(右左) | エルボー(上左) | 直線(上下) |
| 行3 | エルボー(下左) | T字(上右左) | エルボー(上左) | 直線(右左) |
| 行4 | 端点(左) | エルボー(上左) | 端点(左) | 端点(下) |
手順1: 盤の端に接するマスから、形状だけで向きが1通りに決まるものを探す
盤の端(row1・col1・row4・col4)にあるマスは、外側に線を伸ばすことができません。この制約だけで、いくつかのマスは他のマスの状態を見るまでもなく向きが確定します。
- 行1列3(T字)は上端。 T字は4方向のうち1方向だけを欠く形です。「上に伸びてはいけない」という制約を満たすT字の向きは、「上を欠く」ちょうど1通り(右・下・左)しかありません。他の3通り(下を欠く/右を欠く/左を欠く)はいずれも上に線を伸ばしてしまうため、盤の端という情報だけでこの1マスが確定します。
- 同じ理由で、行2列1(T字・左端)は「左を欠く」1通り(上・右・下)、行2列4(直線・右端)は「横向きは右へはみ出すので不可」で縦向き1通り(上・下)、**行3列4(直線・右端)も同様に縦向き1通り(上・下)**に、それぞれ他のマスを見ずに確定します。
- 行1列4(エルボー・右上の角)は、外へ出せない方向が2つ(上・右)重なる角のマスです。 エルボーはもともと2方向にしか伸びないため、「使える方向がちょうど2つ(下・左)しかない角」に置かれたエルボーは、それだけで完全に1通りに決まります(下・左)。
この時点(境界の制約だけ)で、16マス中5マス(行1列3・行1列4・行2列1・行2列4・行3列4)が、他のどのマスも見ずに確定します。これはSignal側の難度判定が記録するboundaryFixed(境界だけで確定するマス数)と一致し、この盤面ではboundaryFixed: 5でした。
手順2: 確定したマスから、隣のマスへ「つながる/つながらない」を伝える
境界だけでは決まらない残り11マスは、隣接マスとの整合性で芋づる式に確定します。ルールは単純です。あるマスが「隣へ伸びている」と確定していれば、隣のマスは必ずこちらへ伸び返さなければならず、逆に「隣へ伸びていない」と確定していれば、隣のマスはこちらへ伸びてはいけません。
具体例で追ってみます。
- 行1列1(端点・左上の角) は、使える方向が右・下の2通りに絞られています(左上の角なので上・左は使えません)。真下の行2列1はすでに「上・右・下」に確定済みで、この中に「上」が含まれています。つまり行2列1は行1列1へ向かって確実に伸びています。端点である行1列1は、これを受けて「下」に伸び返すしかありません。行1列1の向きが、右か下かの2択から、下の1通りに絞られます。
- 行1列2(端点) は、使える方向が右・下・左の3通り(上端なので上は不可)。左隣の行1列1は今「下」に確定したばかりで、右方向には伸びていません。したがって行1列2は左へ伸びられません(左を除外)。右隣の行1列3はすでに「右・下・左」に確定していて、この中の「左」は行1列2へ向かって伸びていることを意味します。端点である行1列2は、これを受けて「右」で伸び返すしかありません。3択が「右」の1通りに絞られます。
このように、「まだ形の向きが決まっていないマス」でも、隣のマスがすでに確定していれば、端点や直線のように選択肢が少ない形状から先に、次々と1通りに絞り込めます。この盤面では、この隣接チェックを3巡繰り返すだけで、16マス全部が確定します(Signal側の難度判定でもlocalRounds: 3・needsSearch: false、つまり「仮置きして試す」場面が一度もなく済んでいます)。
手順3: 確定した向きに合わせてタップする
最終的に決まる16マスの向きと、出題時点からの向きとの差(時計回りに何回タップするか)は次のとおりです(マス番号は行1列1を0として、行→列の順で0〜15)。
マス: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
タップ回数: 2 3 0 3 1 0 0 0 2 2 3 1 2 0 1 2
合計22回のタップです。実際にこの回数どおりにタップした結果が、この記事の執筆時点でE.isSolved(board, 4)により正解と一致することを確認済みです(Node.jsでsignal/engine.jsを直接実行して検証。実際のブラウザUIでも、盤中央(行3列3、マス番号10)の信号源からのBFSで全16マスが点灯し、進捗表示が「16 / 16 接続」になることと対応します)。
誤りやすい判断
- 「回転すれば別の形になるはず」と考えて、形状の違うタイルへの変化を期待しない。 タップは向きを変えるだけで、伸びる方向の数(端点・直線・エルボー・T字・十字の区別)は最初から固定です。
- 境界(盤の端)の制約は、角(2方向同時に制約がかかる)と辺(1方向だけ制約がかかる)で効き方が違います。 角にあるエルボーは即座に1通りに決まりますが、辺にあるエルボーは通常2通りまでしか絞れず、隣接マスの情報が追加で必要です。
- タップ回数を数え違えないこと。 1回のタップは時計回り90°で、4回で元に戻ります。目標の向きが「反時計回りに1回」であっても、実際には時計回りに3回タップする必要があります(逆回転のタップはありません)。
読者の検証方法
- この記事と同じ盤面は、
n=4・シードnotes-solve-easy・難度指定easyで誰でも再現できます(Signal本体のリプレイ機能にシード欄があるほか、signal/engine.jsをrequireしてE.generate(4, 'notes-solve-easy', 'easy')を実行しても同じ結果が得られます。シード付き乱数が決定的であることは、生成ロジックを扱った別記事(その1)で確認済みです)。 - 自分の手順が合っているか不安な場合は、1マスずつヒントで答え合わせしながら進められます(ヒントを使うと「解答補助あり」の扱いになりますが、手順の検証には支障ありません)。
- 全部自力で確定させたあとは、タップ前に画面下の進捗表示(「◯ / 16 接続」)を見ながら1手ずつ進めると、狙った通りに点灯が増えていくかを都度確認できます。
この記事が確認していないこと
- 「境界+隣接だけで解ける」という手順は、この記事の実例(難度
easy)固有の展開です。Signal側の初級(easy)ラベルの定義自体が「局所推論のみで8段以下・境界確定20%以上」(README記載)なので、初級ラベルの問題であれば同種の手順で解けるはずですが、すべての初級問題で同じ順番・同じマス数の確定が起きることまでは検証していません。 - 中級・上級の問題で必要になる「仮に置いて試す」判断は扱っていません。中級編(その2)・上級編(その3)で扱います。
この結果が言っていないこと
- 検証は
signal/engine.js・signal/app.js(エンジンv3、2026-09-29時点)を対象にしています。将来の版で表示・判定基準が変わる可能性があります。 - 表内の形状名(端点・直線・エルボー・T字・十字)は、この記事独自の呼び方です。Signal本体の画面上には形状名の表示はなく、実際のUIはタイルの絵と点灯状態のみで判断します。