# Finding the optimal tic-tac-toe using the Minimax algorithm in game theory (2023)

Requirements:The Minimax algorithm in game theory,Evaluation function in game theory
Let's combine what we've learned so far about the minimax and the estimator to write a real tic-tac-toeDO(AArtificiallyIintelligence) playing the perfect game. This artificial intelligence takes into account all possible scenarios and makes the optimal move.

#### Find the best move:

We will introduce a new function calledfindBestMove(). This feature evaluates all available movesminimax()and then returns the best move the maximizer can make. The pseudocode is as follows:

`functionfindBestMove(array):bestMove = NULLfor everyoneboardmove: if current move is better than bestMove bestMove = current movereturnbest move`

#### Minimum:

To check if the current traffic is better than the best, we use helpminimax()A function that considers all possible play paths and returns the best value for that move, assuming the opponent is also playing optimally

Code for maximizing and minimizingminimax()the function is similarfindBestMove(), the only difference is that it returns a value instead of a move. Here is the pseudocode:

`functionminimax(Board, Tiefe, isMaximizingPlayer):IThe current state of the array is the final state:returnplate valueIisMaximizingPlayer: bestVal = -INFINITYfor everyoneMove Panel: Value = Minimax(Panel, Depth+1, False) BestVal = Max( BestVal, Value)returnbestValInside: bestVal = +INFINITEfor everyoneMove panel: Value = Minimax(Panel, Depth+1, True) BestVal = Min(BestVal, Value)returnbestVal`

#### GameOver Status Function:

It is used to check if the game is over and to make sure there are no more moves leftisMovesLeft()Function. This is a simple direct function that checks if a train is available or not and returns true or false accordingly. The pseudocode is as follows:

`functionisMovesLeft(table):for everyonepanel cell:IThe current cell is empty:returnis saidreturnimproperly`

#### Improving our AI:

The final step is to make our AI a little smarter. Even if the next AI plays perfectly, it may decide a move that will lead to a slower win or a faster loss. Let's take an example and explain it.
Suppose X can win the game in two ways from a given state of the board.

• MoveA: X can win in 2 moves
• MoveB: X can win in 4 moves

Our evaluation function returns +10 for both movesAIB. Although the movementAis better because it provides faster win rate that our AI can pickBSometimes. To solve this problem, we subtract the depth value from the estimated result. This means that if he wins, he chooses the one that requires as few moves as possible, and if he loses, he tries to extend the game and play as many moves as possible. So the new estimate will be

• MoveAwill be +10 - 2 = 8
• MoveBwill be +10 - 4 = 6

Now since movingAhas a higher score compared to moveBOur artificial intelligence will choose the moveAabout the movementsB. The same goes for the minimizer. Instead of subtracting the depth, we add the depth value because the minimizer always tries to get as negative a value as possible. We can subtract the depth inside or outside the estimator. It's good everywhere. I decided to do it outside the office. The pseudocode implementation is as follows.

`IMaximizer won:returnWIN_SCORE – dubinaotherwise ifMinimizer won:returnLOOSE_SCORE + dubin`

Recommended practice

Another optimal move in Tic Tac Toe

try it!

Below is an implementation of the above idea.

## C++

`// C++ program to find the next optimal move`

`// Player`

`#to contain`

`use` `Imenski-Raum` `standard;`

`built` `Move`

`{`

`int` `row column;`

`};`

`char` `player =``'X'``, opponent =``„Ö”``;`

`// This function returns true if there is an offset`

`// stay on board. Returns false if`

`// There are no more moves to play.`

`bool` `isMovesLeft(``char` `Board  )`

`{`

`Do` `(``int` `i = 0; i<3; i++)`

`Do` `(``int` `j = 0; j<3; j++)`

`I` `(table[i][j]==``„_”``)`

`return` `is said``;`

`return` `improperly``;`

`}`

`// This is the evaluation function mentioned`

`// in the previous article (http://goo.gl/sJgv68)`

`int` `treasure (``char` `b)`

`{`

`// Check rows for X or O profit.`

`Do` `(``int` `edit = 0; rot<3; rot++)`

`{`

`I` `(b[red]==b[red] &&`

`b[red]==b[red])`

`{`

`I` `(b[row]==player)`

`return` `+10;`

`Inside` `I` `(b[red]==opponent)`

`return` `-10;`

`}`

`}`

`// Check columns for X or O gain.`

