私はウィキペディアの擬似コードを使用してベースにしています-
function alphabeta(node, depth, α, β, Player)
if depth = 0 or node is a terminal node
return the heuristic value of node
if Player = MaxPlayer
for each child of node
α := max(α, alphabeta(child, depth-1, α, β, not(Player) ))
if β ≤ α
break (* Beta cut-off *)
return α
else
for each child of node
β := min(β, alphabeta(child, depth-1, α, β, not(Player) ))
if β ≤ α
break (* Alpha cut-off *)
return β
これが私のJava実装です-
private int alphabeta(Node newNode, int depth, int alpha, int beta, boolean Player) {
Integer[] children;
if(depth == 0 || newNode.allNodesFull()){
return (newNode.blacknodes() - newNode.whitenodes());
}
if(Player == false){
children = newNode.findMovesBlack();
Arrays.sort(children);
for(Integer child: children){
nodesGenerated ++;
alpha = Math.max(alpha, alphabeta(new Node(newNode.move(child), true),
depth - 1, alpha, beta, !Player));
if(beta <= alpha)
break;
}return alpha;
}else{
children = newNode.findMovesWhite();
Arrays.sort(children);
for(Integer child: children){
nodesGenerated ++;
beta = Math.min(beta, alphabeta(new Node(newNode.move(child), false),
depth - 1, alpha, beta, !Player));
if(beta <= alpha)
break;
}return beta;
}
}
コードをいくつか修正した後、コードが早期に戻るという問題はなくなりましたが、アルファ版とベータ版が変更されないという問題があります。
何が起こるかを説明します、彼らがうまくいくと仮定します
findMovesBlack()とfindMovesWhite()はどちらも、誰が向きを変えたかに関係なく、どちらのプレーヤーも移動できる可能性のある位置を持つInteger[]配列を返します。Reversiの初期位置の場合、findMovesBlack()は[19、26、37、44]を返します。
findMovesBlack()とfindMovesWhite()の両方の長さが0の場合、allNodesFull()はブール値を返します。
blacknodes()とwhitenodes()は、それぞれ黒ノードまたは白ノードの量を返します。
Node.move(int座標)は、反転および配置された新しい位置を含むString[]配列を返します。私を信じてください、それは正しく動作します。
Node(String []ゲームボード、ブール値の移動プレーヤー)は、検出したパラメーターを使用して新しい位置を設定するだけです。
私はあなたが見る必要があるのはそれだけだと信じています。私はバックエンドからすべてのねじれをアイロンをかけました。