Tải bản đầy đủ (.docx) (22 trang)

Minimax algorithm tic tac toe AI in java

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (240.78 KB, 22 trang )

Minimax Algorithm Tic Tac Toe AI In Java
[Minimax][Full tree Search][Artificial Intelligence]
[Java]
The minimax tree has leaf values like -1 0 or 1. Min selects the minimum i.e. -1. Max selects
the maximum among the available after Min would have taken its move. i.e. 0 or 1. So it has
available moves like -1, -1, 0, 0, +1, +1 at the top most node (root, which is the present
game state) and selects the first +1 value as it has a chance of victory no matter what other
opponent does (it has already been calculated like if the opponent does this, I can do this (it
always assumes the opponent takes the smartest move to destroy you) and I can win).
There is no summation of values taking place like +3, +4, +1 so that max selects +3 and
like that. This kind of approach is used in other implementation where you don't have the
time to evaluate the whole tree and just want to evaluate the tree at the (say 4th) level and
then rank the states accordingly like I have 3 rows in which I can get 3 Xs so that gives a
score +1000, 2 rows = +100 and 1 row = +10. -ve values for the opponents position. So you
get values like +1200 or -2300 at the leaves from where you select the move which is
favorable (this player is not perfect, it can lose. It has not evaluated all the possibilites. It
has just gone to some extent of computation to get some available move in some limited
time).
This AI is a perfect player i.e. it can never lose. It wins or it draws the match.
Source: The code isn't really hard. Function names are self explanatory. Comments are
added wherever necessary. I've supposed that 2 is the human player playing the game and
1 is the computer. If you want to see the actual calculations, just uncomment the
commented lines.
[Make sure you have JDK 8.0 Installed] If not, here's a
link: />import java.util.*;
class Point {
int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}



}

@Override
public String toString() {
return "[" + x + ", " + y + "]";
}

class PointsAndScores {
int score;
Point point;
PointsAndScores(int score, Point point) {
this.score = score;


}

this.point = point;

}
class Board {
List<Point> availablePoints;
Scanner scan = new Scanner(System.in);
int[][] board = new int[3][3];
public Board() {
}
public boolean isGameOver() {
//Game is over is someone has won, or board is full (draw)
return (hasXWon() || hasOWon() || getAvailableStates().isEmpty());
}

public boolean hasXWon() {
if ((board[0][0] == board[1][1] && board[0][0] == board[2][2] &&
board[0][0] == 1) || (board[0][2] == board[1][1] && board[0][2] == board[2][0]
&& board[0][2] == 1)) {
//System.out.println("X Diagonal Win");
return true;
}
for (int i = 0; i < 3; ++i) {
if (((board[i][0] == board[i][1] && board[i][0] == board[i][2] &&
board[i][0] == 1)
|| (board[0][i] == board[1][i] && board[0][i] == board[2]
[i] && board[0][i] == 1))) {
// System.out.println("X Row or Column win");
return true;
}
}
return false;
}
public boolean hasOWon() {
if ((board[0][0] == board[1][1] && board[0][0] == board[2][2] &&
board[0][0] == 2) || (board[0][2] == board[1][1] && board[0][2] == board[2][0]
&& board[0][2] == 2)) {
// System.out.println("O Diagonal Win");
return true;
}
for (int i = 0; i < 3; ++i) {
if ((board[i][0] == board[i][1] && board[i][0] == board[i][2] &&
board[i][0] == 2)
|| (board[0][i] == board[1][i] && board[0][i] == board[2]
[i] && board[0][i] == 2)) {

// System.out.println("O Row or Column win");
return true;
}
}
}

return false;


public List<Point> getAvailableStates() {
availablePoints = new ArrayList<>();
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (board[i][j] == 0) {
availablePoints.add(new Point(i, j));
}
}
}
return availablePoints;
}
public void placeAMove(Point point, int player) {
board[point.x][point.y] = player;
//player = 1 for X, 2 for O
}
public Point returnBestMove() {
int MAX = -100000;
int best = -1;
for (int i = 0; i < rootsChildrenScores.size(); ++i) {
if (MAX < rootsChildrenScores.get(i).score) {
MAX = rootsChildrenScores.get(i).score;

best = i;
}
}
}

return rootsChildrenScores.get(best).point;

