我读了一篇关于minimax的教程,并尝试制作一个非常简单的人工智能。 但由于某些原因,代码无法以最佳方式工作,这是我无法找到的。 ai可以放置碎片,但它不是一个聪明的ai。我以为它是无与伦比的。深度越高,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;
}
答案 0 :(得分:3)
我发现了一些事情:
board[move[0]][move[1]] = player;
。这应该是piece
而不是player
,现在你的人工智能认为只有人类玩家的一部分才能登上董事会。-1
次同一个棋盘的得分从对手的视角。答案 1 :(得分:1)
minimax
按行/列对返回移动,而非分数。所以
currentScore = minimax(depth - 1, player)[0];
毫无意义。它可能导致第3行的任何移动看起来都比移动到第1行或第2行更好。
minmax
需要提交
除了最好的举动外,还有一个得分。