ゲーム Threes のための AI!シルボLLCによる。ゲームはここから入手できます: http://asherv.com/threes/
この AI の構築は、後の 2048 AI のインスピレーションの源であり、2048 AI のアイデアの一部はこの AI にもバックポートされています。
この AI のパフォーマンスを (まだ) 正式にベンチマークしたことはありませんが、ゲーム内で利用可能な最高のタイルである 6144 タイルを複数回達成することに成功していることはわかっています。 (より高いタイルも可能ですが、ランダムな効果が大きいため、可能性は低いです)。最高スコア (執筆時点) は 775,524 ポイントです。
この AI は、Threes の複雑さが増しているため、新しい兄弟の 2048 AI よりもはるかに実験的です。それは開発時間がそれほど長くかかっていないからです。さらにスリーズ!ランダム タイル生成アルゴリズムは時々微調整され、AI の変更が必要になるため、一般に少し動く目標になります。
この AI のアルゴリズムは、私の 2048 年の AI を説明するこの StackOverflow の回答ですでに基本的に詳しく説明されています。本質的には、ゲーム ツリー (すべての可能な手、タイルのスポーン値、およびタイルの値) に対して高度に最適化されたブルートフォース検索を実装し、expectimax 最適化を使用して結果を結合し、可能な「最良の」手を見つけます。
この Threes AI は、実際にはさまざまな点で 2048 AI よりも洗練されています。最も注目すべき点は、今後のタイルの「デッキ」 (ランダムに入ってくるタイルが選択される十分に文書化されたプロセス) を考慮し、適切に処理することです。行われた動きに基づいて、考えられるすべてのタイルのスポーン位置。つまり、この Threes AI は、(私の知る限りでは) Expectimax 最適化プロセスの一環として、Threes ゲームのあらゆる詳細を正しくエミュレートします。
AI を実行する最も簡単な方法は、OS とプロセッサに対応するprebuilt/
ブランチの 1 つのクローンを作成することです。これらのブランチには、 bin/
ディレクトリに事前に構築されたバイナリがあります。
Windows の「デフォルト」Python は 32 ビットですが、OS X および Linux の「デフォルト」Python は 64 ビットであることに注意してください。 32 ビット ビルドにはi386
タグが付けられ、64 ビット ビルドにはx86_64
タグが付けられます。
ソースから自分でビルドしたい場合 (変更を加えている場合など)、以下の手順に従ってください。
実行する
./configure
make
端末内で。比較的最近の C++ コンパイラであれば、出力をビルドできるはずです。
make install
行わないことに注意してください。このプログラムはこのディレクトリから実行されるように設計されています。
インストールしたものに応じて、いくつかのオプションがあります。
Pure Cygwin: 上記の Unix/Linux/OS X の手順に従ってください。生成された DLL は Cygwin プログラムでのみ使用できるため、ブラウザ コントロール バージョンを実行するには、(python.org Python ではなく) Cygwin Python を使用する必要があります。詳しい手順については、Tamas Szell (@matukaa) の厚意により、このドキュメントを参照してください。
MinGW を使用した Cygwin: 実行
CXX=x86_64-w64-mingw32-g++ CXXFLAGS='-static-libstdc++ -static-libgcc -D_WINDLL -D_GNU_SOURCE=1' ./configure ; make
MinGW または Cygwin シェルでビルドします。結果として得られる DLL は、Cygwin 以外のプログラムで使用できます。
Visual Studio: Visual Studio コマンド プロンプトを開き、threes-ai ディレクトリにcd
、 make-msvc.bat
を実行します。
Python プログラムを実行するには、Python 2.7、NumPy、および PIL が必要です。
AI 自体の動作を確認したい場合は、 bin/threes
を実行します。
Threes には Web ベースのバージョンがいくつかありますが、私は AI を実際のアプリと対戦させたかったのです。そこで、Android デバイス用のandroid_assistant.py
という「アシスタント」プログラムを構築しました。このプログラムは、ADB 経由で電話と通信し、完全に自動的に動作します。必要なのは USB ADB 権限 (標準の開発者アクセス) のみであり、root 化やデバイスやアプリのその他の変更は必要ありません。標準の Android screencap
ユーティリティを使用して (目に見える) ゲーム状態を取得し、最適な手を計算してから、Linux 入力イベント サブシステムを使用してスワイプ イベントを生成します。
android_assistant.py
を使用するには、デバイスの OCR サブシステムを構成する必要があります。再生のためにスワイプ イベントを記録する必要もあります。現在、LG Nexus 5 と OnePlus One (これをテストした携帯電話に対応します) の 2 つのデバイスが構成されています。電話機を追加するためのパッチを歓迎します。
OCR システムを構成するには、デバイスに対応するエントリをocr/devices.py
に追加する必要があります。モデル名は、デバイスに接続しているときにandroid_assistant.py
実行するだけで取得できます (予想されるモデル名でエラーが発生するはずです)。基本的に、ゲームのスクリーンショットを撮り、「次のタイル」ペインの位置と、タイル グリッドの位置と間隔を取得する必要があります。 (この部分はおそらく、さらに自動化や簡素化を行うことができます。)
イベントを記録するには、単にpython -m android.inputemu --record up down left right
を実行し、プロンプトが表示されたら携帯電話で適切なジェスチャを実行します。
マニュアルアシスタントは汎用のThrees! Threes! のあらゆる実装で動作するアシスタント。ボードと今後のタイルセットを指示すると、アシスタントが最適な手を計算します。
manual_assistant.py
を実行して手動アシスタントを開始します。
手動アシスタントは連続した動きを期待していることに注意してください。先にスキップする (アシスタントを使用せずに移動する) 場合は、Ctrl+C を押してアシスタントを終了し、再度開始します。そうしないと、前のボードと連続していないボードを入力すると、「不可能な状況」のようなエラー メッセージが表示される可能性があります。
次のボードに入るときは、スペース、改行、カンマを使用してタイルを区切ることができます。左から右に読んでから、上から下に読んでください。空白のスペースにはゼロを入力します。入力例:
カンマと改行の使用:
96,2,3,0
2,1,1,0
2,1,0,0
0,0,2,0
カンマのみを使用する場合:
96,2,3,0,2,1,1,0,2,1,0,0,0,0,2,0
スペースの使用:
96 2 3 0
2 1 1 0
2 1 0 0
0 0 2 0
前のボードから「デルタ」を入力することもできます。新しいタイルが生成された行または列、および生成されたタイルの値を指定します (最後に移動した可能性のある新しいタイルが 1 つだけの場合、たとえば、それが赤または青だった場合は、これを省略できます)。 AI が提案した手ではなかった場合は、自分が行った手を指定します。
列と行には左から右、上から下に番号が付けられます。列 1 は左の列、行 1 は上の行です。
たとえば、ボードを上にスワイプして、
96 2 3 0
2 1 1 0
2 1 0 0
0 0 2 0
に
96 3 3 0
2 1 1 0
2 0 2 0
0 3 0 0
次に、 2,3,up
ボードとして送信します (2 列目に 3 が生成されます)。 AI がup
動きを推奨した場合は、単純にそれを省略して2,3
送信できます。次のタイルが 3 と予測されていた場合は、 3 を省略して2
だけを送信できます。
デルタを入力すると、時間を大幅に節約できます。ほとんどの場合、入力する必要があるのは 1 つの数値 (変更された列/行) だけです。
次のタイルを入力するときは、次のいずれかの形式を使用します。
blue
(1)、 red
(2)、またはwhite
(3+)1
、 2
、 3
、 3+
、 6+
、または24,48,96
、 24 48 96
3+
、3 以上である可能性があることを意味します。古い Three でこれを使用してください。ボーナスタイルに「プラス」記号が表示されないもの6+
、ボーナス タイルであることを意味します。次のタイルが「+」の場合にこれを使用します24,48,96
、これら 3 つのうちの 1 つであることを意味します。新しい Threes でこれを使用してください。ボーナス タイル値の明示的なオプションを示します。