Tic-Tac-Toe / without-ai-two-player-app.py
pratikshahp's picture
Rename without-AI-app.py to without-ai-two-player-app.py
1441cee verified
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()