File size: 2,601 Bytes
4b1abb0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import gradio as gr

# --- Game Logic ---
def check_winner(board):
    wins = [
        [0, 1, 2], [3, 4, 5], [6, 7, 8],  # rows
        [0, 3, 6], [1, 4, 7], [2, 5, 8],  # cols
        [0, 4, 8], [2, 4, 6]              # diagonals
    ]
    for i, j, k in wins:
        if board[i] == board[j] == board[k] and board[i] != "":
            return board[i]
    if "" not in board:
        return "Draw"
    return None

def minimax(board, is_maximizing):
    winner = check_winner(board)
    if winner == "O": return 1
    if winner == "X": return -1
    if winner == "Draw": return 0

    if is_maximizing:
        best = -float("inf")
        for i in range(9):
            if board[i] == "":
                board[i] = "O"
                score = minimax(board, False)
                board[i] = ""
                best = max(best, score)
        return best
    else:
        best = float("inf")
        for i in range(9):
            if board[i] == "":
                board[i] = "X"
                score = minimax(board, True)
                board[i] = ""
                best = min(best, score)
        return best

def ai_move(board):
    best_score = -float("inf")
    move = None
    for i in range(9):
        if board[i] == "":
            board[i] = "O"
            score = minimax(board, False)
            board[i] = ""
            if score > best_score:
                best_score = score
                move = i
    return move

def play_game(board, move):
    if board[move] != "":
        return board, "Invalid move!"
    board[move] = "X"
    winner = check_winner(board)
    if winner:
        return board, f"Winner: {winner}"

    ai = ai_move(board)
    if ai is not None:
        board[ai] = "O"
    winner = check_winner(board)
    if winner:
        return board, f"Winner: {winner}"
    return board, "Your turn"

def reset_game():
    return [""] * 9, "Game reset!"

# --- Gradio Interface ---
with gr.Blocks() as demo:
    gr.Markdown("## Smart Tic-Tac-Toe vs AI")
    board_state = gr.State([""] * 9)
    status = gr.Label(value="Your turn")
    buttons = []
    with gr.Row():
        for i in range(3):
            with gr.Column():
                for j in range(3):
                    idx = i*3 + j
                    btn = gr.Button("")
                    buttons.append(btn)

    reset_btn = gr.Button("Reset Game")

    for idx, btn in enumerate(buttons):
        btn.click(fn=play_game, inputs=[board_state, gr.Number(value=idx)], outputs=[board_state, status])

    reset_btn.click(fn=reset_game, inputs=None, outputs=[board_state, status])

demo.launch()