`Do` `(``int` `column = 0; column<3; column++)`

`{`

`I` `(b[column]==b[column] &&`

`b[kol]==b[kol])`

`{`

`I` `(b[col]==player)`

`return` `+10;`

`Inside` `I` `(b[col]==opponent)`

`return` `-10;`

`}`

`}`

`// Check diagonals for X or O win.`

`I` `(b==b && b==b)`

`{`

`I` `(b==player)`

`return` `+10;`

`Inside` `I` `(b==opponent)`

`return` `-10;`

`}`

`I` `(b==b && b==b)`

`{`

`I` `(b==player)`

`return` `+10;`

`Inside` `I` `(b==opponent)`

`return` `-10;`

`}`

`// Otherwise, if none of them won, return 0`

`return` `0;`

`}`

`// This is the minimax function. It takes everything into account`

`// Possible ways the game can go and come back`

`// board value`

`int` `minimum tax (``char` `Brett,``int` `Depth,``bool` `jeMax)`

`{`

`int` `result = stake (array);`

`// If Maximizer won the game, give it to him`

`// estimated result`

`I` `(Score == 10)`

`return` `to achieve;`

`// If Minimizer won the game, give it back to him`

`// estimated result`

`I` `(Score == -10)`

`return` `to achieve;`

`// If then there are no more moves or winners`

`// there is a tie`

`I` `(isMovesLeft(board)==``improperly``)`

`return` `0;`

`// If this move is a maximizer`

`I` `(is max.)`

`{`

`int` `best = -1000;`

`// loop through all cells`

`Do` `(``int` `i = 0; i<3; i++)`

`{`

`Do` `(``int` `j = 0; j<3; j++)`

`{`

`// Check if the cell is empty`

`I` `(table[i][j]==``„_”``)`

`{`

`// Take a step`

`board[i][j] = player;`

`// call and select minimax recursively`

`// maximum value`

`best = maximum (best,`

`minimax(slab, depth+1, !isMax) );`

`// Undo move`

`Brett[i][j] =``„_”``;`

`}`

`}`

`}`

`return` `best;`

`}`

`// When this minimizer moves`

`Inside`

`{`

`int` `best = 1000;`

`// loop through all cells`

`Do` `(``int` `i = 0; i<3; i++)`

`{`

`Do` `(``int` `j = 0; j<3; j++)`

`{`

`// Check if the cell is empty`

`I` `(table[i][j]==``„_”``)`

`{`

`// Take a step`

`array[i][j] = opponent;`

`// call and select minimax recursively`

`// minimum value`

`best = min(best,`

`minimax(slab, depth+1, !isMax));`

`// Undo move`

`Brett[i][j] =``„_”``;`

`}`

`}`

`}`

`return` `best;`

`}`

`}`

`// This returns the player the best possible move`

`move findBestMove(``char` `Board  )`

`{`

`int` `best value = -1000;`

`make the best move;`

`best move.row = -1;`

`best move.col = -1;`

`// Go through all the cells and evaluate the minimax function for`

`// all empty cells. And return the cell with the optimum`

`// Wert.`

`Do` `(``int` `i = 0; i<3; i++)`

`{`

`Do` `(``int` `j = 0; j<3; j++)`

`{`

`// Check if the cell is empty`

`I` `(table[i][j]==``„_”``)`

`{`

`// Take a step`

`board[i][j] = player;`

`// Calculate an estimator for it`

`// Move.`

`int` `moveVal = minimax(width, 0,``improperly``);`

`// Undo move`

`Brett[i][j] =``„_”``;`

`// If the value of the current move`

`// more than best value then update`

`// the best/`

`I` `(moveVal > bestVal)`

`{`

`best move.row = i;`

`best move.col = j;`

`bestvalue = transfervalue;`

`}`

`}`

`}`

`}`

`print``(``"The value of the best move is: %d\n\n"``,`

`bestVal);`

`return` `best move;`

`}`

`// At the driver's`

`int` `mainly()`

`{`

`char` `Brett =`

`{`

`{``'X'``,``„Ö”``,``'X'` `},`

`{``„Ö”``,``„Ö”``,``'X'` `},`

`{``„_”``,``„_”``,``„_”` `}`

`};`

`Move Best Move = findBest Move(table);`

`print``(``"The optimal move is:\n"``);`

`print``(``„REDACT: %d COL: %d\n\n“``, bestMove.row,`

