Orcantus

Guide

Color Sort(筒を注いで色分け)の解き方 — 中級編: 「同じ色を重ねるだけ」が通用しない場面を見分ける

初級編では、「注ぎ先の一番上の色が注ぎ元の一番上の色と一致していれば、その注ぎはいつ行っても安全」という進め方だけで、後戻りなしに最後まで解ける盤面を扱いました。この中級編では、合法な注ぎが複数あり、見た目には同じような色の合流に見えても、片方だけが唯一詰みへ向かう場面を扱います。実例は容量4・5色・空筒2・シード"notes-colorsort-medium-easyset-234"で生成した盤面です(E.generate({ numColors: 5, capacity: 4, duplicateColors: 0, emptyTubes: 2, seed: 'notes-colorsort-medium-easyset-234' })、2回目の試行でこの条件を満たしました)。

Note

この実例のパラメータ(5色・容量4・空筒2)は、実は初級編の実例と同じで、Color Sort本体の「初級」設定と同じ組み合わせです。つまり、この記事でいう「中級」はアプリ側の難度が上がったという意味ではなく、同じ条件下でも「どちらへ注ぐか」の判断が必要になる場面がある、というこの解説記事シリーズの読み物としての順番を指します。アプリの「初級・中級・上級・超上級」はcolorsort/app.jsのLEVEL_PRESETS(色数・容量・同色を分ける数・空き筒数の組み合わせ)であり、生成される個々の盤面が「注ぎ方に気をつける場面を含むかどうか」までは判定していません。

結論。Color Sortでは、合法な注ぎ(注ぎ先の一番上と色が一致する、または注ぎ先が空)がその場では複数存在しても、そのうち1つだけが最終的に詰みへ向かい、他は最後まで解ける、ということが実際に起こる。 見た目だけでは区別できないため、迷ったら注いだ後の盤面に対してsolve(アプリでは「1手のヒント」)を確認するのが確実な見分け方であることを、この記事の実例(3択のうち1つだけが不可解)で示します。

まず、複数の合法手が生まれるまで進める

出題時点の盤面です(下から積まれた順、括弧内は既定で隠れる下2層)。

筒 内容(下→上)
1 (D, E), B, C
2 (C, A), D, A
3 (B, D), D, C
4 (B, A), A, E
5 (C, E), E, B
6 空
7 空

最初の2手は、初級編と同じ「注ぎ先の一番上と色が一致する、または空の筒へ」という進め方で迷わず決まります。

  1. 筒1→筒6: 筒1の一番上のC(1枚)を、空の筒6へ。筒1は(D,E),Bに。
  2. 筒1→筒7: 筒1の一番上のB(1枚)を、もう1本の空の筒7へ。筒1は(D,E)だけに(=D,Eの2枚のみ、いずれも元は隠れていた層)。

この時点の盤面は次のとおりです。

筒 内容(下→上)
1 D, E
2 (C, A), D, A
3 (B, D), D, C
4 (B, A), A, E
5 (C, E), E, B
6 C
7 B

合法な3択と、1つだけが詰みへ向かう理由

この状態で、色が一致する合法な注ぎは次の3つです(いずれも即座に不可能な理由はなく、画面上でも普通にタップして実行できます)。

候補 注ぎ 一致する色 注いだ後、最後まで解けるか
A 筒3→筒6 C(筒3の一番上・筒6の一番上とも C) 解ける(E.solveで確認)
B 筒4→筒1 E(筒4の一番上・筒1の一番上とも E) 解けない(E.solveがsolved: false, truncated: falseを返す=探索の打ち切りではなく、確認済みの詰み)
C 筒5→筒7 B(筒5の一番上・筒7の一番上とも B) 解ける(E.solveで確認)

候補Bは、筒4の一番上のE(1枚)を、筒1の一番上のE(色が一致)へ注ぐという、候補A・候補Cと見た目にはまったく同種の操作です。しかし実際に注いでみると、筒1はD,E,E(Dの上にEが2枚積み上がった状態)になり、筒4はB,A,Aになります。この記事の実例では、この1手を選んだ時点で、以後どんな順で注いでも色を揃えきることができないことをE.solveで確認しました(nodes: 28の探索で、打ち切りではなく解なしと確定)。

候補Bを実際に選んでも、この時点では画面に警告は出ません。盤面には依然として合法な注ぎ手が残っており(E.hasAnyMoveがtrue)、手詰まりですという表示(E.isDeadlocked)にもなりません。もし「1手のヒント」を押していれば、colorsort/app.jsのnextAssistMoveが内部で同じE.solveを呼び、現在の状態からは解けません。一手戻すか最初からをお試しください。という実際のメッセージが表示されます(このメッセージは、探索が上限に達した場合の「現在の状態からの解法が探索の上限内で見つかりませんでした」という別の文言とはコード上区別されており、この記事の候補Bは後者ではなく前者に該当することを確認済みです)。この注ぎは筒を完成させていないため、E.canUndoはtrueのまま(「一手戻す」で候補A・Cの状態へ戻れます)。

なぜ候補Bだけが詰みへ向かうのか(この記事での読み方)

