In: Computer Science
Using Java please implement a 4x4 Tic-Tac-Toe with Minimax with alpha-beta pruning. Please comment code heavily so I can follow along and understand the steps. Also, inlcude a screenshot of the final output. Do not include code for GUI, a GUI is not needed. Thank you
The recursive algorithm for "minimax with alpha-beta pruning" is as follows:
minimax(level, player, alpha, beta) // player may be "computer" or "opponent" if (gameover || level == 0) return score children = all valid moves for this "player" if (player is computer, i.e., max's turn) // Find max and store in alpha for each child score = minimax(level - 1, opponent, alpha, beta) if (score > alpha) alpha = score if (alpha >= beta) break; // beta cut-off return alpha else (player is opponent, i.e., min's turn) // Find min and store in beta for each child score = minimax(level - 1, computer, alpha, beta) if (score < beta) beta = score if (alpha >= beta) break; // alpha cut-off return beta // Initial call with alpha=-inf and beta=inf minimax(2, computer, -inf, +inf)
The relevant changes (over the
AIPlayerMinimax.java
) are:
/** Get next best move for computer. Return int[2] of {row, col} */ @Override int[] move() { int[] result = minimax(2, mySeed, Integer.MIN_VALUE, Integer.MAX_VALUE); // depth, max-turn, alpha, beta return new int[] {result[1], result[2]}; // row, col } /** Minimax (recursive) at level of depth for maximizing or minimizing player with alpha-beta cut-off. Return int[3] of {score, row, col} */ private int[] minimax(int depth, Seed player, int alpha, int beta) { // Generate possible next moves in a list of int[2] of {row, col}. List<int[]> nextMoves = generateMoves(); // mySeed is maximizing; while oppSeed is minimizing int score; int bestRow = -1; int bestCol = -1; if (nextMoves.isEmpty() || depth == 0) { // Gameover or depth reached, evaluate score score = evaluate(); return new int[] {score, bestRow, bestCol}; } else { for (int[] move : nextMoves) { // try this move for the current "player" cells[move[0]][move[1]].content = player; if (player == mySeed) { // mySeed (computer) is maximizing player score = minimax(depth - 1, oppSeed, alpha, beta)[0]; if (score > alpha) { alpha = score; bestRow = move[0]; bestCol = move[1]; } } else { // oppSeed is minimizing player score = minimax(depth - 1, mySeed, alpha, beta)[0]; if (score < beta) { beta = score; bestRow = move[0]; bestCol = move[1]; } } // undo move cells[move[0]][move[1]].content = Seed.EMPTY; // cut-off if (alpha >= beta) break; } return new int[] {(player == mySeed) ? alpha : beta, bestRow, bestCol}; } }