`bestMove.col );`

`return` `0;`

`}`

## Java

`// Java search program`

`// the next optimal move for the player`

`Class` `GFG`

`{`

`static` `Class` `Move`

`{`

`int` `row column;`

`};`

`static` `char` `player =``'X'``, opponent =``„Ö”``;`

`// This function returns true if there is an offset`

`// stay on board. Returns false if`

`// There are no more moves to play.`

`static` `Boolean is a move to the left(``char` `Planks[][])`

`{`

`Do` `(``int` `i =``0``; i <``3``; i++)`

`Do` `(``int` `j =``0``; j <``3``; j++)`

`I` `(table[i][j] ==``„_”``)`

`return` `is said``;`

`return` `improperly``;`

`}`

`// This is the evaluation function mentioned`

`// in the previous article (http://goo.gl/sJgv68)`

`static` `int` `treasure (``char` `B[][])`

`{`

`// Check rows for X or O profit.`

`Do` `(``int` `rot =``0``; line <``3``; rot ++)`

`{`

`I` `(brew][``0``] == b[rot][``1``] &&`

`brew][``1``] == b[rot][``2``])`

`{`

`I` `(brew][``0``] == player)`

`return` `+``10``;`

`Inside` `I` `(brew][``0``] == opponent)`

`return` `-``10``;`

`}`

`}`

`// Check columns for X or O gain.`

`Do` `(``int` `column =``0``; column <``3``; column++)`

`{`

`I` `(B[``0``[kol] == b[``1``[Division] &&`

`B[``1``[kol] == b[``2``[kol])`

`{`

`I` `(B[``0``[column] == player)`

`return` `+``10``;`

`Inside` `I` `(B[``0``][col] == opponent)`

`return` `-``10``;`

`}`

`}`

`// Check diagonals for X or O win.`

`I` `(B[``0``][``0``] == b[``1``][``1``] && B[``1``][``1``] == b[``2``][``2``])`

`{`

`I` `(B[``0``][``0``] == player)`

`return` `+``10``;`

`Inside` `I` `(B[``0``][``0``] == opponent)`

`return` `-``10``;`

`}`

`I` `(B[``0``][``2``] == b[``1``][``1``] && B[``1``][``1``] == b[``2``][``0``])`

`{`

`I` `(B[``0``][``2``] == player)`

`return` `+``10``;`

`Inside` `I` `(B[``0``][``2``] == opponent)`

`return` `-``10``;`

`}`

`// Otherwise, if none of them won, return 0`

`return` `0``;`

`}`

`// This is the minimax function. It takes everything into account`

`// Possible ways the game can go and come back`

`// board value`

`static` `int` `minimum tax (``char` `boards[][],`

`int` `depth, logical value is maximum)`

`{`

`int` `result = stake (array);`

`// If Maximizer won the game`

`// returns his/her estimated score`

`I` `(Result ==``10``)`

`return` `to achieve;`

`// If Minimizer won the game`

`// returns his/her estimated score`

`I` `(Result == -``10``)`

`return` `to achieve;`

`// if there are no more trains i`

`// No winner, then it's a tie`

`I` `(isMovesLeft(board) ==``improperly``)`

`return` `0``;`

`// If this move is a maximizer`

`I` `(is max.)`

`{`

`int` `best = -``1000``;`

`// loop through all cells`

`Do` `(``int` `i =``0``; i <``3``; i++)`

`{`

`Do` `(``int` `j =``0``; j <``3``; j++)`

`{`

`// Check if the cell is empty`

`I` `(table[i][j]==``„_”``)`

`{`

`// Take a step`

`board[i][j] = player;`

`// call and select minimax recursively`

`// maximum value`

`best = Math.max(best, minimax(array,`

`depth +``1``, !jeMax));`

`// Undo move`

`Brett[i][j] =``„_”``;`

`}`

`}`

`}`

`return` `best;`

`}`

`// When this minimizer moves`

`Inside`

`{`

`int` `best =``1000``;`

`// loop through all cells`

`Do` `(``int` `i =``0``; i <``3``; i++)`

`{`

`Do` `(``int` `j =``0``; j <``3``; j++)`

`{`

`// Check if the cell is empty`

`I` `(table[i][j] ==``„_”``)`

`{`

`// Take a step`

`array[i][j] = opponent;`

`// call and select minimax recursively`

`// minimum value`

