Upload 11 files
Browse files- README.md +7 -13
- RockPaperScissor/__init__.py +0 -0
- RockPaperScissor/__pycache__/__init__.cpython-313.pyc +0 -0
- RockPaperScissor/models/__init__.py +3 -0
- RockPaperScissor/models/__pycache__/__init__.cpython-313.pyc +0 -0
- RockPaperScissor/models/__pycache__/random_ai.cpython-313.pyc +0 -0
- RockPaperScissor/models/random_ai.py +23 -0
- app.py +87 -0
- poetry.lock +0 -0
- pyproject.toml +17 -0
- requirements.txt +1 -0
README.md
CHANGED
@@ -1,14 +1,8 @@
|
|
1 |
-
|
2 |
-
title: RPS Game
|
3 |
-
emoji: π
|
4 |
-
colorFrom: yellow
|
5 |
-
colorTo: blue
|
6 |
-
sdk: gradio
|
7 |
-
sdk_version: 5.29.0
|
8 |
-
app_file: app.py
|
9 |
-
pinned: false
|
10 |
-
license: mit
|
11 |
-
short_description: a rps game against AI
|
12 |
-
---
|
13 |
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Rock Paper Scissors - Simple Demo
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
+
Play Rock Paper Scissors against a random AI!
|
4 |
+
|
5 |
+
- Click one of the buttons (Rock, Paper, Scissors) to make your move.
|
6 |
+
- The result of the round and the running score for this session will be displayed below.
|
7 |
+
|
8 |
+
This is a basic demo built with Gradio and deployed on Hugging Face Spaces.
|
RockPaperScissor/__init__.py
ADDED
File without changes
|
RockPaperScissor/__pycache__/__init__.cpython-313.pyc
ADDED
Binary file (172 Bytes). View file
|
|
RockPaperScissor/models/__init__.py
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
from .random_ai import RandomAI
|
2 |
+
|
3 |
+
__all__ = ['RandomAI'] # Expose only RandomAI for this demo
|
RockPaperScissor/models/__pycache__/__init__.cpython-313.pyc
ADDED
Binary file (251 Bytes). View file
|
|
RockPaperScissor/models/__pycache__/random_ai.cpython-313.pyc
ADDED
Binary file (1.4 kB). View file
|
|
RockPaperScissor/models/random_ai.py
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import random
|
2 |
+
from typing import Dict, Any, Tuple, Optional
|
3 |
+
|
4 |
+
class RandomAI:
|
5 |
+
"""
|
6 |
+
AI that makes random moves. Simple version for Gradio demo.
|
7 |
+
"""
|
8 |
+
def __init__(self):
|
9 |
+
self.possible_moves = ["rock", "paper", "scissors"]
|
10 |
+
|
11 |
+
def make_move(self, model_state: Optional[Dict[str, Any]] = None) -> Tuple[str, Dict[str, Any]]:
|
12 |
+
"""
|
13 |
+
Makes a random move. Ignores model_state in this simple version.
|
14 |
+
|
15 |
+
Args:
|
16 |
+
model_state (dict, optional): Not used in this strategy.
|
17 |
+
|
18 |
+
Returns:
|
19 |
+
tuple[str, dict]: A random choice and an empty state dictionary.
|
20 |
+
"""
|
21 |
+
ai_choice = random.choice(self.possible_moves)
|
22 |
+
# Return the move and an empty dictionary as the state (since it's stateless)
|
23 |
+
return ai_choice, {}
|
app.py
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from RockPaperScissor.models import RandomAI # Import the AI model
|
3 |
+
|
4 |
+
# --- Initialize AI ---
|
5 |
+
ai_model = RandomAI()
|
6 |
+
|
7 |
+
# --- Helper Function ---
|
8 |
+
def _determine_winner(player_move, ai_move):
|
9 |
+
"""Determines the winner and returns a result code and message."""
|
10 |
+
if player_move == ai_move:
|
11 |
+
return "draw", f"It's a draw! (Both chose {player_move})"
|
12 |
+
elif (player_move == "rock" and ai_move == "scissors") or \
|
13 |
+
(player_move == "paper" and ai_move == "rock") or \
|
14 |
+
(player_move == "scissors" and ai_move == "paper"):
|
15 |
+
return "player_win", f"You win! ({player_move} beats {ai_move})"
|
16 |
+
else:
|
17 |
+
return "ai_win", f"AI wins! ({ai_move} beats {player_move})"
|
18 |
+
|
19 |
+
# --- Main Gradio Function ---
|
20 |
+
def play_round(player_choice, current_stats):
|
21 |
+
"""
|
22 |
+
Handles one round of the game.
|
23 |
+
Updates stats stored in the Gradio state.
|
24 |
+
"""
|
25 |
+
print(f"Player chose: {player_choice}") # Optional: for debugging in Space logs
|
26 |
+
print(f"Current stats before round: {current_stats}")
|
27 |
+
|
28 |
+
# Get AI's move (state is ignored by RandomAI)
|
29 |
+
ai_choice, _ = ai_model.make_move()
|
30 |
+
print(f"AI chose: {ai_choice}")
|
31 |
+
|
32 |
+
# Determine winner
|
33 |
+
result_code, result_message = _determine_winner(player_choice, ai_choice)
|
34 |
+
|
35 |
+
# Update stats (modify the dictionary directly)
|
36 |
+
if result_code == "player_win":
|
37 |
+
current_stats["wins"] += 1
|
38 |
+
elif result_code == "ai_win":
|
39 |
+
current_stats["losses"] += 1
|
40 |
+
else:
|
41 |
+
current_stats["draws"] += 1
|
42 |
+
|
43 |
+
print(f"Current stats after round: {current_stats}")
|
44 |
+
|
45 |
+
# Format output strings
|
46 |
+
full_result_message = f"You chose: {player_choice}\nAI chose: {ai_choice}\n\n{result_message}"
|
47 |
+
stats_string = f"Wins: {current_stats['wins']} | Losses: {current_stats['losses']} | Draws: {current_stats['draws']}"
|
48 |
+
|
49 |
+
# Return updated components AND the modified state dictionary
|
50 |
+
return full_result_message, stats_string, current_stats
|
51 |
+
|
52 |
+
# --- Build Gradio Interface ---
|
53 |
+
with gr.Blocks(title="Rock Paper Scissors Demo") as demo:
|
54 |
+
gr.Markdown("# Rock Paper Scissors - Simple Demo")
|
55 |
+
gr.Markdown("Play against a Random AI. Choose your move:")
|
56 |
+
|
57 |
+
# State to store session scores
|
58 |
+
session_state = gr.State(value={"wins": 0, "losses": 0, "draws": 0})
|
59 |
+
|
60 |
+
with gr.Row():
|
61 |
+
rock_btn = gr.Button("πͺ¨ Rock")
|
62 |
+
paper_btn = gr.Button("π Paper")
|
63 |
+
scissors_btn = gr.Button("βοΈ Scissors")
|
64 |
+
|
65 |
+
result_output = gr.Textbox(label="Round Result", lines=3) # Use Textbox for multi-line
|
66 |
+
stats_output = gr.Label(label="Session Score")
|
67 |
+
|
68 |
+
# --- Connect Buttons to Function ---
|
69 |
+
# Use lambda functions to pass the specific choice string
|
70 |
+
rock_btn.click(
|
71 |
+
fn=play_round,
|
72 |
+
inputs=[gr.Textbox("rock", visible=False), session_state], # Pass "rock" implicitly
|
73 |
+
outputs=[result_output, stats_output, session_state] # Update outputs AND state
|
74 |
+
)
|
75 |
+
paper_btn.click(
|
76 |
+
fn=play_round,
|
77 |
+
inputs=[gr.Textbox("paper", visible=False), session_state], # Pass "paper" implicitly
|
78 |
+
outputs=[result_output, stats_output, session_state]
|
79 |
+
)
|
80 |
+
scissors_btn.click(
|
81 |
+
fn=play_round,
|
82 |
+
inputs=[gr.Textbox("scissors", visible=False), session_state], # Pass "scissors" implicitly
|
83 |
+
outputs=[result_output, stats_output, session_state]
|
84 |
+
)
|
85 |
+
|
86 |
+
# --- Launch the App ---
|
87 |
+
demo.launch() # share=True creates a public link when running locally
|
poetry.lock
ADDED
The diff for this file is too large to render.
See raw diff
|
|
pyproject.toml
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[project]
|
2 |
+
name = "rps-simple-demo"
|
3 |
+
version = "0.1.0"
|
4 |
+
description = "Simple Rock Paper Scissors Gradio demo for Hugging Face Spaces"
|
5 |
+
authors = [
|
6 |
+
{name = "Your Name",email = "[email protected]"}
|
7 |
+
]
|
8 |
+
readme = "README.md"
|
9 |
+
requires-python = "^3.10"
|
10 |
+
dependencies = [
|
11 |
+
"gradio (>=5.29.0,<6.0.0)"
|
12 |
+
]
|
13 |
+
|
14 |
+
|
15 |
+
[build-system]
|
16 |
+
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
17 |
+
build-backend = "poetry.core.masonry.api"
|
requirements.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
gradio
|