ミニマックスの再帰はどのくらい正確に機能しますか?
質問
だから私はTiC-Tac-TOEゲームのためにミニマックスを見上げていましたが、再帰がどのように働いたのか理解できませんでしたか?さて、それで基本的にここに私の質問があります:
- MiniMaxはどのようにターンがあるのかを知っていますか?プレイヤーを示すための最良の方法は、それが生成していることを順番に何をしていますか?
- どのようにあなたは可能な動きを生み出すのですか?
- ターミナルノードにいるときにどのように知っていますか。ターミナルノードをどのように生成しますか?
次の疑似コード
の場合function integer minimax(node, depth)
if node is a terminal node or depth <= 0:
return the heuristic value of node
α = -∞
for child in node: # evaluation is identical for both players
α = max(α, -minimax(child, depth-1))
return α
.
node
はボードが正しいですか?そして、コードが再帰に停止しなければならないプライの奥行きですか?また、max
関数とは何ですか、およびノードはどこから生成されていますか?
今、これまで私はボードを作成するためのこのコードを持っています:
class Board{
public:
Board();
~Board(){};
public: // The board
// In the board, 1 is x, 2 is o, 0 is empty square.
int board[3][3];
};
.
しかし、どのようにしてどのようなターンですか?そしてボードの子ノードを生成するにはどうすればよいですか?
解決
最初に例としてTIC-TAC-TOEを使用します。
- MiniMaxアルゴリズムは、プレイヤーが交代するゲームに最適なゲームに最適ですが、プレイヤーがターンあたり複数の動きをする可能性があるゲームに適応できます。私たちは前者を仮定します。その場合は、ノードの深さのパリティ(偶数のステップ、または奇数であろうとしているかどうかにかかわらず、Xに移動するにはxを移動するように 'または' Oを移動するように 'oを保存する必要はありません。上からのステップ数。
- 各位置から可能な動きを発生させるには、その動きがあること(以前と判断できる)があることを知っていること、および特定の位置から正当な動きの規則が必要です。 TIC-TAC-TOEのような単純なゲームのために、位置を考えると、現在のプレイヤーに属する新しいピースと、各空の正方形に属する新しいピースと新しいピースとからなるすべての状態を列挙するだけで十分です。 Othelloのようなゲームのために、それぞれの配置を確認して、それが規則に従い、規則の影響に従って最終的な位置を更新しなければなりません(オセロのための、束の色を反転させる)。一般に、追跡している各有効な位置から、新しいピースのすべての可能な配置を列挙し、ルールセットによって許可されているものを確認することを確認します。
- 一般的に、ゲームツリーサイズが地球の記憶容量を簡単に超える可能性があるため、ツリー全体を生成することはありません。あなたは常に最大反復深さを設定します。その後、端末ノードは、単に最大深さのノード、または正当な動きが存在しないノード(TIC-TAC-TOEの場合、すべての正方形の板が充填されたボード)です。あなたは事前に端末ノードを生成しません。彼らはゲームツリーの建設中に自然に生成されます。 TIC-TAC-TOEは、がゲームツリー全体を生成することができますが、TIC-TAC-TOEコードを使用しないでください。オセロ
あなたの疑似コードを見て:
-
max(a, b)
は、a
またはb
の大きさを返す関数です。これは通常数学ライブラリなどによって提供されます。 -
depth
は、検索する最大深度です。 - コンピューティングのヒューリスティック値は、ボードの値を記述する数値の数値です。ゲームツリー全体を列挙することができる簡単なTIC-TAC-TOEのようなゲームのために、Playerが解析を行っているボードポジションの
1
を指定することができます。未使用の位置のプレーヤー、および-1
。一般的に、あなたはあなた自身の発見的に調理すること、またはよく受け入れられているものを使う必要があります。 - 親ノードに基づいて分析中にその場でノードを生成します。ルートノードは常に分析を行っている位置です。
まだグラフや木を扱っていない場合は、最初にそうすることをお勧めします。特に木のプリミティブは、この問題に対する必須です。
このスレッドでのコメントとしての答えとして、そのターンが所与のノード用であることを判断する例を尋ねる、この疑似Python:
who_started_first = None
class TreeNode:
def __init__(self, board_position = EMPTY_BOARD, depth = 0):
self.board_position = board_position
self.children = []
self.depth = depth
def construct_children(self, max_depth):
# call this only ONCE per node!
# even better, modify this so it can only ever be called once per node
if max_depth > 0:
### Here's the code you're actually interested in.
if who_started_first == COMPUTER:
to_move = (COMPUTER if self.depth % 2 == 0 else HUMAN)
elif who_started_first == HUMAN:
to_move = (HUMAN if self.depth % 2 == 0 else COMPUTER)
else:
raise ValueError('who_started_first invalid!')
for position in self.board_position.generate_all(to_move):
# That just meant that we generated all the valid moves from the
# currently stored position. Now we go through them, and...
new_node = TreeNode(position, self.depth + 1)
self.children.append(new_node)
new_node.construct_children(max_depth - 1)
.
各ノードは、 'root'ノードからその絶対深さを追跡することができます。次の動きのためのボードポジションをどのように生成するかを決定しようとすると、その動きが私たちの深さのパリティ(0
の結果)と最初に動いた人の記録に基づいているのを確認します。
他のヒント
1)ミニマックスはどのようにターンですか?ターンが生成しているプレイヤーを示すための最良の方法は何ですか?
そのdepth
引数を持つ。深さがさえも、それが奇数であればそれから他のプレイヤーのターンです。
2)どのようにして動きを発生させますか?
ゲームのルールを使用しています。TiC TAC TOEでは、可能な移動は自分のマークを自由な細胞に配置することを意味します。
3)ターミナルノードにいるときにどのように知っていますか、そして端末ノードを生成する方法を知っていますか?
端末ノードは、誰かが勝ったノードです。あなたはそれらを再帰によって生成します。各再帰呼び出しはボードの現在の状態を与えられるべきです。疑似コードのnode
およびchild
パラメータがあると思います。だからその状況で誰かが勝ったのなら、それはターミナルです、そうでなければあなたはすべての合法的な動きと再発を試みます。
私はあなたが探していることについて、私はあなたが探していることについて少しのアイデアを提供することができます。私はTIC-TAC-TOEのためのMiniMAXアルゴリズムを書きました。
直接質問に答えるには:
-
私のMiniMaxアルゴリズムはそれを決定しませんでした。どのプレイヤーがアルゴリズムを使用していたかを決定した議論を受け入れました。
-
プレーヤーが移動することを知って、ボード上のすべての空白の正方形を介してループし、それぞれの間に、現在のプレーヤーのトークンを持つノードをその正方形に生成します。そこから再帰的に進みます。
-
私はゲームが終わったかどうか、そしてそれが描かれたか勝ったかどうかを示した値を返した関数を使用しました。
- 入力:移動するプレイヤー、およびボードの状態。
- ボード上に残っているすべての空白スペースを見つけます。
- プレイヤーのそのスペースに移動して新しいボードを生成します。
- ゲームが終了した場合は、ゲームの結果を持つノードを生成します。
- それ以外の場合は、他のプレイヤーと新しいボードを渡し、相手の理想的な移動の結果を持つノードを生成します。
- どのノード(Move)が最悪の場合、どのノード(MOVE)が可能になるかを決定します。
- 出力:最良の動き、それからのゲームの結果に関する情報。
私の基本的なアルゴリズムこれは次のとおりです。