`best = Math.min(best, minimax(array,`

`depth +``1``, !jeMax));`

`// Undo move`

`Brett[i][j] =``„_”``;`

`}`

`}`

`}`

`return` `best;`

`}`

`}`

`// This will give the best possible result`

`// move instead of player`

`static` `move findBestMove(``char` `Planks[][])`

`{`

`int` `best value=-``1000``;`

`Scroll best Scroll =``new` `move();`

`bestMove.row = -``1``;`

`bestMove.col = -``1``;`

`// Iterate through all the cells and evaluate the minimax function`

`// for all empty cells. And return the cell`

`// with the optimal value.`

`Do` `(``int` `i =``0``; i <``3``; i++)`

`{`

`Do` `(``int` `j =``0``; j <``3``; j++)`

`{`

`// Check if the cell is empty`

`I` `(table[i][j] ==``„_”``)`

`{`

`// Take a step`

`board[i][j] = player;`

`// Calculate an estimator for it`

`// Move.`

`int` `moveVal = minimax(width,``0``,``improperly``);`

`// Undo move`

`Brett[i][j] =``„_”``;`

`// If the value of the current move`

`// more than best value then update`

`// the best/`

`I` `(moveVal > bestVal)`

`{`

`best move.row = i;`

`best move.col = j;`

`bestvalue = transfervalue;`

`}`

`}`

`}`

`}`

`System.out.printf(``"Best Moving Value"` `+`

`"Ha: %d\n\n"``, bestVal);`

`return` `best move;`

`}`

`// At the driver's`

`public` `static` `cancel` `main (String[]-Argument)`

`{`

`char` `Brett[][] = {{``'X'``,``„Ö”``,``'X'` `},`

`{``„Ö”``,``„Ö”``,``'X'` `},`

`{``„_”``,``„_”``,``„_”` `}};`

`Move Best Move = findBest Move(table);`

`System.out.printf(``"The optimal move is:\n"``);`

`System.out.printf(``„REDACT: %d COL: %d\n\n“``,`

`bestMove.wiersz, bestMove.col );`

`}`

`}`

`// This code was created by PrinciRaj1992`

## Python3

`# Python3 program to find the next optimal move for the player`

`player, opponent``=` `'X'``,``„Ö”`

`# This function returns true if there is an offset`

`# stay on board. Returns false if`

`# No more moves to play.`

`pok` `isMovesLeft(board) :`

`Do` `I``u` `Area``(``3``) :`

`Do` `J``u` `Area``(``3``) :`

`I` `(Table[i][j]``=``=` `„_”``) :`

`return` `It is said`

`return` `improperly`

`# This is the evaluation function mentioned`

`# in the previous article (http://goo.gl/sJgv68)`

`pok` `Rate (b):`

`# Check lines for X or O win.`

`Do` `Rot``u` `Area``(``3``) :`

`I` `(brew][``0``]``=``=` `brew][``1``]``I` `brew][``1``]``=``=` `brew][``2``]):`

`I` `(brew][``0``]``=``=` `Player) :`

`return` `10`

`Elif` `(brew][``0``]``=``=` `Opponent):`

`return` `-``10`

`# Check columns for X or O gain.`

`Do` `kol``u` `Area``(``3``) :`

`I` `(B[``0``][pass]``=``=` `B[``1``][pass]``I` `B[``1``][pass]``=``=` `B[``2``[kol]):`

`I` `(B[``0``][pass]``=``=` `Player) :`

`return` `10`

`Elif` `(B[``0``][pass]``=``=` `Opponent):`

`return` `-``10`

`# Check diagonals for X or O win.`

`I` `(B[``0``][``0``]``=``=` `B[``1``][``1``]``I` `B[``1``][``1``]``=``=` `B[``2``][``2``]):`

`I` `(B[``0``][``0``]``=``=` `Player) :`

`return` `10`

`Elif` `(B[``0``][``0``]``=``=` `Opponent):`

`return` `-``10`

`I` `(B[``0``][``2``]``=``=` `B[``1``][``1``]``I` `B[``1``][``1``]``=``=` `B[``2``][``0``]):`

`I` `(B[``0``][``2``]``=``=` `Player) :`

`return` `10`

`Elif` `(B[``0``][``2``]``=``=` `Opponent):`

`return` `-``10`

`# Otherwise, if none of them won, return 0`

`return` `0`

