Tic-Tac-Toe / ui /components.py
srk-dot-ai's picture
Refactor Tic Tac Toe game by adding DeepSeek and OpenAI agents, updating README title, enhancing game logic, and implementing game statistics tracking.
ee656d3
import gradio as gr
import altair as alt
import pandas as pd
from models.registry import models
from ui.bindings import bind_events
from game.stats import get_leaderboard_data, get_total_games, get_last_10_games
model_choices = [model["name"] for model in models]
def create_leaderboard_chart():
data = get_leaderboard_data()
if not data:
return None
df = pd.DataFrame(data, columns=["Model", "Wins"])
chart = (
alt.Chart(df)
.mark_bar(color="#4c78a8")
.encode(
x=alt.X("Wins:Q", title="Total Wins"),
y=alt.Y("Model:N", sort="-x", title="Model"),
tooltip=["Model:N", "Wins:Q"],
)
.properties(title="Model Wins Leaderboard", width=400, height=200)
)
return chart
def format_total_games():
total = get_total_games()
return f"<p style='margin-bottom:10px;color:#333;'><b>Total Games: {total}</b></p>"
def format_last_games():
games = get_last_10_games()
if not games:
return "<p style='color:#666;'>No games played yet</p>"
html = "<div style='font-size:13px;'>"
for i, game in enumerate(games, 1):
html += f"<p style='margin:5px 0;padding:5px;background:#f5f5f5;border-radius:4px;color:#333;'>{i}. {game}</p>"
html += "</div>"
return html
def refresh_leaderboard():
return format_total_games(), format_last_games(), create_leaderboard_chart()
def create_ui():
with gr.Blocks(css=open("ui/styles.css").read()) as demo:
gr.Markdown("# 🎲 Tic-Tac-Toe Game")
leaderboard_btn = gr.Button("πŸ† Leaderboard", variant="secondary", size="sm")
with gr.Row(visible=False) as leaderboard_row:
with gr.Column(scale=1):
total_games_html = gr.HTML(value=format_total_games)
gr.Markdown("### πŸ… Last 10 Games")
last_games_html = gr.HTML(value=format_last_games)
with gr.Column(scale=1):
gr.Markdown("### πŸ“Š Wins Leaderboard")
leaderboard_plot = gr.Plot(value=create_leaderboard_chart)
def toggle_leaderboard(visible):
return gr.Row(visible=not visible)
with gr.Row():
with gr.Column(scale=1):
model_1_dropdown = gr.Dropdown(
choices=model_choices,
value=models[0]["name"],
label="Select Model for Player 1 (X)",
interactive=True,
)
model_1_comment = gr.Textbox(
label="Model 1 Comment",
value="Waiting for game to start...",
interactive=False,
lines=3,
)
with gr.Column(scale=2):
board_buttons = []
board_state = gr.State([None] * 9)
current_player_move = gr.State("X")
for r in range(3):
row_buttons = []
with gr.Row(elem_classes="tic-row"):
for c in range(3):
btn = gr.Button(
value=" ",
elem_classes=["tic-cell", "tic-btn"],
elem_id=f"cell-{r}-{c}",
interactive=False,
)
row_buttons.append(btn)
board_buttons.append(row_buttons)
status_text = gr.Textbox(
label="Game Status",
value="Click 'Start Game' to begin the battle!",
interactive=False,
)
start_button = gr.Button("Start Game", variant="primary")
reset_button = gr.Button("Reset Game", variant="stop")
with gr.Column(scale=1):
model_2_dropdown = gr.Dropdown(
choices=model_choices,
value=models[0]["name"],
label="Select Model for Player 2 (O)",
interactive=True,
)
model_2_comment = gr.Textbox(
label="Model 2 Comment",
value="Waiting for game to start...",
interactive=False,
lines=3,
)
leaderboard_state = gr.State(False)
leaderboard_btn.click(
fn=toggle_leaderboard, inputs=[leaderboard_state], outputs=[leaderboard_row]
).then(
fn=lambda x: not x, inputs=[leaderboard_state], outputs=[leaderboard_state]
)
bind_events(
start_button,
reset_button,
model_1_dropdown,
model_2_dropdown,
status_text,
board_state,
current_player_move,
board_buttons,
model_1_comment,
model_2_comment,
total_games_html,
last_games_html,
leaderboard_plot,
refresh_leaderboard,
)
return demo