チェスゲームの AI を作っています。
これまでのところ、Alpha-Beta Pruning Minimax アルゴリズムの実装に成功しました。これは次のようになります (ウィキペディアから)。
(* Initial call *)
alphabeta(origin, depth, -∞, +∞, TRUE)
function alphabeta(node, depth, α, β, maximizingPlayer)
if depth = 0 or node is a terminal node
return the heuristic value of node
if maximizingPlayer
for each child of node
α := max(α, alphabeta(child, depth - 1, α, β, FALSE))
if β ≤ α
break (* β cut-off *)
return α
else
for each child of node
β := min(β, alphabeta(child, depth - 1, α, β, TRUE))
if β ≤ α
break (* α cut-off *)
return β
これには時間がかかりすぎるため (すべてのツリーを 1 つずつ調べていく)、「履歴ヒューリスティック」と呼ばれるものに出会いました。
元の論文のアルゴリズム:
int AlphaBeta(pos, d, alpha, beta)
{
if (d=0 || game is over)
return Eval (pos); // evaluate leaf position from current player’s standpoint
score = - INFINITY; // preset return value
moves = Generate(pos); // generate successor moves
for i=1 to sizeof(moves) do // rating all moves
rating[i] = HistoryTable[ moves[i] ];
Sort( moves, rating ); // sorting moves according to their history scores
for i =1 to sizeof(moves) do { // look over all moves
Make(moves[i]); // execute current move
cur = - AlphaBeta(pos, d-1, -beta, -alpha); //call other player
if (cur > score) {
score = cur;
bestMove = moves[i]; // update best move if necessary
}
if (score > alpha) alpha = score; //adjust the search window
Undo(moves[i]); // retract current move
if (alpha >= beta) goto done; // cut off
}
done:
// update history score
HistoryTable[bestMove] = HistoryTable[bestMove] + Weight(d);
return score;
}
したがって、基本的には、以前の「移動」のハッシュテーブルまたは辞書を追跡するという考え方です。
ここで、この「移動」が何を意味するのか混乱しています。それが文字通り単一の動きを指しているのか、それとも各動きの後の全体的な状態を指しているのかはわかりません.
たとえば、チェスでは、このハッシュテーブルの「鍵」は何であるべきでしょうか?
個々の動きは (Queen to position (0,1)) or (Knight to position (5,5))?
それとも、個々の動きの後のチェス盤の全体的な状態ですか?
1 の場合、履歴テーブルに「移動」を記録するときに、他のピースの位置が考慮されていないと思いますか?