我正在尝试使用minimax算法在java中实现connect 4的计算机AI版本。对于任务,我创建了一个“Node”类,它以单个板状态开始,然后递归地创建更多节点,直到指定的深度。然后,它将每个节点评分为1作为赢取0作为绘制或最大深度。最后,我使用minimax algorithem来选择在函数“getColumn()”中使用哪个移动。这是我的代码
package ai;
import java.util.ArrayList;
import java.util.Arrays;
public class Node {
public ArrayList < Node > nodeList = new ArrayList < Node > ();
private int[][] board; // Represents board, 0 is empty space, 1 is player 1, 2 is computer
private int turn; // Current turn, 1 is player, 2 is computer
// Node constructor, creates tree of possible game states
public Node(int[][] board, int depth, int turn) {
this.board = board;
this.turn = turn;
if (depth > 0 && result(turn) == -1) {
int[][] copy = new int[7][6];
for (int i = 0; i < 7; i++)
copy[i] = board[i].clone();
int[] cols = getAvailCols(board);
for (int col: cols) {
int y = placeBlock(col, turn, copy);
nodeList.add(new Node(copy, depth - 1, turn == 1 ? 2 : 1));
copy[col][y] = 0;
}
}
}
// Returns 0 for draw, 1 for win, -1 for no result
private int result(int currTurn) {
int horCount = 1;
int verCount = 1;
int ldiaCount = 1;
int rdiaCount = 1;
for (int x = 0; x < 7; x++) {
for (int y = 0; y < 6; y++) {
for (int countX = x + 1; countX < 7; countX++) {
if (board[countX][y] == currTurn) horCount++;
else break;
}
for (int countX = x - 1; countX >= 0; countX--) {
if (board[countX][y] == currTurn) horCount++;
else break;
}
for (int countY = y + 1; countY < 6; countY++) {
if (board[x][countY] == currTurn) verCount++;
else break;
}
for (int countY = y - 1; countY >= 0; countY--) {
if (board[x][countY] == currTurn) verCount++;
else break;
}
for (int countX = x + 1, countY = y + 1; countX < 7 && countY < 6; countX++, countY++) {
if (board[countX][countY] == currTurn) rdiaCount++;
else break;
}
for (int countX = x - 1, countY = y - 1; countX >= 0 && countY >= 0; countX--, countY--) {
if (board[countX][countY] == currTurn) rdiaCount++;
else break;
}
for (int countX = x + 1, countY = y - 1; countX < 7 && countY >= 0; countX++, countY--) {
if (board[countX][countY] == currTurn) ldiaCount++;
else break;
}
for (int countX = x - 1, countY = y + 1; countX >= 0 && countY < 6; countX--, countY++) {
if (board[countX][countY] == currTurn) ldiaCount++;
else break;
}
if (horCount >= 4 || verCount >= 4 || ldiaCount >= 4 || rdiaCount >= 4) {
return 1;
}
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 6; j++) {
if (board[i][j] == 0) return -1;
}
}
}
}
return 0;
}
// Puts chip into a column
private int placeBlock(int x, int turn, int[][] checkboard) {
int y = 0;
while (y < 5 && checkboard[x][y + 1] == 0)
y++;
checkboard[x][y] = turn;
return y;
}
// Gets the score of a node
private int score() {
int result = result(turn);
if (result == 0) return 0;
else if (result == 1) return Integer.MAX_VALUE;
else if (nodeList.size() > 0) {
int score = Integer.MIN_VALUE;
for (Node node: nodeList)
score = Math.max(score, -node.score());
return score;
} else {
return 0;
}
}
public int[] getAvailCols(int[][] checkboard) {
ArrayList < Integer > list = new ArrayList < Integer > ();
for (int i = 0; i < 7; i++) {
if (checkboard[i][0] == 0) list.add(i);
}
int[] cols = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
cols[i] = (int) list.get(i);
}
return cols;
}
// Only called for top node tell whichmove ai should take
public int getColumn() {
int[] cols = getAvailCols(board);
int index = 0;
int maxScore = Integer.MIN_VALUE;
for (int i = 0; i < cols.length; i++) {
if (nodeList.get(i).score() > maxScore) {
maxScore = nodeList.get(i).score();
index = i;
}
}
return cols[index];
}
}
在棋盘阵列中:
0
是空格1
是玩家筹码2
是ai的筹码我已经运行了很多测试但是计算机似乎总是选择最左边的列,即使其他玩家即将获胜也是如此。任何人都可以解释如何解决这个或问题是什么。我目前正在为游戏使用7的深度。