【发布时间】:2014-12-18 15:23:51
【问题描述】:
已尝试调试我的 MiniMax 代码,但似乎无法在此处找到问题所在。主要方法是evalGame(),它返回 1 表示获胜,-1 表示失败,0 表示平局。我在 MiniMax 算法中有什么明显的错误吗?
package tictactoe;
import static tictactoe.Player.*;
import java.util.Arrays;
public class MinimaxTTT {
private Player[] board = new Player[9];
private static Player player = X;
public MinimaxTTT() {
Arrays.fill(board, E);
player = X;
}
public MinimaxTTT(Player[] b, Player p) {
for(int i = 0; i < 9; i++) {
board[i] = b[i];
}
player = p;
}
public static boolean checkWin(Player[] b, Player p) {
if((b[0]==p&&b[1]==p&&b[2]==p)
|| (b[0]==p&&b[3]==p&&b[6]==p)
|| (b[0]==p&&b[4]==p&&b[8]==p)
|| (b[0]==p&&b[1]==p&&b[2]==p)
|| (b[1]==p&&b[4]==p&&b[7]==p)
|| (b[0]==p&&b[1]==p&&b[2]==p)
|| (b[2]==p&&b[4]==p&&b[6]==p)
|| (b[2]==p&&b[5]==p&&b[8]==p)
|| (b[0]==p&&b[3]==p&&b[6]==p)
|| (b[3]==p&&b[4]==p&&b[5]==p)
|| (b[0]==p&&b[4]==p&&b[8]==p)
|| (b[2]==p&&b[4]==p&&b[6]==p)
|| (b[3]==p&&b[4]==p&&b[5]==p)
|| (b[1]==p&&b[4]==p&&b[7]==p)
|| (b[2]==p&&b[5]==p&&b[8]==p)
|| (b[3]==p&&b[4]==p&&b[5]==p)
|| (b[0]==p&&b[3]==p&&b[6]==p)
|| (b[2]==p&&b[4]==p&&b[6]==p)
|| (b[6]==p&&b[7]==p&&b[8]==p)
|| (b[6]==p&&b[7]==p&&b[8]==p)
|| (b[1]==p&&b[4]==p&&b[7]==p)
|| (b[2]==p&&b[5]==p&&b[8]==p)
|| (b[6]==p&&b[7]==p&&b[8]==p)
|| (b[0]==p&&b[4]==p&&b[8]==p)) {
return true;
}
return false;
}
private static boolean checkTie(Player[] b) {
for(int i = 0; i < 9; i++) {
if(b[i] == E) {
return false;
}
}
return true;
}
private static boolean gameOver(Player[] b) {
return checkTie(b) || checkWin(b, X) || checkWin(b, O);
}
private static int maxOfArray(int[] a) {
int max = a[0];
for (int i : a)
if (max < i)
max = i;
return max;
}
private static int minOfArray(int[] a) {
int min = a[0];
for (int i : a)
if (min > i)
min = i;
return min;
}
private static int getEmptyNumber(Player[] b) {
int spaces = 0;
for(int i = 0; i < 9; i++) {
if(b[i] == E)
spaces++;
}
return spaces;
}
private static int evalGame(Player[] b, Player p, Player currentP) {
if(gameOver(b)) {
if(checkWin(b, p)) {
return 1;
} else if(checkWin(b, p == X ? O : X)) {
return -1;
} else {
return 0;
}
} else {
int[] arrayEval = new int[getEmptyNumber(b)];
for(int i = 0; i < getEmptyNumber(b); i++) {
arrayEval[i] = evalGame(possibleBoards(b, currentP)[i], p, currentP == X ? O : X);
}
if(currentP == p) {
return maxOfArray(arrayEval);
} else {
return minOfArray(arrayEval);
}
}
}
public static Player[][] possibleBoards(Player[] b, Player p) {
Player[][] toReturn = new Player[getEmptyNumber(b)][9];
int spaces = 0;
for(int i = 0; i < 9; i++) {
if(b[i] == E) {
for(int j = 0; j < 9; j++) {
toReturn[spaces][j] = b[j];
}
toReturn[spaces][i] = p;
spaces++;
}
}
return toReturn;
}
public static void main(String[] args) {
Player[] p = new Player[9];
Arrays.fill(p, E);
p[1] = X;
System.out.println(evalGame(p, O, O));
}
}
【问题讨论】:
-
@mbomb007 和 E 在 getEmptyNumber()
-
程序会抛出什么错误,或者他们的游戏如何无法按预期运行?
-
checkWin是如何定义的? -
这不应该解决任何问题,但是您的
checkWin()方法检查了游戏板的许多重复行。请注意,只有 8 种可能获胜的 3 行:3 水平、3 垂直和 2 对角线。 -
是的。也许
if(gameOver(b)) {甚至可以被删除。它正在执行相同的检查 4 次或更多次。我不认为这是问题的根源。如果玩家有一个设置为X或O的属性,那么程序会更容易理解,然后您将棋盘和玩家都传进去以检查是否有空方格或获胜。然后在检查胜利时,您可以使用p.letter或其他任何内容。
标签: java recursion tic-tac-toe minimax