我一直在为我的tictactoe游戏编写一个minimax算法,但似乎没有选择正确的动作。有可能赢得计算机,所以我必须在这里混淆一些东西。我认为算法本身似乎很好,所以我很确定问题是我如何获得最好的举动。有没有人有任何建议?
minimax方法
private int minimax(Board board, boolean maximizingPlayer, char symbol){
//System.out.println(symbol);
Board copyBoard = new Board(board.getCells());
char winner = copyBoard.checkWin();
if(winner!='-' || copyBoard.checkDraw()){
return score(winner);
}
if(maximizingPlayer){
int bestValue = Integer.MIN_VALUE;
for(Board b : simulatePossibleMoves(copyBoard,mySymbol)){
int value = minimax(b,false,switchSymbol(mySymbol));
if(bestValue < value){
bestValue = value;
bestMove = b.getLastMove();
}
}
return bestValue;
}
else{
int bestValue = Integer.MAX_VALUE;
for(Board b: simulatePossibleMoves(copyBoard, switchSymbol(mySymbol))){
int value = minimax(b,true,mySymbol);
if(bestValue > value){
bestValue = value;
bestMove = b.getLastMove();
}
}
return bestValue;
}
}
得分方法
private int score(char winner){
if(winner == mySymbol)
return 10;
else if(winner == switchSymbol(mySymbol))
return -10;
return 0;
}
编辑:
游戏示例(人为X,AI为O)
O左上角
x中心
O中左侧
X左下方
O顶部中间
X右上角(人类胜利)
编辑2:
更多代码,不确定错误是否在这里,也可能包括它。
private ArrayList<Integer> getPossibleMoves(Board board){
ArrayList<Integer> moves = new ArrayList<>();
for(int i = 0; i < board.getCells().length; i++)
if(!board.isCellTaken(i))
moves.add(i);
return moves;
}
private ArrayList<Board> simulatePossibleMoves(Board board, char symbol){
ArrayList<Board> possibleBoards = new ArrayList<>();
for(Integer move : getPossibleMoves(board)){
Board temp = new Board(board.getCells());
temp.setCell(move, symbol);
possibleBoards.add(temp);
}
return possibleBoards;
}
private char switchSymbol(char s){
if(s=='X')
return 'O';
return 'X';
}
答案 0 :(得分:0)
事实证明,我一直试图通过选择minimax方法本身内部的最佳值来错误地使用算法。通过创建另一个调用minimax方法的方法,我能够找到最佳移动方式。以下代码对我有用。
public int getMiniMaxMove(Board board){
int score = -1;
int bestMove = -1;
for(int i : getPossibleMoves(board)){
Board copyBoard = new Board(board.getCells());
copyBoard.setCell(i, mySymbol);
int moveScore = minimax(copyBoard,false,mySymbol);
if(moveScore >= score){
score = moveScore;
bestMove = i;
}
}
return bestMove;
}
private int minimax(Board board, boolean maximizingPlayer, char symbol){
Board copyBoard = new Board(board.getCells());
char winner = copyBoard.checkWin();
if(winner!='-' || copyBoard.checkDraw()){
return score(winner);
}
if(maximizingPlayer){
int bestValue = Integer.MIN_VALUE;
for(Board b : simulatePossibleMoves(copyBoard,mySymbol)){
int value = minimax(b,false,switchSymbol(mySymbol));
if(bestValue < value){
bestValue = value;
}
}
return bestValue;
}
else{
int bestValue = Integer.MAX_VALUE;
for(Board b: simulatePossibleMoves(copyBoard, switchSymbol(mySymbol))){
int value = minimax(b,true,mySymbol);
if(bestValue > value){
bestValue = value;
}
}
return bestValue;
}
}