見出し画像

【AIとつくったペンシルパズル】ライアーコンパス

ChatGPTと新しいペンシルパズルを作ることに挑戦してみました!

前回の挑戦はこちら。


今回も、私とChatGPTが協力してパズルのルールやコードを作成しました。今回は、「ライアーコンパス」と名付けたパズルをご紹介します。ChatGPT o1-previewと一緒にルール問題を生成したパズルです。(シンプルなルールなので、全く同じパズルをすでに考案している人がいるかもしれません。)

この記事は「ライアーコンパス」パズルについての紹介だけでなく、ChatGPT o1-previewの活用方法についても触れています。また、サムネイル画像はChatGPT 4oが生成したものです。
今回は大変な挑戦となりました。

パズルの概要

ルール

  1. 黒マスのペア配置:

    • グリッドの中にはいくつかの黒マスがあり、 黒マスは必ず2つ1組でペアを組んで配置されます。

    • 1つの黒マスには、隣接する他の黒マスが1つだけで、黒マス同士が複数繋がることはありません(ペア以外の黒マスと隣接してはいけません)。

    • 黒マスに書かれていた数字は、特に意味を持ちません。無視してかまいません。

  2. 白マスと数字:

    • 黒マス以外のセルは白マスです。

    • 白マスに書かれている数字は、その数字から上下左右4方向にまっすぐ進んで、外周か黒マスにたどりつくまでの、その数字を含めての白マスの数の合計を表します。

  3. 白マスの連続

    • 黒マスによって盤面が分断されてはいけません。すべての白マスはひとつながりにつながります。

  4. パズルの目的:

    • パズルの目的は、グリッド内に黒マスを正しくペアで配置し、全ての白マスの数字が正確に対応するように、白マスが黒マスで分断されないようにグリッドを完成させることです。

例題

左が問題、右が答え

まず、2行目3列目の「2」に注目します。このマスが白マスだとすると、盤面が黒マスによって分断されてしまいます。

どのように白マスを配置しても、白マスが一つながりにならない

つまり、このマスは黒マスだとわかります。

左下の6を黒マスにすると、黒マスを2つ1組でペアにして、ペア以外の黒マスと隣接してはいけないというルールを満たせません。このことから、左下の6は白マスだとわかります。

左下の6は白マス

白マスに書かれている数字は、その数字から上下左右4方向にまっすぐ進んで、外周か黒マスにたどりつくまでの、その数字を含めての白マスの数の合計を表します。そのため、下記の白マスが確定します。

ここが黒マスだと、6マスに満たなくなる

2列目4行目の「3」が白マスなので、左下の「3」は黒マスだとわかります。

ここが白マスだと、3マスを超えてしまう

左下の黒マスを2つ1組でペアにします。

ペア以外の黒マスと隣接してはいけないので、このペアに接するマスは白マスに確定します。

2列目3行目の黒マスを2つ1組でペアにします。

こんな感じで解いていくことができます。

今回の問題

問1

問2

問3

ちゃんと手筋の連続で解くことができます

ChatGPT o1-preview への指示文

最初のプロンプト

このパズルを作成するために、以下のプロンプトをChatGPT o1-previewに与えました。

Prompt

4×4くらいの小さいグリッドサイズから楽しめる、数字を使わない新しいペンシルパズルのルールを考えてください。さらに、そのパズルの問題を作るpythonコードを書いてください。さらに、そのパズルの問題を解くpythonコードを作成し、解が一つしかないことを確認するようにしてください。解が一つになるまで、問題を修正するようにコーディングしてください。コードは、現実的な時間で実行できるように工夫してください。

ポイント

  1. 一度にすべての要求を盛り込む:ChatGPT o1-previewの場合、プロンプトにすべての指示を盛り込むと、複数回のやり取りをせずに問題生成がスムーズに進みます。

  2. Pythonコードを経由する:直接パズル問題を生成させるのではなく、Pythonコードを介することでルールに破綻のない問題を作成することができます。ただし、実行に時間がかかりすぎることがあるため、試行錯誤が必要です。


ペアリンクのルール

ChatGPTが提案してきた最初のルールは、以下のようなものでした。

  1. 黒マスを配置する:グリッド上のいくつかのセルを黒く塗りつぶします。

  2. 黒マスはペアになる:黒マスは必ず隣接(上下左右)する1つの黒マスとペアにならなければなりません。一つの黒マスが複数の黒マスと隣接してはいけません。

  3. 白マスは連結:全ての白マス(塗られていないセル)は一つながりの領域を形成しなければなりません。

  4. 2×2の黒マス禁止:2×2の領域が全て黒マスになることは許されません。


このルールは一見してつまらなそうです。また、ルール2があればルール4は自動的に満たすため、少し冗長に感じました。そこで、数字を使うことを許可し、ルールを再考させました。

このルールをベースに、数字を使ってもよいので、別のバリエーションを考えてください

ペアリンク・ナンバーのルール

