Tic Tac Toe: Understanding The Minimax Algorithm
If the game is over, return the score from X's perspective.
Otherwise get a list of new game states for every possible move
Create a scores list
For each of these states add the minimax result of that state to the scores list
If it's X's turn, return the maximum score from the scores list
If it's O's turn, return the minimum score from the scores list
You'll notice that this algorithm is recursive, it flips back and forth between the players until a final score is found.
Fighting the Good Fight: Depth
The key improvement to this algorithm, such that, no matter the board arrangement, the perfect player will play perfectly unto its demise, is to take the "depth" or number of turns till the end of the game into account. Basically the perfect player should play perfectly, but prolong the game as much as possible.
In order to achieve this we will subtract the depth, that is the number of turns, or recursions, from the end game score, the more turns the lower the score, the fewer turns the higher the score.
https://github.com/jasonrobertfox/tictactoe
1.2 Simplest Strategy – Heuristic Preferences via Table Lookup
Minimax with Alpha-beta Pruning
Alpha-beta pruning seeks to reduce the number of nodes that needs to be evaluated in the search tree by the minimax algorithm
http://www.codebytes.in/2014/08/minimax-algorithm-tic-tac-toe-ai-in.html
http://www.coderslexicon.com/a-beginner-tic-tac-toe-class-for-java/
https://sites.google.com/site/arjunwebworld/Home/programming/tic-tac-toe-game
Always occupy center.
Check if you can win.
Check if you need to block.
Always occupy middle space.
Occupy any free space.
http://algojava.blogspot.com/2012/05/tic-tac-toe-game-swingjava.html
Read full article from Tic Tac Toe: Understanding The Minimax Algorithm
If the game is over, return the score from X's perspective.
Otherwise get a list of new game states for every possible move
Create a scores list
For each of these states add the minimax result of that state to the scores list
If it's X's turn, return the maximum score from the scores list
If it's O's turn, return the minimum score from the scores list
You'll notice that this algorithm is recursive, it flips back and forth between the players until a final score is found.
Fighting the Good Fight: Depth
The key improvement to this algorithm, such that, no matter the board arrangement, the perfect player will play perfectly unto its demise, is to take the "depth" or number of turns till the end of the game into account. Basically the perfect player should play perfectly, but prolong the game as much as possible.
In order to achieve this we will subtract the depth, that is the number of turns, or recursions, from the end game score, the more turns the lower the score, the fewer turns the higher the score.
https://github.com/jasonrobertfox/tictactoe
def score(game, depth)
if game.win?(@player)
return 10 - depth
elsif game.win?(@opponent)
return depth - 10
else
return 0
end
end
https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaGame_TicTacToe_AI.html1.2 Simplest Strategy – Heuristic Preferences via Table Lookup
Minimax with Alpha-beta Pruning
Alpha-beta pruning seeks to reduce the number of nodes that needs to be evaluated in the search tree by the minimax algorithm
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 }
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.callMinimax(0, 1); for (PointsAndScores pas : b.rootsChildrenScores) { System.out.println("Point: " + pas.point + " Score: " + pas.score); } b.placeAMove(b.returnBestMove(), 1); b.displayBoard(); }
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); }http://www.flyingmachinestudios.com/programming/minimax/
http://www.coderslexicon.com/a-beginner-tic-tac-toe-class-for-java/
https://sites.google.com/site/arjunwebworld/Home/programming/tic-tac-toe-game
Always occupy center.
Check if you can win.
Check if you need to block.
Always occupy middle space.
Occupy any free space.
http://algojava.blogspot.com/2012/05/tic-tac-toe-game-swingjava.html
Read full article from Tic Tac Toe: Understanding The Minimax Algorithm