我目前正在为我的TictaToe android应用程序(使用java)开发一个算法,使用minimax,但首先,我只想确保算法工作正常,所以我做了一个算法来“建议”玩家的下一步行动。
玩家被宣布为 String player = "x";
在极大极小类中。
极小极大.java
package com.firaz.tictactoe;
public class Minimax {
public static class Move {
int row, col;
}
static String player = "x";
static String opponent = "o";
String[][] board = new String[3][3];
// This function returns true if there are moves
// remaining on the board. It returns false if
// there are no moves left to play.
static Boolean isMovesLeft(String[][] board) {
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (board[i][j].equals("_"))
return true;
return false;
}
// This is the evaluation function
static int evaluate(String[][] b) {
// Checking for Rows for X or O victory.
for (int row = 0; row < 3; row++) {
if (b[row][0].equals(b[row][1]) &&
b[row][1].equals(b[row][2])) {
if (b[row][0].equals(player))
return +10;
else if (b[row][0].equals(opponent))
return -10;
}
}
// Checking for Columns for X or O victory.
for (int col = 0; col < 3; col++) {
if (b[0][col].equals(b[1][col])
&& b[1][col].equals(b[2][col])) {
if (b[0][col].equals(player))
return +10;
else if (b[0][col].equals(opponent))
return -10;
}
}
// Checking for Diagonals for X or O victory.
if (b[0][0].equals(b[1][1])
&& b[1][1].equals(b[2][2])) {
if (b[0][0].equals(player))
return +10;
else if (b[0][0].equals(opponent))
return -10;
}
if (b[0][2].equals(b[1][1])
&& b[1][1].equals(b[2][0])) {
if (b[0][2].equals(player))
return +10;
else if (b[0][2].equals(opponent))
return -10;
}
// Else if none of them have won then return 0
return 0;
}
// This is the minimax function. It considers all
// the possible ways the game can go and returns
// the value of the board
static int minimax(String[][] board,
int depth, Boolean isMax) {
int score = evaluate(board);
// If Maximizer has won the game
// return his/her evaluated score
if (score == 10)
return score;
// If Minimizer has won the game
// return his/her evaluated score
if (score == -10)
return score;
// If there are no more moves and
// no winner then it is a tie
if (isMovesLeft(board) == false)
return 0;
// If this maximizer's move
if (isMax) {
int best = -1000;
// Traverse all cells
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
// Check if cell is empty
if (board[i][j].equals("_")) {
// Make the move
board[i][j] = player;
// Call minimax recursively and choose
// the maximum value
best = Math.max(best, minimax(board,
depth + 1, !isMax));
// Undo the move
board[i][j] = "_";
}
}
}
return best;
}
// If this minimizer's move
else {
int best = 1000;
// Traverse all cells
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
// Check if cell is empty
if (board[i][j].equals("_")) {
// Make the move
board[i][j] = opponent;
// Call minimax recursively and choose
// the minimum value
best = Math.min(best, minimax(board,
depth + 1, !isMax));
// Undo the move
board[i][j] = "_";
}
}
}
return best;
}
}
// This will return the best possible
// move for the player
static Move findBestMove(String[][] board) {
int bestVal = -1000;
Move bestMove = new Move();
bestMove.row = -1;
bestMove.col = -1;
// Traverse all cells, evaluate minimax function
// for all empty cells. And return the cell
// with optimal value.
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
// Check if cell is empty
if (board[i][j].equals("_")) {
// Make the move
board[i][j] = player;
// compute evaluation function for this
// move.
int moveVal = minimax(board, 0, false);
// Undo the move
board[i][j] = "_";
// If the value of the current move is
// more than the best value, then update
// best/
if (moveVal > bestVal) {
bestMove.row = i;
bestMove.col = j;
bestVal = moveVal;
}
}
}
}
return bestMove;
}
public void setBoard(String[][] Board){
this.board = Board;
Move bestMove = findBestMove(board);
PlayerVersusComputer playerVersusComputer = new PlayerVersusComputer();
playerVersusComputer.setRow(bestMove.row);
playerVersusComputer.setCol(bestMove.col);
}
}
我希望从 Minimax.java
到 PlayerVersusComputer.java
在这个代码段中。
播放服务器SUSComputer.java
String buttonID = getResources().getResourceEntryName(v.getId()); //button_ij
int pointerOne = Integer.parseInt(buttonID.substring(7, buttonID.length()-1)); //obtain i
int pointerTwo = Integer.parseInt(buttonID.substring(buttonID.length()-1)); //obtain j
if (player1Turn) {
((Button) v).setText("x");
board[pointerOne][pointerTwo] = "x";
} else {
((Button) v).setText("o");
board[pointerOne][pointerTwo] = "o";
checkBestMove();
}
protected void checkBestMove() {
minimax.setBoard(board);
row = getCol();
col = getRow();
tvAI.setText(row+"R"+" "+col+"C");
}
这是电路板阵列。每次我按下按钮,电路板就会自动“更新” ((Button) v).setText("x");
或者 ("o")
,然后在轮到o时传递到minimax.java。
String[][] board = {{"_","_","_"},
{"_","_","_"},
{"_","_","_"}};
自从 row
以及 col
不返回到 checkBestMove()
函数(我不确定它是否没有返回或者只是不能“更新”它本身) tvAI.setText
一直说“0r0c”而不是更新自己(到2r2c,然后0r1c,等等)。
更新到 row
以及 col
因为 tvAI.setText
旨在建议玩家的下一步行动。为什么不更新?
1条答案
按热度按时间d5vmydt91#
在功能上
setBoard
是一种召唤findBestMove(board);
但是类型的返回值Move
被忽略。也许你可以把它赋给一个变量。