E.solveは「解けるか・解けないか」だけを返し、理由までは説明しません。以下は、盤面の中身を見た筆者の解釈です(engineが明示的に述べている理由ではありません)。候補Bは、筒1の底に眠っているD(1枚)の上に、新たにE(1枚)を積み増します。これで筒1はD,E,Eとなり、Dを掘り出すには、いずれこの2枚のEをまた注ぎ出す必要があります。一方、候補A・候補Cはどちらも、すでに空の筒(6・7)へ同色を積み増すだけで、他の色を巻き込みません。この盤面では、それ以外の色(A・B・C・D)を捌ききるための空き容量に余裕がなく、候補Bで筒1にEを2枚積んでしまうと、そのEを注ぎ出す行き先が最後まで確保できなくなる、という状況になっていました。この読み方はこの実例固有の観察であり、「一番上の色が一致する注ぎのうち、空筒以外への合流は避けるべき」という一般的なルールとしては確認していません(次章の続きで、他の一致する合流(候補A自体も筒3→筒6という空筒経由ではない合流)がそのまま正解手順に含まれることからも分かるとおり、色の合流そのものが悪いわけではありません)。

候補Aを選んで最後まで解く

候補A(筒3→筒6)を選んだ場合の、実際にengineが確認した19手すべてです(E.solveの結果をそのままE.pourGameで適用し、最後にE.isClearedがtrueになることを確認済み)。

手 注ぎ 移る色・枚数 注ぎ後の筒の状態(下→上)
1 筒1→筒6 Cを1枚 1:DEB 2:CADA 3:BDDC 4:BAAE 5:CEEB 6:C 7:(空)
2 筒1→筒7 Bを1枚 1:DE 2:CADA 3:BDDC 4:BAAE 5:CEEB 6:C 7:B
3 筒3→筒6 Cを1枚(候補A) 1:DE 2:CADA 3:BDD 4:BAAE 5:CEEB 6:CC 7:B
4 筒5→筒7 Bを1枚 1:DE 2:CADA 3:BDD 4:BAAE 5:CEE 6:CC 7:BB
5 筒5→筒1 Eを2枚 1:DEEE 2:CADA 3:BDD 4:BAAE 5:C 6:CC 7:BB
6 筒6→筒5 Cを2枚 1:DEEE 2:CADA 3:BDD 4:BAAE 5:CCC 6:(空) 7:BB
7 筒1→筒6 Eを3枚 1:D 2:CADA 3:BDD 4:BAAE 5:CCC 6:EEE 7:BB
8 筒3→筒1 Dを2枚 1:DDD 2:CADA 3:B 4:BAAE 5:CCC 6:EEE 7:BB
9 筒7→筒3 Bを2枚 1:DDD 2:CADA 3:BBB 4:BAAE 5:CCC 6:EEE 7:(空)
10 筒2→筒7 Aを1枚 1:DDD 2:CAD 3:BBB 4:BAAE 5:CCC 6:EEE 7:A
11 筒1→筒2 Dを1枚 1:DD 2:CADD 3:BBB 4:BAAE 5:CCC 6:EEE 7:A
12 筒2→筒1 Dを2枚 1:DDDD(完成) 2:CA 3:BBB 4:BAAE 5:CCC 6:EEE 7:A
13 筒2→筒7 Aを1枚 1:DDDD 2:C 3:BBB 4:BAAE 5:CCC 6:EEE 7:AA
14 筒5→筒2 Cを3枚 1:DDDD 2:CCCC(完成) 3:BBB 4:BAAE 5:(空) 6:EEE 7:AA
15 筒4→筒5 Eを1枚 1:DDDD 2:CCCC 3:BBB 4:BAA 5:E 6:EEE 7:AA
16 筒6→筒5 Eを3枚 1:DDDD 2:CCCC 3:BBB 4:BAA 5:EEEE(完成) 6:(空) 7:AA
17 筒4→筒6 Aを2枚 1:DDDD 2:CCCC 3:BBB 4:B 5:EEEE 6:AA 7:AA
18 筒3→筒4 Bを3枚 1:DDDD 2:CCCC 3:(空) 4:BBBB(完成) 5:EEEE 6:AA 7:AA
19 筒6→筒7 Aを2枚 1:DDDD 2:CCCC 3:(空) 4:BBBB 5:EEEE 6:(空) 7:AAAA(完成)

19手を終えた時点でE.isClearedがtrue(色が揃い、隠れていた10個の「?」もすべて露出済み)であることを確認しました。最終盤面は、筒1=D4枚・筒2=C4枚・筒3=空・筒4=B4枚・筒5=E4枚・筒6=空・筒7=A4枚です。

誤りやすい判断

読者の検証方法

この記事が確認していないこと

この結果が言っていないこと

  • 検証はcolorsort/engine.js・colorsort/app.js(いずれも記事執筆時点、生成結果のversion: 2で確認)を対象にしています。将来の版で表示・判定基準が変わる可能性があります。
  • 「候補A」「候補B」「候補C」という呼び方はこの記事独自の説明用の表記です。アプリ本体の画面上にはこのような候補の一覧表示はありません。