`# This is the minimax function. It takes everything into account`

`# possible ways to exit and return the game`

`# array value`

`pok` `minimax(slab; depth; isMax) :`

`to achieve``=` `Tariff (meal)`

`# If Maximizer won the game, pay him`

`# estimated result`

`I` `(to achieve``=``=` `10``) :`

`return` `to achieve`

`# If Minimizer won the game, return it`

`# estimated result`

`I` `(to achieve``=``=` `-``10``) :`

`return` `to achieve`

`# When there are no more moves and no winners`

`# to remis`

`I` `(swipe left (panel)``=``=` `improperly``) :`

`return` `0`

`# If it is a maximizing move`

`I` `(jeMax):`

`best``=` `-``1000`

`# View all cells`

`Do` `I``u` `Area``(``3``) :`

`Do` `J``u` `Area``(``3``) :`

`# Check if the cell is empty`

`I` `(Table[i][j]``=``=``„_”``) :`

`# Take a step`

`Brett[i][j]``=` `player`

`# Call and select minimax recursively`

`# maximum value`

`best``=` `maks``(best, minimax (board,`

`depth``+` `1``,`

`This is` `Maks))`

`# Undo move`

`Brett[i][j]``=` `„_”`

`return` `best`

`# When will this minimizer be moved`

`Inside` `:`

`best``=` `1000`

`# View all cells`

`Do` `I``u` `Area``(``3``) :`

`Do` `J``u` `Area``(``3``) :`

`# Check if the cell is empty`

`I` `(Table[i][j]``=``=` `„_”``) :`

`# Take a step`

`Brett[i][j]``=` `Opponent`

`# Call and select minimax recursively`

`# minimum value`

`best``=` `Minimum``(preferably, minimax(board, depth``+` `1``,``This is` `Maks))`

`# Undo move`

`Brett[i][j]``=` `„_”`

`return` `best`

`# Returns the player the best possible move`

`pok` `findBestMove(board):`

`bestVal``=` `-``1000`

`best move``=` `(``-``1``,``-``1``)`

`# Go through all the cells and evaluate the minimax function for`

`# all blank cells. And return the cell with the optimum`

`# Wert.`

`Do` `I``u` `Area``(``3``) :`

`Do` `J``u` `Area``(``3``) :`

`# Check if the cell is empty`

`I` `(Table[i][j]``=``=` `„_”``) :`

`# Take a step`

`Brett[i][j]``=` `player`

`# Calculate the estimator for this`

`# Move.`

`ruchWal``=` `Minimax(plate,``0``,``improperly``)`

`# Undo move`

`Brett[i][j]``=` `„_”`

`# If the value of the current move`

`# more than best value then update`

`#rather/`

`I` `(moveVal > bestVal):`

`best move``=` `(me J)`

`bestVal``=` `ruchWal`

`print``(``"The value of the best move is:"``, best value)`

`print``()`

`return` `best move`

`# On the driver's door`

`boards``=` `[`

`[``'X'``,``„Ö”``,``'X'` `],`

`[``„Ö”``,``„Ö”``,``'X'` `],`

`[``„_”``,``„_”``,``„_”` `]`

`]`

`best move``=` `findBestMove (table)`

`print``(``"The optimal move is:"``)`

`print``(``"ROT:"``, best move[``0``],``"PASS:"``, best move[``1``])`

`# This code was submitted by divyesh072019`

## C#

`// search program in C#`

`// the next optimal move for the player`

`use` `System;`

`use` `System.Collections.Generic;`

`Class` `GFG`

`{`

`Class` `Move`

`{`

`public` `int` `row column;`

`};`

`static` `char` `player =``'X'``, opponent =``„Ö”``;`

`// This function returns true if there is an offset`

`// stay on board. Returns false if`

`// There are no more moves to play.`

`static` `Boolean is a move to the left(``char` `[,] boards)`

`{`

`Do` `(``int` `i = 0; i < 3; i++)`

`Do` `(``int` `j = 0; d < 3; j++)`

`I` `(table[i, j] ==``„_”``)`

`return` `is said``;`

`return` `improperly``;`

`}`

`// This is the evaluation function mentioned`

`// in the previous article (http://goo.gl/sJgv68)`

`static` `int` `treasure (``char` `[,]B)`

`{`

`// Check rows for X or O profit.`

`Do` `(``int` `row = 0; line < 3; line++)`

`{`