void takeHumanInput() {
System.out.println("Your move: ");
int x = scan.nextInt();
int y = scan.nextInt();
Point point = new Point(x, y);
placeAMove(point, 2);
}
public void displayBoard() {
System.out.println();
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
System.out.print(board[i][j] + " ");
}
System.out.println();
}

}

public int returnMin(List<Integer> list) {
int min = Integer.MAX_VALUE;
int index = -1;
for (int i = 0; i < list.size(); ++i) {
if (list.get(i) < min) {

min = list.get(i);


}

index = i;

}
return list.get(index);
}
public int returnMax(List<Integer> list) {
int max = Integer.MIN_VALUE;
int index = -1;
for (int i = 0; i < list.size(); ++i) {
if (list.get(i) > max) {
max = list.get(i);
index = i;
}
}
return list.get(index);
}
List<PointsAndScores> rootsChildrenScores;
public void callMinimax(int depth, int turn){
rootsChildrenScores = new ArrayList<>();
minimax(depth, turn);
}
public int minimax(int depth, int turn) {
if (hasXWon()) return +1;
if (hasOWon()) return -1;
List<Point> pointsAvailable = getAvailableStates();

if (pointsAvailable.isEmpty()) return 0;
List<Integer> scores = new ArrayList<>();
for (int i = 0; i < pointsAvailable.size(); ++i) {
Point point = pointsAvailable.get(i);
if (turn == 1) { //X's turn select the highest from below
minimax() call
placeAMove(point, 1);
int currentScore = minimax(depth + 1, 2);
scores.add(currentScore);
if (depth == 0)
rootsChildrenScores.add(new PointsAndScores(currentScore,
point));
} else if (turn == 2) {//O's turn select the lowest from below
minimax() call
placeAMove(point, 2);
scores.add(minimax(depth + 1, 1));
}
board[point.x][point.y] = 0; //Reset this point
}
return turn == 1 ? returnMax(scores) : returnMin(scores);


}

}

public class TicTacToe {
public static void main(String[] args) {
Board b = new Board();
Random rand = new Random();

b.displayBoard();
System.out.println("Who's gonna move first? (1)Computer (2)User: ");
int choice = b.scan.nextInt();
if(choice == 1){
Point p = new Point(rand.nextInt(3), rand.nextInt(3));
b.placeAMove(p, 1);
b.displayBoard();
}
while (!b.isGameOver()) {
System.out.println("Your move: ");
Point userMove = new Point(b.scan.nextInt(), b.scan.nextInt());

pas.score);

b.placeAMove(userMove, 2); //2 for O and O is the user
b.displayBoard();
if (b.isGameOver()) {
break;
}
b.callMinimax(0, 1);
for (PointsAndScores pas : b.rootsChildrenScores) {
System.out.println("Point: " + pas.point + " Score: " +
}
b.placeAMove(b.returnBestMove(), 1);
b.displayBoard();

}

}
if (b.hasXWon()) {

System.out.println("Unfortunately, you lost!");
} else if (b.hasOWon()) {
System.out.println("You win! This is not going to get printed.");
} else {
System.out.println("It's a draw!");
}

}
Sample run:
000
000
000
Who's gonna move first? (1)Computer (2)User:
2
Your move:
22


000
000
002
Point:
Point:
Point:
Point:
Point:
Point:
Point:
Point:


[0,
[0,
[0,
[1,
[1,
[1,
[2,
[2,

0]
1]
2]
0]
1]
2]
0]
1]

Score:
Score:
Score:
Score:
Score:
Score:
Score:
Score:

-1
-1
-1

-1
0
-1
-1
-1

Score:
Score:
Score:
Score:
Score:
Score:

0
-1
0
0
-1
0

Score:
Score:
Score:
Score:

-1
-1
-1
0


000
010
002
Your move:
00
200
010
002
Point:
Point:
Point:
Point:
Point:
Point:

[0,
[0,
[1,
[1,
[2,
[2,

1]
2]
0]
2]
0]
1]

210

010
002
Your move:
21
210
010
022
Point:
Point:
Point:
Point:

[0,
[1,
[1,
[2,

2]
0]
2]
0]

210
010
122
Your move:
02
212
010
122

Point: [1, 0] Score: -1
Point: [1, 2] Score: 0
212


