File size: 3,404 Bytes
b463791
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import gradio as gr
from RockPaperScissor.models import RandomAI # Import the AI model

# --- Initialize AI ---
ai_model = RandomAI()

# --- Helper Function ---
def _determine_winner(player_move, ai_move):
    """Determines the winner and returns a result code and message."""
    if player_move == ai_move:
        return "draw", f"It's a draw! (Both chose {player_move})"
    elif (player_move == "rock" and ai_move == "scissors") or \
         (player_move == "paper" and ai_move == "rock") or \
         (player_move == "scissors" and ai_move == "paper"):
        return "player_win", f"You win! ({player_move} beats {ai_move})"
    else:
        return "ai_win", f"AI wins! ({ai_move} beats {player_move})"

# --- Main Gradio Function ---
def play_round(player_choice, current_stats):
    """
    Handles one round of the game.
    Updates stats stored in the Gradio state.
    """
    print(f"Player chose: {player_choice}") # Optional: for debugging in Space logs
    print(f"Current stats before round: {current_stats}")

    # Get AI's move (state is ignored by RandomAI)
    ai_choice, _ = ai_model.make_move()
    print(f"AI chose: {ai_choice}")

    # Determine winner
    result_code, result_message = _determine_winner(player_choice, ai_choice)

    # Update stats (modify the dictionary directly)
    if result_code == "player_win":
        current_stats["wins"] += 1
    elif result_code == "ai_win":
        current_stats["losses"] += 1
    else:
        current_stats["draws"] += 1

    print(f"Current stats after round: {current_stats}")

    # Format output strings
    full_result_message = f"You chose: {player_choice}\nAI chose: {ai_choice}\n\n{result_message}"
    stats_string = f"Wins: {current_stats['wins']} | Losses: {current_stats['losses']} | Draws: {current_stats['draws']}"

    # Return updated components AND the modified state dictionary
    return full_result_message, stats_string, current_stats

# --- Build Gradio Interface ---
with gr.Blocks(title="Rock Paper Scissors Demo") as demo:
    gr.Markdown("# Rock Paper Scissors - Simple Demo")
    gr.Markdown("Play against a Random AI. Choose your move:")

    # State to store session scores
    session_state = gr.State(value={"wins": 0, "losses": 0, "draws": 0})

    with gr.Row():
        rock_btn = gr.Button("πŸͺ¨ Rock")
        paper_btn = gr.Button("πŸ“„ Paper")
        scissors_btn = gr.Button("βœ‚οΈ Scissors")

    result_output = gr.Textbox(label="Round Result", lines=3) # Use Textbox for multi-line
    stats_output = gr.Label(label="Session Score")

    # --- Connect Buttons to Function ---
    # Use lambda functions to pass the specific choice string
    rock_btn.click(
        fn=play_round,
        inputs=[gr.Textbox("rock", visible=False), session_state], # Pass "rock" implicitly
        outputs=[result_output, stats_output, session_state] # Update outputs AND state
    )
    paper_btn.click(
        fn=play_round,
        inputs=[gr.Textbox("paper", visible=False), session_state], # Pass "paper" implicitly
        outputs=[result_output, stats_output, session_state]
    )
    scissors_btn.click(
        fn=play_round,
        inputs=[gr.Textbox("scissors", visible=False), session_state], # Pass "scissors" implicitly
        outputs=[result_output, stats_output, session_state]
    )

# --- Launch the App ---
demo.launch() # share=True creates a public link when running locally