`I` `(b[rotation, 0] == b[rotation, 1] &&`

`b[rotation, 1] == b[rotation, 2])`

`{`

`I` `(b[row, 0] == player)`

`return` `+10;`

`Inside` `I` `(b[red, 0] == protivnik)`

`return` `-10;`

`}`

`}`

`// Check columns for X or O gain.`

`Do` `(``int` `column = 0; column < 3; column++)`

`{`

`I` `(b[0, column] == b[1, column] &&`

`b[1, column] == b[2, column])`

`{`

`I` `(b[0, col] == player)`

`return` `+10;`

`Inside` `I` `(b[0, col] == opponent)`

`return` `-10;`

`}`

`}`

`// Check diagonals for X or O win.`

`I` `(b[0, 0] == b[1, 1] && b[1, 1] == b[2, 2])`

`{`

`I` `(b[0, 0] == player)`

`return` `+10;`

`Inside` `I` `(b[0, 0] == opponent)`

`return` `-10;`

`}`

`I` `(b[0, 2] == b[1, 1] && b[1, 1] == b[2, 0])`

`{`

`I` `(b[0, 2] == player)`

`return` `+10;`

`Inside` `I` `(b[0, 2] == opponent)`

`return` `-10;`

`}`

`// Otherwise, if none of them won, return 0`

`return` `0;`

`}`

`// This is the minimax function. It takes everything into account`

`// Possible ways the game can go and come back`

`// board value`

`static` `int` `minimum tax (``char` `[,]Boards,`

`int` `depth, logical value is maximum)`

`{`

`int` `result = stake (array);`

`// If Maximizer won the game`

`// returns his/her estimated score`

`I` `(Score == 10)`

`return` `to achieve;`

`// If Minimizer won the game`

`// returns his/her estimated score`

`I` `(Score == -10)`

`return` `to achieve;`

`// if there are no more trains i`

`// No winner, then it's a tie`

`I` `(isMovesLeft(board) ==``improperly``)`

`return` `0;`

`// If this move is a maximizer`

`I` `(is max.)`

`{`

`int` `best = -1000;`

`// loop through all cells`

`Do` `(``int` `i = 0; i < 3; i++)`

`{`

`Do` `(``int` `j = 0; d < 3; j++)`

`{`

`// Check if the cell is empty`

`I` `(table[i, j] ==``„_”``)`

`{`

`// Take a step`

`board[i,j] = player;`

`// call and select minimax recursively`

`// maximum value`

`best = Math.Max(best, minimax(array,`

`dubina + 1, !isMax));`

`// Undo move`

`Brett[i, j] =``„_”``;`

`}`

`}`

`}`

`return` `best;`

`}`

`// When this minimizer moves`

`Inside`

`{`

`int` `best = 1000;`

`// loop through all cells`

`Do` `(``int` `i = 0; i < 3; i++)`

`{`

`Do` `(``int` `j = 0; d < 3; j++)`

`{`

`// Check if the cell is empty`

`I` `(table[i, j] ==``„_”``)`

`{`

`// Take a step`

`board[i,j] = opponent;`

`// call and select minimax recursively`

`// minimum value`

`best = Math.Min(best, minimax(array,`

`dubina + 1, !isMax));`

`// Undo move`

`Brett[i, j] =``„_”``;`

`}`

`}`

`}`

`return` `best;`

`}`

`}`

`// This will give the best possible result`

`// move instead of player`

`static` `move findBestMove(``char` `[,] boards)`

`{`

`int` `best value = -1000;`

`Scroll best Scroll =``new` `move();`

`best move.row = -1;`

`best move.col = -1;`

`// Iterate through all the cells and evaluate the minimax function`

`// for all empty cells. And return the cell`

`// with the optimal value.`

`Do` `(``int` `i = 0; i < 3; i++)`

`{`

`Do` `(``int` `j = 0; d < 3; j++)`

`{`

`// Check if the cell is empty`

`I` `(table[i, j] ==``„_”``)`

`{`

`// Take a step`

`board[i,j] = player;`

`// Calculate an estimator for it`

`// Move.`

`int` `moveVal = minimax(width, 0,``improperly``);`

`// Undo move`

`Brett[i, j] =``„_”``;`

`// If the value of the current move`

`// more than best value then update`

`// the best/`

`I` `(moveVal > bestVal)`

`{`

`best move.row = i;`

`best move.col = j;`

