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()