Я прочитал учебник о минимаксах и попытался сделать tac tac toe AI. Но код по какой-то причине не работает оптимально, чего я не могу найти. Ai может размещать куски, но это не умный ai. Я ожидал, что это будет непобедимым. Чем выше глубина, тем глубже становится ai. «Игра» - это мой другой класс, в котором находится настоящая игра.Что случилось с моим Tic Tac Toe AI?
private Game game;
private Piece[][] board;
private Piece ai = Piece.CIRCLE;
private Piece player = Piece.CROSS;
public AI(Game game) {
this.game = game;
this.board = game.getBoard();
}
public int[] move() {
int[] result = minimax(1, ai);
return new int[] {result[1], result[2]};
}
private int[] minimax(int depth, Piece piece) {
List<int[]> possibleMoves = generateMoves();
int bestScore = (piece == ai) ? Integer.MIN_VALUE : Integer.MAX_VALUE;
int currentScore;
int bestRow = -1;
int bestCol = -1;
if (possibleMoves.isEmpty() || depth == 0) {
// Game over or depth reached
bestScore = evaluate();
}
else {
for (int[] move : possibleMoves) {
// Try this move for the player
board[move[0]][move[1]] = player;
if (piece == ai) { // ai is maximizing player
currentScore = minimax(depth - 1, player)[0];
if (currentScore > bestScore) {
bestScore = currentScore;
bestRow = move[0];
bestCol = move[1];
}
}
else { // player is minimizing player
currentScore = minimax(depth - 1, ai)[0];
if (currentScore < bestScore) {
bestScore = currentScore;
bestRow = move[0];
bestCol = move[1];
}
}
// Undo move
board[move[0]][move[1]] = null;
}
}
return new int[] {bestScore, bestRow, bestCol};
}
private List<int[]> generateMoves() {
List<int[]> possibleMoves = new ArrayList<int[]>();
// If game over
if (game.getWinner() != null) {
return possibleMoves; // return empty list
}
// Add possible moves to list
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
if (game.getBoard()[x][y] == null) {
possibleMoves.add(new int[] {x, y});
}
}
}
return possibleMoves;
}
private int evaluate() {
int score = 0;
// Evaluate
score += evaluateLine(0, 0, 0, 1, 0, 2); // row 0
score += evaluateLine(1, 0, 1, 1, 1, 2); // row 1
score += evaluateLine(2, 0, 2, 1, 2, 2); // row 2
score += evaluateLine(0, 0, 1, 0, 2, 0); // col 0
score += evaluateLine(0, 1, 1, 1, 2, 1); // col 0
score += evaluateLine(0, 2, 1, 2, 2, 2); // col 0
score += evaluateLine(0, 0, 1, 1, 2, 2); // diag 1
score += evaluateLine(0, 2, 1, 1, 2, 0); // diag 2
return score;
}
// Return +100, +10, +1 for 3-, 2-, 1-in-a-line for ai
// Return -100, -10, -1 for 3-, 2-, 1-in a line for player
// Else return 0
private int evaluateLine(int row1, int col1, int row2, int col2, int row3, int col3) {
int score = 0;
// First cell
if (board[row1][col1] == ai) {
score = 1;
}
else if (board[row1][col1] == player) {
score = -1;
}
// Second cell
if (board[row2][col2] == ai) {
if (score == 1) { // board1 is ai
score = 10;
}
else if (score == -1) { // board1 is player
return 0;
}
else { // board1 is empty
score = 1;
}
}
else if (board[row2][col2] == player) {
if (score == -1) { // board1 is player
score = -10;
}
else if (score == 1) { // board1 is ai
return 0;
}
else { // board1 is empty
score = -1;
}
}
// Third cell
if (board[row3][col3] == ai) {
if (score > 0) { // board1 and/or board2 is ai
score *= 10;
}
else if (score < 0) { // board1 and/or board2 is player
return 0;
}
else { // board1 and/or board2 is empty
score = 1;
}
}
else if (board[row3][col3] == player) {
if (score < 0) { // board1 and/or board2 is player
score *= 10;
}
else if (score > 1) { // board1 and/or board2 is ai
return 0;
}
else { // board1 and/or board2 is empty
score = -1;
}
}
return score;
}
Он возвращает int [] {bestScore, bestRow, bestCol}, поэтому оценка [0] – DingDongDang132