`bestvalue = transfervalue;`

`}`

`}`

`}`

`}`

`Console.Write(``"Best Moving Value"` `+`

`"Ty: {0}\n\n"``, bestVal);`

`return` `best move;`

`}`

`// At the driver's`

`public` `static` `cancel` `Main(String[] argumenty)`

`{`

`char` `[,]table = {{``'X'``,``„Ö”``,``'X'` `},`

`{``„Ö”``,``„Ö”``,``'X'` `},`

`{``„_”``,``„_”``,``„_”` `}};`

`Move Best Move = findBest Move(table);`

`Console.Write(``"The optimal move is:\n"``);`

`Console.Write(``"READ: {0} COLOR: {1}\n\n"``,`

`bestMove.wiersz, bestMove.col );`

`}`

`}`

`// This code was submitted by 29AjayKumar`

## JavaScript

`// JavaScript search engine`

`// the next optimal move for the player`

`class movement`

`{`

`Constructor()`

`{`

`row, buddy;`

`}`

`}`

`let the player =``'X'``, opponent =``„Ö”``;`

`// This function returns true if there is an offset`

`// stay on board. Returns false if`

`// There are no more moves to play.`

`function` `moves to the left (platter)`

`{`

`Do``(six i = 0; i < 3; i++)`

`Do``(six j = 0; j < 3; j++)`

`I` `(table[i][j] ==``„_”``)`

`return` `is said``;`

`return` `improperly``;`

`}`

`// This is the evaluation function mentioned`

`// in the previous article (http://goo.gl/sJgv68)`

`function` `rate (b)`

`{`

`// Check rows for X or O profit.`

`Do``(let row = 0; row < 3; row++)`

`{`

`I` `(b[red] == b[red] &&`

`b[red] == b[red])`

`{`

`I` `(b[row] == player)`

`return` `+10;`

`Inside` `I` `(b[red] == opponent)`

`return` `-10;`

`}`

`}`

`// Check columns for X or O gain.`

`Do``(kol = 0; kol < 3; kol++)`

`{`

`I` `(b[kol] == b[kol] &&`

`b[kol] == b[kol])`

`{`

`I` `(b[col] == player)`

`return` `+10;`

`Inside` `I` `(b[col] == opponent)`

`return` `-10;`

`}`

`}`

`// Check diagonals for X or O win.`

`I` `(b == b && b == b)`

`{`

`I` `(b == player)`

`return` `+10;`

`Inside` `I` `(b == opponent)`

`return` `-10;`

`}`

`I` `(b == b &&`

`b == b)`

`{`

`I` `(b == player)`

`return` `+10;`

`Inside` `I` `(b == opponent)`

`return` `-10;`

`}`

`// Else if none of them exist`

`// won and returned 0`

`return` `0;`

`}`

`// This is the minimax function. This`

`// consider all possible paths`

`// The game can go and come back`

`// board value`

`function` `minimax(plate, depth, isMax)`

`{`

`let result = stake (array);`

`// If Maximizer won the game`

`// returns his/her estimated score`

`I` `(Score == 10)`

`return` `to achieve;`

`// If Minimizer won the game`

`// returns his/her estimated score`

`I` `(Score == -10)`

`return` `to achieve;`

`// if there are no more trains i`

`// No winner, then it's a tie`

`I` `(isMovesLeft(board) ==``improperly``)`

`return` `0;`

`// If this move is a maximizer`

`I` `(is max.)`

`{`

`let best = -1000;`

`// loop through all cells`

`Do``(six i = 0; i < 3; i++)`

`{`

`Do``(six j = 0; j < 3; j++)`

`{`

`// Check if the cell is empty`

`I` `(table[i][j]=='_``')`

`{`

`// Take a step`

`board[i][j] = player;`

`// call minimax recursively`

`// and choose the largest value`

`best = Math.max(best, minimax(array,`

`dubina + 1, !isMax));`

`// Undo move`

`table[i][j] = '``_``';`

`}`

`}`

`}`

`return the best;`

`}`

`// If this minimizer``with the movement`

`Inside`

`{`

`be the best = 1000;`

`// loop through all cells`

`Do``(six i = 0; i < 3; i++)`

`{`

`Do``(six j = 0; j < 3; j++)`

`{`

`// Check if the cell is empty`

`I` `(table[i][j] ==``„_”``)`

`{`

`// Take a step`