011
122
Your move:
10
212
211
122
It's a draw!
Update:
Here is an improved version. We don't need to evaluate more when we already have found a
winning move, so we just skip rest of the evaluations as soon as we get +1 (for max) or -1
(for min) for some state for the next move.
Source:

import
import
import
import

java.util.ArrayList;
java.util.List;
java.util.Random;
java.util.Scanner;

class Point {

int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}

}

@Override
public String toString() {
return "[" + x + ", " + y + "]";
}

class PointAndScore {
int score;
Point point;
PointAndScore(int score, Point point) {
this.score = score;
this.point = point;
}
}
class Board {
List<Point> availablePoints;
Scanner scan = new Scanner(System.in);
int[][] board = new int[3][3];
public Board() {


}
public boolean isGameOver() {

//Game is over is someone has won, or board is full (draw)
return (hasXWon() || hasOWon() || getAvailableStates().isEmpty());
}
public boolean hasXWon() {
if ((board[0][0] == board[1][1] && board[0][0] == board[2][2] &&
board[0][0] == 1) || (board[0][2] == board[1][1] && board[0][2] == board[2][0]
&& board[0][2] == 1)) {
//System.out.println("X Diagonal Win");
return true;
}
for (int i = 0; i < 3; ++i) {
if (((board[i][0] == board[i][1] && board[i][0] == board[i][2] &&
board[i][0] == 1)
|| (board[0][i] == board[1][i] && board[0][i] == board[2]
[i] && board[0][i] == 1))) {
// System.out.println("X Row or Column win");
return true;
}
}
return false;
}
public boolean hasOWon() {
if ((board[0][0] == board[1][1] && board[0][0] == board[2][2] &&
board[0][0] == 2) || (board[0][2] == board[1][1] && board[0][2] == board[2][0]
&& board[0][2] == 2)) {
// System.out.println("O Diagonal Win");
return true;
}
for (int i = 0; i < 3; ++i) {
if ((board[i][0] == board[i][1] && board[i][0] == board[i][2] &&

board[i][0] == 2)
|| (board[0][i] == board[1][i] && board[0][i] == board[2]
[i] && board[0][i] == 2)) {
// System.out.println("O Row or Column win");
return true;
}
}
return false;
}
public List<Point> getAvailableStates() {
availablePoints = new ArrayList<>();
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (board[i][j] == 0) {
availablePoints.add(new Point(i, j));
}
}
}
return availablePoints;
}


public void placeAMove(Point point, int player) {
board[point.x][point.y] = player;
//player = 1 for X, 2 for O
}
void takeHumanInput() {
System.out.println("Your move: ");
int x = scan.nextInt();
int y = scan.nextInt();

Point point = new Point(x, y);
placeAMove(point, 2);
}
public void displayBoard() {
System.out.println();
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
System.out.print(board[i][j] + " ");
}
System.out.println();
}

}

Point computersMove;
public int minimax(int depth, int turn) {
if (hasXWon()) return +1;
if (hasOWon()) return -1;
List<Point> pointsAvailable = getAvailableStates();
if (pointsAvailable.isEmpty()) return 0;
int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
for (int i = 0; i < pointsAvailable.size(); ++i) {
Point point = pointsAvailable.get(i);
if (turn == 1) {
placeAMove(point, 1);
int currentScore = minimax(depth + 1, 2);
max = Math.max(currentScore, max);
if(depth == 0)System.out.println("Score for position "+(i+1)+"
= "+currentScore);
if(currentScore >= 0){ if(depth == 0) computersMove = point;}

if(currentScore == 1){board[point.x][point.y] = 0; break;}
if(i == pointsAvailable.size()-1 && max < 0){if(depth ==
0)computersMove = point;}
} else if (turn == 2) {
placeAMove(point, 2);
int currentScore = minimax(depth + 1, 1);
min = Math.min(currentScore, min);
if(min == -1){board[point.x][point.y] = 0; break;}
}


}

board[point.x][point.y] = 0; //Reset this point
}
return turn == 1?max:min;

}
public class TicTacToe {
public static void main(String[] args) {
Board b = new Board();
Random rand = new Random();
b.displayBoard();
System.out.println("Select turn:\n\n1. Computer 2. User: ");
int choice = b.scan.nextInt();
if(choice == 1){
Point p = new Point(rand.nextInt(3), rand.nextInt(3));
b.placeAMove(p, 1);
b.displayBoard();
}

while (!b.isGameOver()) {
System.out.println("Your move: ");
Point userMove = new Point(b.scan.nextInt(), b.scan.nextInt());
b.placeAMove(userMove, 2); //2 for O and O is the user
b.displayBoard();
if (b.isGameOver()) break;
b.minimax(0, 1);
b.placeAMove(b.computersMove, 1);
b.displayBoard();

}
}
Output:

}
if (b.hasXWon())
System.out.println("Unfortunately, you lost!");
else if (b.hasOWon())
System.out.println("You win!"); //Can't happen
else
System.out.println("It's a draw!");

