Implement the Minimax Algorithm for Tic-Tac-Toe. The algorithm explores the full game tree to find the optimal move for the current player, assuming both players play perfectly.
from typing import List, Optional, Tuple
def minimax_tictactoe(board: List[List[str]], is_maximizing: bool) -> Tuple[int, Optional[Tuple[int, int]]]:
def check_winner(b):
for i in range(3):
if b[i][0] == b[i][1] == b[i][2] != '':
return b[i][0]
if b[0][i] == b[1][i] == b[2][i] != '':
return b[0][i]
if b[0][0] == b[1][1] == b[2][2] != '':
return b[0][0]
if b[0][2] == b[1][1] == b[2][0] != '':
return b[0][2]
return None
def is_full(b):
return all(b[i][j] != '' for i in range(3) for j in range(3))
winner = check_winner(board)
if winner == 'X':
return 1, None
if winner == 'O':
return -1, None
if is_full(board):
return 0, None
best_move = None
if is_maximizing:
best_score = -float('inf')
for i in range(3):
for j in range(3):
if board[i][j] == '':
board[i][j] = 'X'
score, _ = minimax_tictactoe(board, False)
board[i][j] = ''
if score > best_score:
best_score = score
best_move = (i, j)
return best_score, best_move
else:
best_score = float('inf')
for i in range(3):
for j in range(3):
if board[i][j] == '':
board[i][j] = 'O'
score, _ = minimax_tictactoe(board, True)
board[i][j] = ''
if score < best_score:
best_score = score
best_move = (i, j)
return best_score, best_move