OneCompiler

Tictactoe MinMax

106

import random

PLAYER_X = "X"
PLAYER_O = "O"
EMPTY = " "

def print_board(board):
for row in range(3):
print(" | ".join(board[row]))
if row < 2:
print("---------")

def check_win(board, player):
for i in range(3):
if all(board[i][j] == player for j in range(3)) or all(board[j][i] == player for j in range(3)):
return True
if all(board[i][i] == player for i in range(3)) or all(board[i][2-i] == player for i in range(3)):
return True
return False

def is_board_full(board):
return all(board[i][j] != EMPTY for i in range(3) for j in range(3))

def available_moves(board):
return [(i, j) for i in range(3) for j in range(3) if board[i][j] == EMPTY]

def minimax(board, depth, is_maximizing, alpha, beta):
if check_win(board, PLAYER_X):
return -1
if check_win(board, PLAYER_O):
return 1
if is_board_full(board):
return 0

if is_maximizing:
    max_eval = float('-inf')
    for (i, j) in available_moves(board):
        board[i][j] = PLAYER_O
        eval = minimax(board, depth + 1, False, alpha, beta)
        board[i][j] = EMPTY
        max_eval = max(max_eval, eval)
        alpha = max(alpha, eval)
        if beta <= alpha:
            break
    return max_eval
else:
    min_eval = float('inf')
    for (i, j) in available_moves(board):
        board[i][j] = PLAYER_X
        eval = minimax(board, depth + 1, True, alpha, beta)
        board[i][j] = EMPTY
        min_eval = min(min_eval, eval)
        beta = min(beta, eval)
        if beta <= alpha:
            break
    return min_eval

def best_move(board):
max_eval = float('-inf')
move = None
for (i, j) in available_moves(board):
board[i][j] = PLAYER_O
eval = minimax(board, 0, False, float('-inf'), float('inf'))
board[i][j] = EMPTY
if eval > max_eval:
max_eval = eval
move = (i, j)
return move

def play_game():
board = [[EMPTY for _ in range(3)] for _ in range(3)]
print("Welcome to Tic Tac Toe!")
print("Player X will go first.")

current_player = PLAYER_X

while True:
    print_board(board)

    if current_player == PLAYER_X:
        print("Player X's turn.")
        try:
            row, col = map(int, input("Enter row and column (0-2) separated by space: ").split())
            if 0 <= row <= 2 and 0 <= col <= 2:
                if board[row][col] == EMPTY:
                    board[row][col] = PLAYER_X
                    if check_win(board, PLAYER_X):
                        print_board(board)
                        print("Player X wins!")
                        break
                    current_player = PLAYER_O
                else:
                    print("Invalid move, cell already occupied. Try again.")
            else:
                print("Invalid input, row and column must be between 0 and 2.")
        except ValueError:
            print("Invalid input, please enter numbers separated by space.")
    else:
        print("Player O's turn (Computer).")
        row, col = best_move(board)
        board[row][col] = PLAYER_O
        if check_win(board, PLAYER_O):
            print_board(board)
            print("Player O (Computer) wins!")
            break
        current_player = PLAYER_X

    if is_board_full(board):
        print_board(board)
        print("It's a draw!")
        break

play_game()