000
000
000
Select turn:
1. Computer 2. User:
2
Your move:
22

000


000
002
Score
Score
Score
Score
Score
Score
Score
Score

for
for
for
for
for
for
for
for

position
position
position
position
position
position
position

position

1
2
3
4
5
6
7
8

=
=
=
=
=
=
=
=

-1
-1
-1
-1
0
-1
-1
-1

1

2
3
4
5
6

=
=
=
=
=
=

0
-1
0
0
-1
0

1
2
3
4

=
=
=
=


0
-1
-1
-1

000
010
002
Your move:
00
200
010
002
Score
Score
Score
Score
Score
Score

for
for
for
for
for
for

position
position
position

position
position
position

200
010
012
Your move:
01
220
010
012
Score
Score
Score
Score

for
for
for
for

position
position
position
position

221
010
012

Your move:
20
221
010
212
Score for position 1 = 0
Score for position 2 = -1
221
110


212
Your move:
12
221
112
212
It's a draw!


The unbeatable Tic Tac Toe game, is one of my favorite project I built on Java
(download TicTacToe for windows or TicTacToe for android device).To create an
unbeatable game, you should calculate all possible moves and then choose the
best (the best move is the move that gives you win). To do so, I used the MiniMax
algorithm.

What is MiniMax algorithm?
MiniMax is a decision rule used in decision theory, game theory, statistics and
philosophy for minimizing the possible loss for a worst case (maximum loss)
scenario. Alternatively, it can be thought of as maximizing the minimum gain

(MaxiMin). Originally formulated for two-player zero sum game theory, covering both the
cases where players take alternate moves and those where they make simultaneous
moves, it has also been extended to more complex games and to general decision
making in the presence of uncertainty. (Reference: Wikipedia - MiniMax)

Implementing MiniMax on Tic Tac Toe game:

1) How MiniMax Works
To create an unbeatable Tic Tac Toe game, the computer needs to win the game or draw the game.
So let's give each situation a score:
- If computer wins, the score is +1,
- If computer loses , the score is -1,
- If computer draws, the score is 0.
(Note: The computer is O and the player is X).

The two players (the computer and the player) are defined as Max (computer) and Min (player). The
computer should always search for the best score (the best score is the highest score), and let's
suppose that the player is a powerful player, so the player will search for the worst score (the lowest
score, the lowest score for the player is the best score for him).
Scenario 1 :


It's computer's turn and it has two choices ( A and B).
If it choose B the score will be 0, but if it choose A it gets +1. And because the computer is Max, it
will choose A and get the highest score.
Scenario 2 :



It's computer's turn and it has three options (A, B and C).

- If it choose A, the player has two choices A1 and A2, if the player choose A1 the game is draw and
the score is 0.But if the player choose A2 the score is -1, and because it's player's turn (Min) the
player gives the computer the worst score which is -1, so back to top, Choice (A) gives the
computer the score -1.
- If the computer choose B, the player has two choices B1 and B2, if the player choose B1, the game
is draw so the score is 0. But if the player choose B2, the player wins and the score is -1, and
because the player is Min, he gives the computer the worst score so between B1(score=0) and
B2(score=-1) the player will choose B2. So back to top, Choice (B) gives the computer the score -1.
- If the computer choose C, the player has two choice C1 and C2. If he choose C1 the game is draw
so the score is 0, and if the player choose C2 the game is draw too and the score is 0.
C1 gives 0 and C2 gives also 0 this means that if the computer choose C the score is 0.
So for conclusion :
-A gives score -1,
-B gives score -1,
-C gives score 0,
and because it's computer's turn (Max) the computer will choose the highest score (0 is the highest
score), so the computer will choose the (C) choice.
Now let's resume all the above:
- We have two players: Max and Min,
- The Max always choose the best score,
- The Min player choose the worst score.
In the Tic Tac Toe game the computer is the Max player because we want to build an unbeatable
game, which makes the player the Min player.

