在我的minimax算法中,当计算机出现一个有两种方式赢得计算机的玩家时,就会选择该板的第一个打开位置。以下为例。 X可以在位置0,2和位置1,0获胜。
X | |
__________
| x |
__________
x | o | o
目前我的算法将o放在位置0,1。我相信这样做是因为当minimax运行并在位置0,1放置o并且因为这不是赢,它再次调用minimax,这次是x。然后X在位置0,2移动获胜。这个位置返回-10。如果计算机在位置0,2移动,则调用minimax,x最终放在位置1,0,此位置也返回-10。实际上无论计算机放置o的位置,都会返回-10,因为无论玩家获胜的是什么。因为对于放置的每个位置,它返回-10,计算机将o放在第一个可用的槽中,即0,1因为max从未从第一个位置更新。我希望将o放在位置1,0或0,2只是为了表明它识别出一个块。
我的算法如下。这是3x3x3,但概念是相同的。
public int MiniMax(int pGameState[][][], int Depth, boolean IsMax){
FunctionCalls++;
if(CheckForWin(2, pGameState)){ //Max Player (since the computer is always 2)
return 10 - Depth;
}
if(CheckForWin(1, pGameState)){ //Player will win therefore we return -10. If this is the first level of the tree
//then the value return is -10. If the second ply then the value returned is -8.
//It is more important for the computer to win sooner than later.
return -10 - Depth;
}
if(Depth >= 2){
return 0;
}
if(IsMax){
int Value = Integer.MIN_VALUE;
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
for(int k=0; k<3; k++){
if(pGameState[i][j][k] == 0){
pGameState[i][j][k] = 2;
int best = MiniMax(CopyArray(pGameState), Depth+1, !IsMax);
if(best > Value)
Value = best;
pGameState[i][j][k] = 0;
}
}
}
}
return Value;
}
else{
int Value = Integer.MAX_VALUE;
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
for(int k=0; k<3; k++){
if(pGameState[i][j][k] == 0){
pGameState[i][j][k] = 1;
int best = MiniMax(CopyArray(pGameState), Depth+1, !IsMax);
if(best < Value)
Value = best;
pGameState[i][j][k] = 0;
}
}
}
}
return Value;
}
}
我最初用这种方式调用minimax
best = MiniMax(CopyArray(GameState), 0, false);
然后,我与之前的Max相比最佳。如果最好的是更大,我保存此移动作为我的计算机的移动。