File size: 3,915 Bytes
f29d297
 
 
 
 
 
 
87b6a3d
2430418
87b6a3d
f29d297
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71ea2dc
 
 
 
 
 
 
f29d297
 
 
87b6a3d
 
f29d297
 
 
 
 
71ea2dc
87b6a3d
f29d297
 
 
71ea2dc
87b6a3d
f29d297
 
 
87b6a3d
 
 
 
f29d297
 
 
 
 
 
 
 
 
 
87b6a3d
f29d297
 
 
 
87b6a3d
f29d297
 
 
 
 
 
71ea2dc
87b6a3d
f29d297
 
 
 
 
 
 
87b6a3d
f29d297
 
 
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

# Initialize the game board and state
def initialize_game():
    board = [["" for _ in range(3)] for _ in range(3)]
    current_player = "X"
    status = "Player 1's turn (X)"
    # Create 9 buttons for the grid
    buttons = [gr.Button(value="", elem_classes=["cell-btn"], interactive=True) for _ in range(9)]
    return board, current_player, status, *buttons

# Check for a winner
def check_winner(board):
    for i in range(3):
        if board[i][0] == board[i][1] == board[i][2] and board[i][0] != "":
            return board[i][0]
        if board[0][i] == board[1][i] == board[2][i] and board[0][i] != "":
            return board[0][i]
    if board[0][0] == board[1][1] == board[2][2] and board[0][0] != "":
        return board[0][0]
    if board[0][2] == board[1][1] == board[2][0] and board[0][2] != "":
        return board[0][2]
    return None

# Check for a draw
def check_draw(board):
    return all(cell != "" for row in board for cell in row)

# Handle a move
def handle_move(board, current_player, button_idx, game_status):
    # If the game is already over (winner or draw), don't allow further moves
    if "wins" in game_status or "draw" in game_status:
        status = game_status  # No change to status if the game is over
        buttons = [gr.Button(value=board[i//3][i%3], elem_classes=["cell-btn"], interactive=False) for i in range(9)]
        return board, current_player, status, *buttons

    row, col = divmod(button_idx, 3)
    if board[row][col] != "":
        status = f"Invalid move! Player {1 if current_player == 'X' else 2}'s turn ({current_player})"
        buttons = [gr.Button(value=board[i//3][i%3], elem_classes=["cell-btn"]) for i in range(9)]
        return board, current_player, status, *buttons

    board[row][col] = current_player
    winner = check_winner(board)
    if winner:
        status = f"Player {1 if winner == 'X' else 2} ({winner}) wins! ๐ŸŽ‰"
        buttons = [gr.Button(value=board[i//3][i%3], elem_classes=["cell-btn"], interactive=False) for i in range(9)]
        return board, current_player, status, *buttons

    if check_draw(board):
        status = "It's a draw! ๐Ÿค"
        buttons = [gr.Button(value=board[i//3][i%3], elem_classes=["cell-btn"], interactive=False) for i in range(9)]
        return board, current_player, status, *buttons

    current_player = "O" if current_player == "X" else "X"
    status = f"Player {1 if current_player == 'X' else 2}'s turn ({current_player})"
    
    # Update the buttons to reflect the new board state
    buttons = [gr.Button(value=board[i//3][i%3], elem_classes=["cell-btn"]) for i in range(9)]
    return board, current_player, status, *buttons

# Build the Gradio UI
with gr.Blocks(css=".cell-btn {height: 100px; width: 100px; font-size: 2em; text-align: center;}") as tic_tac_toe:
    gr.Markdown("## Tic-Tac-Toe ๐ŸŽฎ")

    # Initialize states
    board_state = gr.State([["" for _ in range(3)] for _ in range(3)])
    current_player = gr.State("X")
    game_status = gr.Textbox(value="Player 1's turn (X)", label="Game Status", interactive=False)

    # Create grid buttons
    buttons = []
    for i in range(3):
        with gr.Row():
            for j in range(3):
                btn = gr.Button(value="", elem_classes=["cell-btn"])
                buttons.append(btn)

    # Update buttons dynamically on click
    for idx, btn in enumerate(buttons):
        btn.click(
            handle_move,
            inputs=[board_state, current_player, gr.Number(idx, visible=False), game_status],
            outputs=[board_state, current_player, game_status, *buttons],  # Return all outputs
        )

    # Reset game button
    reset_button = gr.Button("Reset Game")
    reset_button.click(
        initialize_game,
        inputs=[],
        outputs=[board_state, current_player, game_status, *buttons],  # Include buttons in reset
    )

tic_tac_toe.launch()