Note
この記事でいう「初級・中級・上級」は、この解説記事を3段階に分けた読み物としての順番です。Loop本体のスタート画面には「盤面サイズ(難易度の保証ではありません)」という注記つきで4×4・5×5・6×6を選ぶだけの欄があり(loop/index.htmlの実際の表記)、クリア後の得点計算も盤サイズだけで初級・中級・上級のレベルを決めています(loop/rating.jsのLEVEL_BY_SIZE = { 4: 'easy', 5: 'medium', 6: 'hard' })。つまりLoop自身は「このシード・この盤面が解く上でどれくらい難しいか」を判定していません。この記事の初級・中級・上級は、あくまでこの記事が選んだ実例の解きやすさを指し、盤サイズとも完全には対応しません(初級編の実例は4×4、中級編は5×5、上級編は6×6ですが、これはLoop側の判定基準ではなく筆者による選定です)。
結論。Loopの数字は「そのマスの4辺のうち輪の一部になる辺の本数」を表し、輪は各格子点を必ず0本(通らない)か2本(通過する)で通る。盤面が0や4といった極端な数字を含み、その周辺の格子点で0本/2本ルールが次々に効く場合、仮定を一度も置かずに、数字の制約と格子点の制約を交互に見ていくだけで最後の1辺まで確定することがある。 この記事の実例(4×4・16マス・40辺)は、まさにこの繰り返しだけで6ラウンドのうちに全40辺が確定し、実際の完成形(答えの輪)と完全に一致します。
盤面の見方: マスの数字と、辺・格子点という3つの要素
Loopの盤はn×n個のマスですが、プレイヤーが実際にタップして輪を描くのは、マスとマスの境界線である辺です。n×nマスの周りには(n+1)×(n+1)個の格子点(辺の交わる点)があり、辺はこの格子点と格子点を結ぶ線分です。この記事では格子点を1始まりで「点(行,列)」(例: 盤の左上端は点(1,1))、マスも1始まりで「行r列c」と呼びます。
- **マスの数字(0〜4)**は、そのマスを囲む4辺(上下左右)のうち、輪の一部として選ばれている辺の本数を表します。数字のないマス(空欄)には制約がありません。
- 格子点のルール: 輪は分岐せず、途中で終わらない、ひとつながりの単純な輪です。そのため、どの格子点でも、そこに接続する辺のうち輪の一部になっているものは必ず0本か2本です(1本だけ・3本以上は輪の形として成立しません)。盤の角にある格子点は接続しうる辺が2本しかなく、辺にある格子点は3本、内側の格子点は4本です。
使える操作(合法手)
- 辺をタップ: その辺1本の状態を「空白→輪(線)→×印(輪ではないという自分用の印)→空白」の順に切り替えます(
loop/app.jsのtapEdge)。×印は正式なルール上の意味を持たず、プレイヤーが「ここは通さない」と判断した箇所を忘れないための目印です。 - 「一手戻す」: 直前の1回のタップ(1辺分の状態変化)だけを取り消します。
- 「1辺のヒント」: まだ答えと状態が違う辺を1本だけ、自動で正しい状態(輪か空白)に直します。×印がついていても、ヒントは輪か空白のどちらかにするだけで、×印をそのまま残すことはありません。
- 「答えを見る」: 残り全辺を一括で正しい状態に直します(「1辺のヒント」「答えを見る」のどちらを使っても、クリア自体はできますが「解答補助あり」の扱いになります)。
回転や辺の追加・削除はありません。タップで切り替わる3状態(空白・輪・×印)のうち、実際の判定(クリア条件)で意味を持つのは「輪かどうか」だけです。
盤の下には、現在輪になっている辺の本数(「◯ 本の辺が輪」)が表示されます。全マスの数字が満たされ、かつ選ばれた辺全体がひとつながりの単純な輪(分岐なし・途中で閉じた輪を含まない)になったときだけがクリアです。 数字を超過しているマスがあれば「数字を超過」という警告が、輪が閉じているのに数字と食い違うマスが残っていれば別の警告が、それぞれ画面に表示されます(loop/app.jsのclueWarningMessage)。
実例: 4×4盤を、仮定なしで最後まで解く
n=4・シード"notes-loop-easy-scan-43"で生成した盤面です(E.generate(4, 'notes-loop-easy-scan-43')、1回目の試行でこの条件を満たしました)。出題時点の数字配置は次のとおりです(.は空欄)。
+ + + + +
0 1
+ + + + +
+ + + + +
3 0 0 2
+ + + + +
1
+ + + + +
見えている数字は7個だけ(行1列1=0、行1列2=1、行3列1=3、行3列2=0、行3列3=0、行3列4=2、行4列3=1)で、残り9マスは空欄です。
ラウンド1: 数字の0が、4辺すべてを「輪でない」に決める
数字が0のマスは、4辺すべてが輪に参加しないことが即座に決まります(0本選ぶには、4辺とも選ばないしかありません)。この盤面には数字0のマスが3つ(行1列1・行3列2・行3列3)あり、この時点で合計11辺が「輪でない」に確定します。
さらに、この3マスぶんの確定を受けて、格子点の0本/2本ルールが働く箇所が4か所あります。たとえば点(1,2)(行1列1と行1列2の間、盤の上端)には辺が3本接続しますが、行1列1の数字0によってそのうち2本(点(1,1)-点(1,2)・点(1,2)-点(2,2))がすでに「輪でない」に確定しているため、残る1本(点(1,2)-点(1,3))が「輪でない」でなければ、その格子点の本数が1本になってしまい0本/2本ルールに反します。したがって点(1,2)-点(1,3)も「輪でない」に決まります。同様の理由で、点(2,1)-点(3,1)・点(2,3)-点(3,3)・点(4,3)-点(5,3)の3辺も「輪でない」に決まり、ラウンド1で合計15辺が確定します。
ラウンド2〜4: 数字の3・2・1と、格子点のルールが芋づる式に効く
- 行3列1の数字3は、4辺のうち3本が輪になるという意味です。この時点で4辺とも未確定でしたが、もし4辺のうち1本でも「輪でない」に決まれば、残り3本は全部「輪」で確定します。実際には、このマスの4辺はいずれも他のマスの制約から先に「輪でない」に決まることはなかったため、ラウンド2の時点でこの数字3自体は他の辺の状態を必要とせず、「4辺のうち3本」という制約を満たす組み合わせが、格子点ルールとの突き合わせで1通りに絞られていきます(点(4,1)の0本/2本ルールが、行3列1の3本確定と組み合わさって、点(4,1)-点(5,1)を「輪でない」に、点(4,2)-点(5,2)を「輪」に決めます)。
- 行4列3の数字1(ラウンド3)・行3列4の数字2(ラウンド4)も、同様に隣接する格子点のルールと交互に効き合いながら、1辺ずつ確定していきます。
この過程をすべて示すと次のとおりです(edge = 輪は輪として確定、edge = 輪でないは空白として確定)。
| ラウンド | 確定した辺 | 根拠 |
|---|---|---|
| 1 | 点(1,1)-点(1,2)・点(2,1)-点(2,2)・点(1,1)-点(2,1)・点(1,2)-点(2,2) | 行1列1(数字0) |
| 1 | 点(3,2)-点(3,3)・点(4,2)-点(4,3)・点(3,2)-点(4,2)・点(3,3)-点(4,3) | 行3列2(数字0) |
| 1 | 点(3,3)-点(3,4)・点(4,3)-点(4,4)・点(3,4)-点(4,4) | 行3列3(数字0) |
| 1 | 点(1,2)-点(1,3)・点(2,1)-点(3,1)・点(2,3)-点(3,3)・点(4,3)-点(5,3) | 点(1,2)・点(2,1)・点(3,3)・点(4,3)の0本/2本ルール |
| 2 | 点(3,1)-点(3,2)・点(4,1)-点(4,2)・点(3,1)-点(4,1) | 行3列1(数字3) |
| 2 | 点(2,2)-点(3,2)・点(4,1)-点(5,1)・点(4,2)-点(5,2)・点(5,1)-点(5,2)・点(5,2)-点(5,3) | 点(3,2)・点(4,1)・点(4,2)・点(5,1)・点(5,2)の0本/2本ルール |
| 3 | 点(4,4)-点(5,4) | 行4列3(数字1) |
| 3 | 点(2,2)-点(2,3)・点(4,4)-点(4,5)・点(5,4)-点(5,5)・点(4,5)-点(5,5) | 点(2,2)・点(4,4)・点(5,4)・点(5,5)の0本/2本ルール |
| 4 | 点(1,3)-点(2,3)・点(3,4)-点(3,5)・点(3,5)-点(4,5) | 行1列2(数字1)・行3列4(数字2) |
| 4 | 点(1,3)-点(1,4)・点(2,3)-点(2,4)・点(2,4)-点(3,4)・点(2,5)-点(3,5) | 点(1,3)・点(2,3)・点(3,4)・点(3,5)の0本/2本ルール |
| 5 | 点(2,4)-点(2,5)・点(1,4)-点(2,4)・点(1,5)-点(2,5) | 点(2,4)・点(2,5)の0本/2本ルール |
| 6 | 点(1,4)-点(1,5) | 点(1,4)の0本/2本ルール |
ラウンド7では変化がなくなり(=これ以上絞れる辺がなくなり)、この時点で全40辺がちょうど確定しています(loop/engine.jsのpropagate関数をNode.js上で直接実行し、この盤面のクルーに対して一度も分岐探索(仮定)に入らず全辺が確定することを確認済みです)。完成形は次のとおりです。
+ + + + +
0 1
+ +---+---+ +
| |
+---+ + +---+
| 3 0 0 2 |
+---+ + + +
| 1 |
+ +---+---+---+
この輪が、出題時点の全数字と一致し、かつ分岐や孤立した輪を含まないひとつながりの単純な輪であることは、loop/engine.jsのvalidateLoop関数(数字の一致とisClosedLoopの両方を検証)で確認済みです。またこの完成形は、E.generateが実際に生成時点で持っていた「答えの輪」(answerフィールド)と1辺の違いもなく一致します。
誤りやすい判断
- 「数字が0だから、そのマスは何もしなくていい」と考えない。 数字0のマスは「4辺とも輪でない」という強い情報を持ちます。むしろ最初に手をつけるべき手がかりです。
- 格子点のルールは、マスの数字とは別の場所でも独立に効きます。 数字のないマスの周りでも、隣接する辺がすでに確定していれば、格子点の0本/2本ルールだけで新しい辺が決まることがあります(上の表の「点(◯,◯)の0本/2本ルール」の行がその例です)。数字がある場所だけを見ていると、これらの確定を見落とします。
- ×印(2回タップ)と空白(3回タップで元に戻る)を混同しない。 ×印はルール上「輪でない」と同じ意味を持つプレイヤー用の目印ですが、盤面の判定処理(
clueViolations・isClosedLoop)は状態が「輪(1)」かどうかしか見ておらず、×印と空白を区別しません。数字の本数を数えるときは、×印のマスも「輪でない」として数えて問題ありません。
読者の検証方法
- この記事と同じ盤面は、
n=4・シードnotes-loop-easy-scan-43で誰でも再現できます(Loop本体のリプレイ機能にシード欄があるほか、loop/engine.jsをrequireしてE.generate(4, 'notes-loop-easy-scan-43')を実行しても同じ結果が得られます)。 - 自分の手順が合っているか不安な場合は、1辺ずつ**「1辺のヒント」**で答え合わせしながら進められます(ヒントを使うと「解答補助あり」の扱いになりますが、手順の検証には支障ありません)。
- 全部自力で確定させたあとは、タップ前に画面下の進捗表示(「◯ 本の辺が輪」、この盤面では最終的に14本)を見ながら1手ずつ進めると、狙った通りに輪が伸びていくかを都度確認できます。
この記事が確認していないこと
- 「数字の制約と格子点の制約だけで、仮定なしに全辺が確定する」という展開は、この記事の実例(4×4・このシード)固有のものです。Loopには難易度を事前に判定する仕組み(
analyzeDifficultyのような関数)が実装されていないため、別の4×4盤面や、同じシードでも別のサイズで同じ展開になることは保証されません(実際、この記事を書く過程で試した他の4×4シードの多くは、この手順だけでは全辺が確定せず、中級編で扱う「仮に置いて確かめる」判断が必要でした)。 - 数字の制約と格子点の制約が、どういう順番・組み合わせで効くと最も早く解けるかという「最適な手順」は扱っていません。この記事の表は、実際に
propagate関数が辿った順序をそのまま示したものです。 - 中級・上級で必要になる「仮に置いて確かめる」判断は扱っていません。中級編(その2)・上級編(その3)で扱います。
この結果が言っていないこと
- 検証は
loop/engine.js・loop/app.js(エンジンv1、2026-09-29時点)を対象にしています。将来の版で表示・判定基準が変わる可能性があります。 - 表内の「点(行,列)」「行◯列◯」という呼び方は、この記事独自の説明用の表記です。Loop本体の画面上にはこのような座標表示はなく、実際のUIは格子点と辺の見た目のみで判断します。