rui3000 commited on
Commit
cad0de9
ยท
verified ยท
1 Parent(s): 5c22548

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -306
app.py DELETED
@@ -1,306 +0,0 @@
1
- # RPS_SIMPLE_DEMO/app.py
2
- import gradio as gr
3
- import uuid
4
- import httpx
5
- import os
6
- #from RockPaperScissor.repositories import CombinedStorage
7
-
8
- # FastAPI imports
9
- from fastapi import FastAPI, Request, Body
10
- from fastapi.responses import RedirectResponse
11
- from RockPaperScissor.routes import game_router
12
- from RockPaperScissor.services.service_instance import game_service
13
- from RockPaperScissor.services.LLM_service import LLMService
14
-
15
- # --- Game Constants and Types ---
16
- from enum import Enum
17
-
18
- class Move(Enum):
19
- ROCK = "rock"
20
- PAPER = "paper"
21
- SCISSORS = "scissors"
22
-
23
- class GameResult(Enum):
24
- PLAYER_WIN = "player_win"
25
- AI_WIN = "ai_win"
26
- DRAW = "draw"
27
-
28
- # --- Gradio Interface ---
29
- class RockPaperScissorsUI:
30
- def __init__(self, game_service):
31
- self.game_service = game_service
32
- self.session_id = None # Will be set from State
33
- self.ai_models = list(self.game_service.ai_models.keys())
34
- self.ai_descriptions = {
35
- "random": "Random AI: Makes completely random moves.",
36
- "adaptive_markov": "Adaptive Markov AI: Uses entropy-weighted Markov and frequency models to predict your next move."
37
- }
38
- self.last_move = None
39
-
40
- async def reset_session(self, session_id: str):
41
- # Use environment variable for base URL, fallback to localhost
42
- base_url = os.getenv("HF_SPACE_URL", "http://localhost:7860")
43
- async with httpx.AsyncClient() as client:
44
- response = await client.post(
45
- f"{base_url}/api/game/end",
46
- json={"session_id": session_id}
47
- )
48
- print("[DEBUG] /api/game/end response:", response.text)
49
- # Optionally, also clear the session in-memory (if needed)
50
- await self.game_service.clear_session(session_id)
51
- return {"status": "ok"}
52
-
53
- def create_interface(self):
54
- with gr.Blocks(theme=gr.themes.Soft(), title="Rock Paper Scissors ๐ŸŽฎ") as demo:
55
- gr.Markdown("# ๐Ÿชจ๐Ÿ“„โœ‚๏ธ Rock Paper Scissors")
56
-
57
- with gr.Row():
58
- with gr.Column(scale=1):
59
- gr.Markdown("### ๐ŸŽฎ Game Setup")
60
- ai_dropdown = gr.Dropdown(
61
- choices=self.ai_models,
62
- value=self.ai_models[0],
63
- label="Select AI Opponent"
64
- )
65
- ai_description = gr.Markdown(self.ai_descriptions[self.ai_models[0]])
66
-
67
- with gr.Row():
68
- rock_btn = gr.Button("๐Ÿชจ Rock", variant="secondary", elem_classes=["move-btn"])
69
- paper_btn = gr.Button("๐Ÿ“„ Paper", variant="secondary", elem_classes=["move-btn"])
70
- scissors_btn = gr.Button("โœ‚๏ธ Scissors", variant="secondary", elem_classes=["move-btn"])
71
- # Add End Game button
72
- end_btn = gr.Button("End Game", variant="stop", elem_id="end-game-btn")
73
- # Add Help button
74
- help_btn = gr.Button("๐Ÿ’ก Get Help", variant="primary", elem_id="help-btn")
75
- # Add a dedicated box for the help answer, initially empty
76
- help_answer_box = gr.Markdown("", visible=True)
77
-
78
- with gr.Column(scale=2):
79
- gr.Markdown("### ๐Ÿ“Š Game Statistics")
80
- stats_display = gr.Markdown()
81
- result_display = gr.Markdown("Make your move!")
82
- end_result_display = gr.Markdown(visible=False)
83
- status_display = gr.Markdown(visible=True)
84
-
85
- ai_dropdown.change(
86
- fn=self.update_ai_description,
87
- inputs=[ai_dropdown],
88
- outputs=[ai_description]
89
- )
90
-
91
- # Use a Gradio State to store the session ID
92
- move_state = gr.State("")
93
- session_id_state = gr.State("")
94
-
95
- async def play_rock(ai_type, session_id):
96
- if not session_id:
97
- session_id = f"session_{uuid.uuid4()}"
98
- self.session_id = session_id
99
- stats, result = await self.play_round(ai_type, "rock")
100
- return stats, result, session_id
101
- async def play_paper(ai_type, session_id):
102
- if not session_id:
103
- session_id = f"session_{uuid.uuid4()}"
104
- self.session_id = session_id
105
- stats, result = await self.play_round(ai_type, "paper")
106
- return stats, result, session_id
107
- async def play_scissors(ai_type, session_id):
108
- if not session_id:
109
- session_id = f"session_{uuid.uuid4()}"
110
- self.session_id = session_id
111
- stats, result = await self.play_round(ai_type, "scissors")
112
- return stats, result, session_id
113
-
114
- # Add a hidden HTML block with JS to auto-save on tab close
115
- gr.HTML("""
116
- <script>
117
- // Store session ID in localStorage whenever it changes
118
- window.setRpsSessionId = function(session_id) {
119
- if (session_id) {
120
- localStorage.setItem('rps_session_id', session_id);
121
- }
122
- };
123
- // On tab close, send session end to backend
124
- window.onbeforeunload = function() {
125
- let session_id = localStorage.getItem('rps_session_id');
126
- if (session_id) {
127
- navigator.sendBeacon("/game/end", JSON.stringify({session_id: session_id}));
128
- }
129
- };
130
- </script>
131
- """)
132
-
133
- # Inject JS to click End Game button on tab close
134
- gr.HTML("""
135
- <script>
136
- window.onbeforeunload = function() {
137
- var btn = document.getElementById('end-game-btn');
138
- if (btn) {
139
- btn.click();
140
- }
141
- };
142
- </script>
143
- """)
144
-
145
- # After each move, update localStorage with the session ID
146
- def update_session_id_js(session_id):
147
- return f"window.setRpsSessionId('{session_id}');"
148
-
149
- rock_btn.click(
150
- fn=play_rock,
151
- inputs=[ai_dropdown, session_id_state],
152
- outputs=[stats_display, result_display, session_id_state],
153
- js=update_session_id_js
154
- )
155
- paper_btn.click(
156
- fn=play_paper,
157
- inputs=[ai_dropdown, session_id_state],
158
- outputs=[stats_display, result_display, session_id_state],
159
- js=update_session_id_js
160
- )
161
- scissors_btn.click(
162
- fn=play_scissors,
163
- inputs=[ai_dropdown, session_id_state],
164
- outputs=[stats_display, result_display, session_id_state],
165
- js=update_session_id_js
166
- )
167
-
168
- # End Game button logic
169
- async def end_game(session_id):
170
- if not session_id:
171
- return "No session to end. Play a round first!"
172
- result = await self.reset_session(session_id)
173
- return f"End Game: {result['status']} - {result.get('message', '')}"
174
-
175
- end_btn.click(
176
- fn=end_game,
177
- inputs=[session_id_state],
178
- outputs=[end_result_display],
179
- )
180
- end_result_display.visible = True
181
-
182
- # Help button logic
183
- async def get_help(session_id):
184
- # Show loading message while waiting
185
- loading_message = "Generating answer, please wait..."
186
- try:
187
- base_url = os.getenv("HF_SPACE_URL", "http://localhost:7860")
188
- async with httpx.AsyncClient() as client:
189
- response = await client.post(f"{base_url}/api/help", json={"session_id": session_id})
190
- if response.status_code == 200:
191
- data = response.json()
192
- suggestion = data.get("suggestion", "No suggestion available.")
193
- else:
194
- suggestion = "Sorry, I'm having trouble getting help right now."
195
- except Exception as e:
196
- suggestion = f"Error getting help: {str(e)}"
197
- return suggestion
198
-
199
- # When help button is clicked, first show loading, then update with answer
200
- def show_loading():
201
- return "Generating answer, please wait..."
202
-
203
- help_btn.click(
204
- fn=show_loading,
205
- inputs=[],
206
- outputs=[help_answer_box],
207
- queue=False
208
- )
209
- help_btn.click(
210
- fn=get_help,
211
- inputs=[session_id_state],
212
- outputs=[help_answer_box],
213
- queue=True
214
- )
215
-
216
- return demo
217
-
218
- def update_ai_description(self, ai_type: str) -> str:
219
- return self.ai_descriptions[ai_type]
220
-
221
- async def play_round(self, ai_type: str, move: str):
222
- if not self.session_id:
223
- return "Internal Error: Session ID missing in play_round.", "Error"
224
- result = await self.game_service.play_round(self.session_id, move, ai_type)
225
- stats = result["stats"]
226
- stats_text = f"""
227
- ### Game Statistics
228
- - Total Rounds: {stats['total_rounds']}
229
- - Player Wins: {stats['player_wins']} ({stats['player_win_rate']})
230
- - AI Wins: {stats['ai_wins']} ({stats['ai_win_rate']})
231
- - Draws: {stats['draws']}
232
-
233
- ### Player Move Distribution
234
- - Rock: {stats['player_moves']['rock']}
235
- - Paper: {stats['player_moves']['paper']}
236
- - Scissors: {stats['player_moves']['scissors']}
237
-
238
- ### AI Move Distribution
239
- - Rock: {stats['ai_moves']['rock']}
240
- - Paper: {stats['ai_moves']['paper']}
241
- - Scissors: {stats['ai_moves']['scissors']}
242
- """
243
- result_text = f"""
244
- ### Round Result
245
- You played: {result['player_move'].upper()}
246
- AI played: {result['ai_move'].upper()}
247
- Result: {result['result'].replace('_', ' ').title()}
248
- """
249
- return stats_text, result_text
250
-
251
- async def clear_session(self, session_id: str):
252
- await self.game_service.clear_session(session_id)
253
- return {"status": "ok"}
254
-
255
- # Create FastAPI app
256
- app = FastAPI()
257
-
258
- # Initialize LLM Service
259
- llm_service = LLMService()
260
-
261
- # Add help endpoint
262
- @app.post("/api/help")
263
- async def get_help(request: Request, body: dict = Body(...)):
264
- try:
265
- session_id = body.get("session_id")
266
- stats = None
267
- if session_id:
268
- # Try to get stats from the game service
269
- session_data = game_service.cache.get_session(session_id)
270
- if session_data:
271
- # Calculate AI move distribution
272
- ai_moves = [round['ai_move'] for round in session_data['rounds']]
273
- total_moves = len(ai_moves)
274
- if total_moves > 0:
275
- move_distribution = {
276
- "rock": int((ai_moves.count("rock") / total_moves) * 100),
277
- "paper": int((ai_moves.count("paper") / total_moves) * 100),
278
- "scissors": int((ai_moves.count("scissors") / total_moves) * 100)
279
- }
280
- stats = {"move_distribution": move_distribution}
281
- suggestion = await llm_service.generate_response("help", stats=stats)
282
- print("Help suggestion:", suggestion) # Debug print
283
- return {"suggestion": suggestion}
284
- except Exception as e:
285
- return {"error": str(e), "suggestion": "Sorry, I'm having trouble generating a suggestion right now."}
286
-
287
- # Create Gradio interface
288
- ui = RockPaperScissorsUI(game_service)
289
- demo = ui.create_interface()
290
-
291
- # Mount Gradio app
292
- app.include_router(game_router, prefix="/api/game")
293
- app = gr.mount_gradio_app(app, demo, path="/")
294
-
295
- # Initialize the app
296
- @app.on_event("startup")
297
- async def startup_event():
298
- await game_service.initialize()
299
-
300
- @app.on_event("shutdown")
301
- async def shutdown_event():
302
- await llm_service.close()
303
-
304
- if __name__ == "__main__":
305
- import uvicorn
306
- uvicorn.run("app:app", host="0.0.0.0", port=7860, reload=False)