`array[i][j] = opponent;`

`// call minimax recursively i`

`// Choose the minimum value`

`best = Math.min(best, minimax(array,`

`dubina + 1, !isMax));`

`// Undo move`

`Brett[i][j] =``„_”``;`

`}`

`}`

`}`

`return` `best;`

`}`

`}`

`// This will give the best possible result`

`// move instead of player`

`function` `findBestMove (table)`

`{`

`let bestVal = -1000;`

`let the best move =``new` `move();`

`best move.row = -1;`

`best move.col = -1;`

`// Go through all cells, evaluate`

`// The Minimax function is empty for everything`

`// stations. And return the cell`

`// with the optimal value.`

`Do``(six i = 0; i < 3; i++)`

`{`

`Do``(six j = 0; j < 3; j++)`

`{`

`// Check if the cell is empty`

`I` `(table[i][j] ==``„_”``)`

`{`

`// Take a step`

`board[i][j] = player;`

`// Calculate the estimator`

`// for this move.`

`let moveVal = minimax(array, 0,``improperly``);`

`// Undo move`

`Brett[i][j] =``„_”``;`

`// If the value of the current move`

`// is therefore more than the best value`

`// The best update`

`I` `(moveVal > bestVal)`

`{`

`best move.row = i;`

`best move.col = j;`

`bestvalue = transfervalue;`

`}`

`}`

`}`

`}`

`document.write(``"Best Moving Value"` `+`

`"Is:"``, the best Val +``""``);`

`return` `best move;`

`}`

`// At the driver's`

`let on board = [ [``'X'``,``„Ö”``,``'X'` `],`

`[``„Ö”``,``„Ö”``,``'X'` `],`

`[``„_”``,``„_”``,``„_”` `] ];`

`let best move = find best move (array);`

`document.write(``"The optimal move is:"``);`

`document.write(``"THE LINE: "` `+ bestMove.row +`

`"PASS:"``+ bestMove.col +``""``);`

`// This code was created by rag2127`

Exit:

`The value of the best move is: 10 The optimal move is: ROW: 2 COL: 2`

### Explanation: This image shows all the possible paths the game can take based on the state of the motherboard. It is often mentionedgame tree.

The three possible scenarios in the example above are:

• Go left: When X plays [2.0]. Then O[2,1] plays and wins the game. The value of this move is -10
• central train: When X plays [2,1]. O then plays [2,2], resulting in a draw. The value of this move is 0
• The right move: When X plays [2,2]. Then he will win the match. The value of this move is +10;

Remember, while X has the potential to win by playing middle move, O will never allow it, choosing a draw instead.
Therefore, the best choice for X is to play [2,2], which guarantees him a win.
We encourage our readers to try different inputs and understand why the AI ​​chose this move. Minimax can confuse developers because it thinks several steps ahead, and sometimes it's very difficult to get it right. Note that this implementation of the minimax algorithm can be applied to any two-player board game with minor changes to the board structure and how moves are repeated. Also, sometimes minimax cannot calculate every possible game state for complex games like chess. So we only count to a certain depth and use the estimator to calculate the value of the board.
Stay tuned for an article next week where we discuss thisAlpha Beta cutThis can drastically reduce the time it takes for the minimax to traverse the game tree.

This article was written byAkshay L Aradhya. If you like GeeksforGeeks and want to contribute, you can also contribute to the articlewrite.geeksforgeeks.orgor send your article to review-team@geeksforgeeks.org. See how your article looks on the GeeksforGeeks homepage and help other geeks.
Write a comment if you find something wrong or want to share more information on the topic discussed above.

My personal notes Arrow_drop_up

Last actualisation: February 20, 2023

As an article

save article

Top Articles
Latest Posts
Article information

Author: The Hon. Margery Christiansen

Last Updated: 05/04/2023

Views: 6205

Rating: 5 / 5 (70 voted)

Author information

Name: The Hon. Margery Christiansen

Birthday: 2000-07-07

Address: 5050 Breitenberg Knoll, New Robert, MI 45409

Phone: +2556892639372

Job: Investor Mining Engineer

Hobby: Sketching, Cosplaying, Glassblowing, Genealogy, Crocheting, Archery, Skateboarding

Introduction: My name is The Hon. Margery Christiansen, I am a bright, adorable, precious, inexpensive, gorgeous, comfortable, happy person who loves writing and wants to share my knowledge and understanding with you.