このチェッカーゲームを見て、AIがどのように実装されているのか疑問に思いました。
チェッカー(ドラフト、ダマ、ダメ)にAIを実装するにはどうすればよいですか?既知のアルゴリズムはありますか?
すべてに完全にひそかに。このTic Tac Toeゲームチュートリアルのブログ投稿を見るのは非常に不思議です。
だから、私はダマゲームアルゴリズムのオープンソースコードとブログの投稿が欲しいです。役に立つリンクやドキュメントファイルはありますか?私にお知らせください..
このチェッカーゲームを見て、AIがどのように実装されているのか疑問に思いました。
チェッカー(ドラフト、ダマ、ダメ)にAIを実装するにはどうすればよいですか?既知のアルゴリズムはありますか?
すべてに完全にひそかに。このTic Tac Toeゲームチュートリアルのブログ投稿を見るのは非常に不思議です。
だから、私はダマゲームアルゴリズムのオープンソースコードとブログの投稿が欲しいです。役に立つリンクやドキュメントファイルはありますか?私にお知らせください..
回答:
ああ、これらのゲームが大好きです!
まず最初に、コンピューターでゲームをプレイするには、次のものが必要です。
一度にこの1つのピースに取り組みましょう。
ボードは8x8グリッド(ただし、簡単にスケーリングできます)であり、各グリッドスペースは5つの状態のうちの1つだけに存在する可能性があるため、これらの状態を定義しましょう。
[EMPTY, WHITE_PIECE, BLACK_PIECE, WHITE_PIECE_PROMOTED, BLACK_PIECE_PROMOTED]
それぞれにENUMされました:
[0, 1, 2, 3, 4]
各スペースが何であるかがわかったので、すべてのスペースを表す何らかの方法、または必要に応じてボードを必要とします。ほとんどすべての強力な言語は、多次元配列(各要素がデータを保持する配列である配列)をサポートします。したがって、配列を定義するために次のスラックコードを使用します。
BOARD_ARRAY = array(8, 8)
これにより、整数(以前の列挙型)を格納できる8 x 8配列が得られます。
(
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
)
これで、ボードがボードのように見え始めていることがわかります。私はyoutubeのビデオで言及されたバリアントをプレイしたことはありませんが、下から1行の白い部分の2行と上から1行の黒い部分の2行で始まるように見えます。つまり、ゲームを開始すると、配列は次のようになります。
(
[0, 0, 0, 0, 0, 0, 0, 0],
[2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0],
)
(2は「BLACK_PIECE」を表し、1は「WHITE_PIECE」を表します)
これで、コンピューターには動作する構造ができました。ステップ1が完了しました!
マスタープレイヤーと対戦する実際のボードが目の前に設置されていると想像してください。彼の作品の1つを動かそうとすると、手が平手打ちされます。できない方法でピースを動かそうとすると、手が平手打ちされます。あなたがうまくカンニングしようとした場合...あなたはアイデアを得る。しかし、問題は、コンピューターにはありません。したがって、内部でプレイするための厳格なルールを提供することが私たちの仕事です。
特定の動きが「合法」であるかどうかを確認する方法を作成する必要があります。つまり、最初に「移動」を表す何らかの方法が必要です。1つの方法は、配列の位置を使用することです。たとえば、ピースを[0、0]から[0、1]に移動するには、その移動に応じてボードを更新する関数を作成できます。だからスラックに戻ります:
MY_MOVE = array( [0, 0], [0, 1] )
上記は1つのピースを表しており、ボードの上隅から1スペース下に移動します(0を想定し、0は左上隅です)。また、移動に多次元配列を使用することにしました。これは、1つのターンでピースが理論的に多数回移動する可能性があるためです(他のピースを「ジャンプ」するため)。それでは、0、1のふりをして、対戦相手の駒があったとしましょう。つまり、0、2に着陸するということです。
MY_MOVE = array( [0, 0], [0, 2] )
とても簡単です。プログラムは、スペースをスキップすると別のピースにジャンプすることを理解する必要があります(または、それは違法な動きであり、エラーをスローする必要があります)。次に、2つの部分にジャンプします。
MY_MOVE = array ( [0, 0], [0, 2], [0, 4] )
これにより、ボード上の動きを説明することができます。わーい!今、私は問題の正確なゲームのルールを完全には理解していないので(今日はカナダのチェッカーを少しプレイしましたが)、正確なムーブの合法性を定義する必要があります。ここまでの流れは次のようになります。
FUNCTION_FIND_ALL_LEGAL_MOVES( MY_BOARD ) Returns: array ALL_LEGAL_MOVES
FUNCTION_FIND_BEST_MOVE( MY_BOARD, ALL_LEGAL_MOVES ) Returns: array MY_MOVE
FUNCTION_DO_MOVE( MY_BOARD, MY_MOVE ) Throws: error ILLEGAL_MOVE Updates: MY_BOARD
repeat from start for each turn
上記は、各ピースを循環して合法的な動きをすべて見つけることができ、すべての合法的な動きのコレクションが何らかの形で最良のものを選択できることを前提としています(ここでの戦略)。その後、移動がボードに適用されるか、エラーがスローされます。その後、次のプレイヤーが順番を取ります。プレイ方法を知っているAIがあります!喜び!続けて。
勝利は非常に単純な状態によって定義されるため、単純なゲームは素晴らしいです。ボードに白い破片がありませんか?まああなたが勝ったと思います!これは、勝利条件に近づけるために最適な動きを選択するときに、ステップ2で実装されます。
非常にインテリジェントなAIを作成するには、すべての可能なボードを状態として保存したデータベースを保持し、すべての可能な状態からのすべての可能な移動により、勝つためのチェーンを見つけることができます。
次のような戦略を作成することもできます。ジャンプするピースがある場合、そのピースを保存するか、ピースが他の複数のピースをジャンプできる場合。
それはあなたに良い出発点を与えるはずです、それは文字通り無制限の可能性の唯一の方法です。理論的には、クレヨンで描く巨大なロボットを構築し、その図面にスペクトル分析を行って動きを選択することができます...しかし、それはあまりうまく、または速く動作しません。この方法は過去にも機能し、うまく機能していました(:助けてほしい!
Checkersは、「解決された」ゲームと呼ばれるもので、未知の要素なしですべての動きを計算できます。しかし、それは動きの全体です!したがって、すべてを手動で実行する方法はありません...一部が存在する場合のみ...ああ、私たちはプログラマです。拳ポンプ
SQLは、これらの一見無限の動きをすべて保存するための素晴らしいツールです。SQLの経験がない人のために、mySQLは無料の(かなり使いやすい)オープンソースのSQLサーバーです。SQLは、ステロイドのスプレッドシートのように、データベースの管理に使用されます。また、非常に大量のデータを保持し、非常に迅速に処理することもできます。
では、これをどのように使用できますか?ボードが正確な状態(各ピースが特定の位置にある)であれば、使用可能なすべての動きを計算して保存できることがわかっているためです。例えば:
+Board State+ +All Possible Moves+ +Best Move+
([0,0,1,2,3],[3..) ([0,1],[0,2]), ([7,6],[7,7],[5..) ([7,6],[7,7])
([0,0,2,2,3],[3..) ([0,1],[0,2]), ([7,6],[7,7],[5..) ([5,5],[5,4])
([0,0,1,3,3],[3..) ([0,1],[0,2]), ([7,6],[7,7],[5..) ([4,4],[4,3])
etc...
そのため、コンピューターが移動を行う必要がある場合、データベースでボードの状態(主キーとして格納されている)を検索し、最適な移動(無敵)を選択するか、他の移動のいずれかを選択してより友好的にすることができますAI。
さあ、このデータベースを構築しましょう。まず、すべてのボードの状態を計算する必要があります。誰かが少し時間を費やしてそれを解決したい場合、それは素晴らしい大きな厄介なループで行うことができます。配列を1つの大きな数として見てから、基数5(0、1、2、3、4)を除いて上向きに数え、各プレイヤーが16個しか持っていないことを条件にします。
この時点で、すべてのボードの状態を保存し、可能なすべての動きを計算することができます。
すべての可能な動きが計算されると、可能な限り最高の動きを見つける経路探索の楽しい部分になります。ここで私の知識が不足し始め、MinimaxやA *のようなものが働き始めます。申し訳ありませんが、私はそれについてのヘルプができません:/
ゲームのどの時点でも、プレーヤーの可能な動きの量は非常に少ない*(約5)。これは、いくつかの動きを先に考え、考えられるすべての動きを評価し、最適な動きを選択できることを意味します。
このアプローチはミニマックスと呼ばれます(ウィキペディア)ます。
minimaxを実装するには、特定のボードレイアウトとプレーヤーのスコアを返す評価関数が必要です。ドラフトでは、単純な実装は、プレイヤーが生きているすべてのピースに対して1ポイントを返す関数になります。
ミニマックス決定ツリーの視覚化(ウィキペディアの記事から)。左側にはターン番号があります。リーフノードにはそれぞれ評価スコアがあり、ツリーにフィードバックされて決定を下します。
*
ただし、ドラフトは、完全に解決された最高の分岐係数を持つゲームです。
アルファベータプルーニングは、検索ツリーでミニマックスアルゴリズムによって評価されるノードの数を減らすことを目的とした検索アルゴリズムです。これは、2人用ゲーム(三目並べ、チェス、囲、など)のマシンプレイで一般的に使用される敵対者検索アルゴリズムです。移動が以前に調査された移動よりも悪いことが証明された可能性が少なくとも1つ見つかった場合、移動の評価を完全に停止します。そのような動きをさらに評価する必要はありません。標準のミニマックスツリーに適用すると、ミニマックスと同じ動きを返しますが、最終決定に影響を与えない可能性のある枝を取り除きます。