ChatGPTが再考したルールは、よりパズルらしいものになりました。

  1. 数字のセル:グリッドの一部のセルに数字が書かれています。これらのセルは必ず白マスです。

  2. 数字の意味:各数字は、そのセルを含めて、上下左右に連続する白マスの数を示します(黒マスまたはグリッドの端にぶつかるまで数えます)。

  3. 黒マスのペア:黒マスは隣接(上下左右)する1つの黒マスとだけ隣接します。つまり、黒マスはペアで存在し、一つの黒マスが複数の黒マスと接してはいけません。

  4. 白マスの連結:全ての白マスは一つながりの領域を形成しなければなりません。

  5. 2×2の黒マス禁止:2×2の領域が全て黒マスになることは許されません。

ライアーコンパス最終ルールの確定

このルールをベースにして、私は最終的に「黒マスの数字は無視してよい」という、ライアースイーパーのアイデアを流用しました。これにより、黒マスの数字に何を入れるかで難易度や解き味を調整できるようになり、個人的に気に入っています。

少しだけ面白くなりましたが、まだつまらないです。次のルールに変更してみてください。

ペアリンクのルール:
黒マスを配置する:グリッド上のいくつかのセルを黒く塗りつぶします。 黒マスはペアになる:黒マスは必ず隣接(上下左右)する1つの黒マスとペアにならなければなりません。一つの黒マスが複数の黒マスと隣接してはいけません。
白マスは連結:全ての白マス(塗られていないセル)は一つながりの領域を形成しなければなりません。
数字のセル:数字が書かれたセルが白マスの場合、数字はそのセルから上下左右に連続する白マスの数を正確に示します。数字が書かれたセルが黒マスの場合、そこに書かれている数字は無視できます。 すべてのセルに数字が書かれています。

生成の難しさ

しかし、問題はここからです。解が一つしかないことの確認に非常に時間がかかり、何度もo1-previewやo1-miniとやり取りしました。当初はバックトラッキングで解いていましたが、最適化を試みたものの、正しく動作せず。結局、シンプルなバックトラッキングのコードを少しだけ高速化し、それを使って今回の問題を生成しました。

CSPソルバーやSATソルバーを使うのも難しいようで、試してくれたのですが正しく動作しませんでした。黒マスによって盤面が分断しない(すべての白マスがつながる)という制約を扱うのが難しいのだろうと思います。

そんなわけで、小規模の問題であれば唯一解であることを自動で保証できるのですが、大規模な問題については、私が解いて確認しました。今回は、問題生成の完全自動化には失敗だ。そう思っていました。

ついに高速化に成功!

しかしです。

この記事を執筆している最中に、ついにZ3ソルバーを使って高速化に成功しました!正直なところ、定式化やコードが完全に正しいかどうかすぐには理解できませんが、解が複数ないことを示す部分の定式化や、各定式化の概念は確認できました。これで、現実的な時間での問題生成の完全自動化に成功しました!

成功の決め手

成功のカギは、o1-miniへの次のプロンプトでした。

解があるはずの問題に対して解なしになっています。どこが間違っているのか念入りに確認してから修正してください。

この指示が功を奏し、ついに黒マスで盤面が分断しないという制約をソルバーで扱えるようになりました。今後も同様のルールでAIと一緒にパズルを作ることができそうです。

ぬか喜び

さて、記事の下書きも終わり、後述するアプリの動作テストも兼ねて問題を解いていたところ、複数解を持つ問題に遭遇しました。何が問題なのか、定式化を見てもすぐにはわかりません。細かく見ていくうちに、黒マスで盤面が分断しないという制約も正しく定式化できていないことに気づきました。テンション高く成功を謳いましたが、成功していませんでした
ぬか喜びです。

自力で修正

さらに細かく見ていくと、黒マス同士の連結制約も正しくないことがわかりました。ここは自力で修正しました。
緩和問題を解いた後で、すべての制約を満たしているかどうかを確認するというコードをChatGPTは返していたので、黒マスで盤面が分断しないという制約は完全に無視した緩和問題を解き、得られた解についてすべての制約を満たしているかどうかを確認する方針にしました。

生成されたコードはこんな構造になっていた

そしてついに、今度こそ、完全自動化に成功しました。
具体的には、10×10のサイズの問題の唯一解のチェックが3秒ほどでできるようになっています。

今回の挑戦は、わたしの方でのコード修正も多く大変でしたが、得られたものは大きかったです。今後わたしがAIと作るパズルのデザインの幅を広げてくれる、嬉しい出来事でした。


ブラウザアプリ

今回のパズルは、問題生成のロジックは異なるものの、ゲームプレイのUIや正解ファイルとの一致確認など、ライアースイーパーのアプリで実装した内容のほとんどすべてが流用できます。
ですので、サクっとブラウザで遊べるようにしました。下記から遊べます。

最後に

今回の記事を楽しんでいただけましたか?よければ「スキ」を押していただけると励みになります。また、ぜひ「コメント」でご感想をお聞かせください!
新しいパズルやアイデアをもっと共有していきたいと思いますので、今後ともよろしくお願いします。

この記事が参加している募集

この記事が気に入ったらサポートをしてみませんか?