2) How implementing MiniMax on Java:Now we will take a look on how to implement MiniMax in
Java. (Note: I will note talk about graphics and interface, only about algorithm).
We will use the ResultMM class for the algorithm. This class has 3 attributes (score, depth and
matrix)
public class ResultMM {
String[] matrix;

int score;
int depth;
public ResultMM(String[] matrix, int score, int depth)
{
this.matrix = matrix;
this.score = score;
this.depth = depth;
}
public void updateMatrix(String[] matrix)
{


this.matrix = matrix;
}
public int getScore()
{
return score;
}
public int getIntrus()
{
for(int i=0; i<9; i++)
if(matrix[i].equals("o"))
return i;
return -1;
}
}

Now the Controller Class. The Controller Class contains 2 attributes, and 9 methods:

//gameXO is the game

static String[] gameXO = new String[9];
//_sdepth is used to control the depth
static int sdepth;

1) The Constructor:

public Controller()
{//reInitialise the gameXO when i create a new controller
for(int i=0; i<9; i++)
gameXO[i] = " ";
}

2) inverse: this method is used to toggle between level (Min and Max)

public String inverse(String level)
{ //inverse level from MIN to MAX
return (level.equals("MIN")) ? "MAX" : "MIN" ;
}

3)getScore: this method calculates the score.
-If player O (computer) wins, the score is +1,
-If player X (player) wins, the score is -1,
-If game draw, the score is 0.


public int getScore(String[] demo)
{ //return the score:
//if X win return -1;
//if O win return 1;
//else return 0, this mean draw

if( (demo[0].equalsIgnoreCase("x") && demo[1].equalsIgnoreCase("x")
&& demo[2].equalsIgnoreCase("x")) || (demo[3].equalsIgnoreCase("x") &&
demo[4].equalsIgnoreCase("x") && demo[5].equalsIgnoreCase("x")) ||
(demo[6].equalsIgnoreCase("x") &&
demo[7].equalsIgnoreCase("x") && demo[8].equalsIgnoreCase("x")) ||
(demo[0].equalsIgnoreCase("x") && demo[3].equalsIgnoreCase("x") &&
demo[6].equalsIgnoreCase("x")) ||
(demo[1].equalsIgnoreCase("x") &&
demo[4].equalsIgnoreCase("x") && demo[7].equalsIgnoreCase("x")) ||
(demo[2].equalsIgnoreCase("x") && demo[5].equalsIgnoreCase("x") &&
demo[8].equalsIgnoreCase("x")) ||
(demo[0].equalsIgnoreCase("x") &&
demo[4].equalsIgnoreCase("x") && demo[8].equalsIgnoreCase("x")) ||
(demo[2].equalsIgnoreCase("x") && demo[4].equalsIgnoreCase("x") &&
demo[6].equalsIgnoreCase("x"))
)
return -1;
if( (demo[0].equalsIgnoreCase("o") && demo[1].equalsIgnoreCase("o")
&& demo[2].equalsIgnoreCase("o")) || (demo[3].equalsIgnoreCase("o") &&
demo[4].equalsIgnoreCase("o") && demo[5].equalsIgnoreCase("o")) ||
(demo[6].equalsIgnoreCase("o") &&
demo[7].equalsIgnoreCase("o") && demo[8].equalsIgnoreCase("o")) ||
(demo[0].equalsIgnoreCase("o") && demo[3].equalsIgnoreCase("o") &&
demo[6].equalsIgnoreCase("o")) ||
(demo[1].equalsIgnoreCase("o") &&
demo[4].equalsIgnoreCase("o") && demo[7].equalsIgnoreCase("o")) ||
(demo[2].equalsIgnoreCase("o") && demo[5].equalsIgnoreCase("o") &&
demo[8].equalsIgnoreCase("o")) ||
(demo[0].equalsIgnoreCase("o") &&
demo[4].equalsIgnoreCase("o") && demo[8].equalsIgnoreCase("o")) ||

(demo[2].equalsIgnoreCase("o") && demo[4].equalsIgnoreCase("o") &&
demo[6].equalsIgnoreCase("o"))
)
return 1;
return 0;
}


