I am using MinMax algorithm for Tictactoe, and it works correctly, but it's trying to win, without blocking my turns, so it's very easy to win the AI. I added the depth parameter, but the result is the same. Here you can see my code:
public int playMiniMax(Tableau t, char maximizingPlayer,int depth) {
int bestMove = 0;
if (t.getWinner() == 'x') {
return 1;
} else if (t.getWinner() == 'd') {
return 0;
} else if (t.getWinner() == 'o') {
return -1;
}
else if (depth == 0) {
return 0;
}
else {
int bestValue;
int i;
if (maximizingPlayer == 'x') {
bestValue = Integer.MIN_VALUE;
for(i = 1; i <= 9; ++i) {
if (t.chooseCase(i, 'x')) {
bestValue = Math.max(bestValue, this.playMiniMax(t, 'o',depth-1));
bestMove = i;
t.resetCase(i);
}
}
} else {
bestValue = Integer.MAX_VALUE;
for(i = 1; i <= 9; ++i) {
if (t.chooseCase(i, 'o')) {
bestValue = Math.min(bestValue, this.playMiniMax(t, 'x',depth-1));
bestMove = i;
t.resetCase(i);
}
}
}
return bestMove;
}
}
The "bestMove" is the best case(from 1 to 9) proposed by minmax, and in my main I am calling it like this:
int movei = playerAI.playMiniMax(t, 'x',3);
correctCase = t.chooseCase(movei, 'x');
public class Tableau {
private char[][] charArray;
private boolean gameIsOver = false;
private char winner = 'n';
Tableau(char[][] _charArray) {
this.charArray = _charArray;
this.moves = new Stack();
this.ceateTable();
}
public void ceateTable() {
for(int i = 0; i < this.charArray.length; ++i) {
for(int j = 0; j < this.charArray.length; ++j) {
if (j != 2 && j != 5) {
System.out.print(this.charArray[i][j] + "|");
} else {
System.out.println(this.charArray[i][j] + "|");
}
}
}
}
public boolean chooseCase(int number, char player) {
int c = 1;
for(int i = 0; i < this.charArray.length; ++i) {
for(int j = 0; j < this.charArray.length; ++j) {
if (c == number && this.charArray[i][j] == '-') {
this.charArray[i][j] = player;
return true;
}
++c;
}
}
return false;
}
public void resetCase(int number) {
int c = 1;
for(int i = 0; i < this.charArray.length; ++i) {
for(int j = 0; j < this.charArray.length; ++j) {
if (c == number) {
this.charArray[i][j] = '-';
}
++c;
}
}
}
public boolean checkWin(char player) {
if ((this.charArray[0][0] != player || this.charArray[0][1] != player || this.charArray[0][2] != player) && (this.charArray[1][0] != player || this.charArray[1][1] != player || this.charArray[1][2] != player) && (this.charArray[2][0] != player || this.charArray[2][1] != player || this.charArray[2][2] != player) && (this.charArray[0][0] != player || this.charArray[1][0] != player || this.charArray[2][0] != player) && (this.charArray[0][1] != player || this.charArray[1][1] != player || this.charArray[2][1] != player) && (this.charArray[0][2] != player || this.charArray[1][2] != player || this.charArray[2][2] != player) && (this.charArray[0][0] != player || this.charArray[1][1] != player || this.charArray[2][2] != player) && (this.charArray[0][2] != player || this.charArray[1][1] != player || this.charArray[2][0] != player)) {
return false;
} else {
System.out.println("Dear " + player + " you won!");
this.gameIsOver = true;
this.winner = player;
return true;
}
}
public boolean isFull() {
for(int i = 0; i < this.charArray.length; ++i) {
for(int j = 0; j < this.charArray.length; ++j) {
if (this.charArray[i][j] == '-') {
return false;
}
}
}
return true;
}
public boolean checkDraw(char player) {
if (!this.checkWin(player) && this.isFull()) {
System.out.println("It's a draw!!!");
this.winner = 'd';
return true;
} else {
return false;
}
}
public boolean checkLoose(char player) {
return player == 'x' ? this.checkWin('o') : false;
}
public boolean isGameIsOver() {
return this.gameIsOver;
}
public void setGameIsOver(boolean gameIsOver) {
this.gameIsOver = gameIsOver;
}
public char getWinner() {
return this.winner;
}
public void setWinner(char winner) {
this.winner = winner;
}
}