我正在尝试为Tic Tac Toe实现Minimax算法,并且似乎无法让它正确运行。我曾多次尝试重写它,但它没有给出正确的输出。
这是实现游戏的 MinimaxGame.java 的代码 -
public class MinimaxGame {
public MinimaxResult play(MinimaxBoard board) {
ArrayList<Position> possibleMoves = board.getAllPossibleMoves();
MinimaxBoard bestChild = null;
int bestScore= Integer.MIN_VALUE;
for (Position position : possibleMoves) {
MinimaxBoard child = new MinimaxBoard((MinimaxBoard)board.clone(), position, 'O');
int moveScore = max(child);
if (moveScore > bestScore) {
bestChild = child;
bestScore = moveScore;
}
}
MinimaxResult result = new MinimaxResult(bestChild, bestScore);
return result;
}
private int max(MinimaxBoard child) {
ArrayList<Position> possibleMoves = child.getAllPossibleMoves();
if (possibleMoves.isEmpty()) {
int score = evaluateScore(child);
return score;
}
int bestScore = Integer.MIN_VALUE;
for (Position position : possibleMoves) {
MinimaxBoard currentChild = new MinimaxBoard((MinimaxBoard)child.clone(), position, 'X');
int moveScore = min(currentChild);
if (moveScore > bestScore ) {
bestScore = moveScore;
}
}
return bestScore;
}
private int min(MinimaxBoard child) {
ArrayList<Position> possibleMoves = child.getAllPossibleMoves();
if (possibleMoves.isEmpty()) {
int score = evaluateScore(child);
return score;
}
int bestScore = Integer.MAX_VALUE;
for (Position position : possibleMoves) {
MinimaxBoard currentChild = new MinimaxBoard((MinimaxBoard)child.clone(), position, 'O');
int moveScore = max(currentChild);
if (moveScore < bestScore ) {
bestScore = moveScore;
}
}
return bestScore;
}
private boolean hasWon(MinimaxBoard board, char player) {
boolean status = false;
char [][] boardArray = board.boardArray;
// Check rows
for (int i = 0; i < 3; i++) {
status |= (boardArray[i][0] == player) && (boardArray[i][1] == player) && (boardArray[i][2] == player);
if (status) {
return true;
}
}
// Check columns
for (int i = 0; i < 3; i++) {
status |= (boardArray[0][i] == player) && (boardArray[1][i] == player) && (boardArray[2][i] == player);
if (status) {
return true;
}
}
// Check left diagonal
status |= (boardArray[0][0] == player) && (boardArray[1][1] == player) && (boardArray[2][2] == player);
if (status) {
return true;
}
// Check right diagonal
status |= (boardArray[0][2] == player) && (boardArray[1][1] == player) && (boardArray[2][0] == player);
if (status) {
return true;
}
return false;
}
// The function simply returns a score of +1 if computer wins, -1 if the user wins,
// and 0 in case of a draw.
private int evaluateScore(MinimaxBoard board) {
if (hasWon(board, 'X')) {
return -1;
}
else if (hasWon(board, 'O')) {
return 1;
}
return 0;
}
// Main method included for debugging purposes
public static void main(String args[]) {
Board sampleBoard = new Board();
sampleBoard.setState("----X----");
MinimaxBoard minimaxBoard = new MinimaxBoard(sampleBoard);
MinimaxGame game = new MinimaxGame();
MinimaxResult result = game.play(minimaxBoard);
Board updatedBoard = result.getUpdatedBoard().getBoard();
System.out.println(updatedBoard.getState());
}
}
很明显,我试图用这个初始字符串执行它 -
"----X----"
我得到的输出就是这个 -
"OOOOXOOOO"
不是以最佳的动作做出回应,而是以这种超级奇怪的方式表现出来并且放置一个&#39; O&#39;在每个空位。 我已经尝试过调试代码,但我仍然不知道代码出了什么问题。我无法弄清楚问题出在哪里。
有人可以帮帮我吗?提前谢谢。
修改 -
以下是 MinimaxBoard.java 的代码,其中我也实现了clone()方法。但是,输出仍然是一样的。谁能告诉我为什么?
public class MinimaxBoard implements Cloneable {
public char[][] boardArray;
public MinimaxBoard(Board board) {
boardArray = convertBoardTo2D(board.getState());
}
public MinimaxBoard(MinimaxBoard board, Position position, char player) {
this.boardArray = board.boardArray;
boardArray[position.row][position.coloumn] = player;
}
public Board getBoard() {
Board board = new Board();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < boardArray.length; i++) {
builder.append(String.valueOf(boardArray[i]));
}
board.setState(builder.toString());
return board;
}
public char[][] convertBoardTo2D(String boardString) {
char[][] boardArray = new char[3][3];
char[] chars = boardString.toCharArray();
if (chars.length == 9) {
for (int i = 0; i < chars.length; i++) {
boardArray[i/3][i%3] = chars[i];
}
}
return boardArray;
}
public ArrayList<Position> getAllPossibleMoves() {
ArrayList<Position> allMoves = new ArrayList<Position>();
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) {
if(boardArray[i][j] == '-') {
allMoves.add(new Position(i, j));
}
}
}
return allMoves;
}
@Override
public Object clone() {
try {
return (MinimaxBoard)super.clone();
}
catch(CloneNotSupportedException e) {
return null;
}
}
}
答案 0 :(得分:0)
我认为你必须克隆你的电路板。在你的情况下,你设置&#39; 0&#39; 0在所有可能的位置
MinimaxBoard child = new MinimaxBoard(board, position, 'O');
你必须改为
MinimaxBoard child = new MinimaxBoard(board.clone(), position, 'O');
并在Board类中实现clone()方法
克隆实施示例:
@Override
public Object clone() {
try {
MinimaxBoard cloned = (MinimaxBoard)super.clone();
cloned.boardArray = (char[][])boardArray.clone();
for(int row=0; row< cloned.boardArray.length;row++)
cloned.boardArray[row] = (char[])boardArray[row].clone();
return cloned;
}
catch(CloneNotSupportedException e) {
return null;
}
}
}