4)gameDraw: this method is used to check if the game is draw

public boolean drawGame(String[] demo)
{
//test if the game is draw.
//if demo is full, this mean that game is draw
//if demo still has empty square, this mean that the game isn't
finished
for(int i=0; i<9; i++)
if(demo[i].equals(" "))
return false;
return true;
}

5)gameOver: this method is used to check if there is a winner

public boolean gameOver(String[] demo)
{//if the score of the game is 0 then return false else we have a winner
return (getScore(demo)!=0) ? true : false;
}

6)genere_succ: this method is used to generate successors.

(like in the photo of Scenario2, (A) (B) (C) are the successor of the main game, (A1) (A2) are the
successor of (A) ).

public ArrayList<String[]> genere_succ(String[] demo, String level)
{//generate successor
//if level is MAX, generate successor with o (o in lowercase)
//if level is MIN, generate successor with x (x in lowercase)
//if demo has no successor, return null
ArrayList<String[]> succ = new ArrayList<String[]>();
for(int i=0; i{
if( demo[i].equals(" ") )
{
String[] child = new String[9];
for(int j=0; j<9; j++)
child[j] = demo[j];
if(level.equals("MAX"))
child[i] = "o";
else


child[i] = "x";
succ.add(child);
}
}
return ( succ.size() == 0 ) ? null : succ ;
}

7)getResult: this method is used to choose the appropriate score. This mean if the level is Max we
have to choose the highest score, but if level is Min we choose the lowest score.


public ResultMM getResult(ArrayList<ResultMM> listScore, String level)
{//this method is used to get the appropriate score
//if level is MAX, i search for the higher score in the nearer
depth
//if level is MIN, i search for the lowest score in the nearer
depth
ResultMM result= listScore.get(0);
if(level.equals("MAX"))
{
for(int i=1; i{
if( (listScore.get(i).getScore() > result.getScore())
||
(listScore.get(i).getScore() ==
result.getScore() && listScore.get(i).depth < result.depth) )
result = listScore.get(i);
}
}
else
{
for(int i=1; i{
if( (listScore.get(i).getScore() < result.getScore())
||
(listScore.get(i).getScore() == result.getScore() &&
listScore.get(i).depth < result.depth) )
result = listScore.get(i);
}
}

return result;
}


8)MinMax: this is the principal function that calls all the above methods.

public ResultMM MinMax(String[] demo, String level, int fils, int depth)
{/*MinMax algorithm
* 1- generate successor
* 2- if no successor or game is finished return score
* 3- if there is successor
*
a) apply MinMax for each successor
*
b) after recursive call, i return the good score
*/
//1--------------ArrayList<String[]> children = genere_succ(demo,level);
//2-----------------if(children == null || gameOver(demo))
{
return new ResultMM(demo, getScore(demo), depth);
}
else
{//3-----------------ArrayList<ResultMM> listScore = new ArrayList<ResultMM>();
//pass into each child
for(int i = 0; i{//3 a)--------------listScore.add( MinMax(children.get(i), inverse(level), 1,
depth+1));
}
//3 b)---------------ResultMM res = getResult(listScore, level);
if( fils == 1)

res.updateMatrix(demo);
return res;
}
}

9)MakeMove: the method that calls the MiniMax method.

public int makeMove(int index)
{
/*Step to do in this method
*1- update gameXO. put X in the gameXO[index]
*2- test if game is finished (draw or X win)


*3- call MinMax algorithm and return the score and return the best
position for O
*4- update gameXO. put O in its position
*5- test if game is finished (draw or O win)
*/
//return -1 to know that player X wins
//return -2 to know that the game is draw
//1
gameXO[index] = "X";
//2
if(gameOver(gameXO)) { return -1; }
if(drawGame(gameXO)) { return -2; }
//3
ResultMM res = MinMax(gameXO,"MAX", 0, 0);
int i = res.getIntrus();
//4

gameXO[i] = "O";
//5
// return i+20 to know that o wins (i used this method for
programming issues)
// retrun i-30 to know that the game is draw (i used this method
for programming issues)
if(gameOver(gameXO)) { return i+20; }
if(drawGame(gameXO)) { return i-30;
}
return i;
}



×