🎮 Tic-Tac-Toe with Minimax AI (Fully Explained)

This notebook explains Tic-Tac-Toe with a Minimax-based AI step by step.

Concepts Covered:

  • Board representation using list
  • Printing formatted grid
  • Winner checking logic
  • Draw condition
  • Minimax algorithm (recursive game tree search)
  • AI move selection
  • Full game loop

Board Index Layout:

0 | 1 | 2 ---+---+--- 3 | 4 | 5 ---+---+--- 6 | 7 | 8

Human = X
AI = O

In [1]:
"""
TIC-TAC-TOE WITH MINIMAX AI
Human = X
AI = O
"""

import math

# Create board
board = [" " for _ in range(9)]
In [2]:
def print_board():
    """Prints the board in 3x3 format."""
    print()
    for i in range(3):
        print(" | ".join(board[i*3:(i+1)*3]))
        if i < 2:
            print("--+---+--")
    print()
In [3]:
def check_winner(player):
    """Returns True if player wins."""
    win_positions = [
        [0,1,2], [3,4,5], [6,7,8],
        [0,3,6], [1,4,7], [2,5,8],
        [0,4,8], [2,4,6]
    ]
    for pos in win_positions:
        if all(board[i] == player for i in pos):
            return True
    return False
In [4]:
def is_draw():
    """Returns True if board is full."""
    return " " not in board
In [5]:
def minimax(is_maximizing):
    """
    Minimax recursive algorithm.
    Returns:
        1  -> AI wins
       -1  -> Human wins
        0  -> Draw
    """
    if check_winner("O"):
        return 1
    if check_winner("X"):
        return -1
    if is_draw():
        return 0

    if is_maximizing:
        best_score = -math.inf
        for i in range(9):
            if board[i] == " ":
                board[i] = "O"
                score = minimax(False)
                board[i] = " "
                best_score = max(score, best_score)
        return best_score
    else:
        best_score = math.inf
        for i in range(9):
            if board[i] == " ":
                board[i] = "X"
                score = minimax(True)
                board[i] = " "
                best_score = min(score, best_score)
        return best_score
In [6]:
def ai_move():
    """Chooses best move for AI using minimax."""
    best_score = -math.inf
    move = 0

    for i in range(9):
        if board[i] == " ":
            board[i] = "O"
            score = minimax(False)
            board[i] = " "
            if score > best_score:
                best_score = score
                move = i

    board[move] = "O"
In [7]:
# Game Loop
print("You are X, AI is O")
print_board()

while True:
    try:
        position = int(input("Enter position (0-8): "))
        if board[position] != " ":
            print("Position already taken!")
            continue
        board[position] = "X"
    except:
        print("Invalid input!")
        continue

    print_board()

    if check_winner("X"):
        print("You Win!")
        break
    if is_draw():
        print("It's a Draw!")
        break

    print("AI is making a move...")
    ai_move()
    print_board()

    if check_winner("O"):
        print("AI Wins!")
        break
    if is_draw():
        print("It's a Draw!")
        break
You are X, AI is O

  |   |  
--+---+--
  |   |  
--+---+--
  |   |  

Enter position (0-8): 0

X |   |  
--+---+--
  |   |  
--+---+--
  |   |  

AI is making a move...

X |   |  
--+---+--
  | O |  
--+---+--
  |   |  

Enter position (0-8): 8

X |   |  
--+---+--
  | O |  
--+---+--
  |   | X

AI is making a move...

X | O |  
--+---+--
  | O |  
--+---+--
  |   | X

Enter position (0-8): 7

X | O |  
--+---+--
  | O |  
--+---+--
  | X | X

AI is making a move...

X | O |  
--+---+--
  | O |  
--+---+--
O | X | X

Enter position (0-8): 2

X | O | X
--+---+--
  | O |  
--+---+--
O | X | X

AI is making a move...

X | O | X
--+---+--
  | O | O
--+---+--
O | X | X

Enter position (0-8): 3

X | O | X
--+---+--
X | O | O
--+---+--
O | X | X

It's a Draw!