pabberpe commited on
Commit
0de90bb
1 Parent(s): 0042ac6

Fix Game Start bug

Browse files
Files changed (1) hide show
  1. app.py +104 -67
app.py CHANGED
@@ -26,34 +26,52 @@ class GameResults:
26
  class GameState:
27
  def __init__(self):
28
  self.lock = Lock()
29
- self.reset()
 
 
 
 
 
 
 
 
 
 
 
30
 
31
  def reset(self):
 
32
  with self.lock:
33
- self.user_score = 0
34
- self.model_score = 0
35
- self.current_round = 0
36
- self.total_rounds = NUM_ROUNDS
37
- self.game_images: List[str] = []
38
- self.is_game_active = False
39
- self.last_results: Optional[GameResults] = None
40
- self.processing_submission = False
41
 
42
- def start_new_game(self) -> bool:
 
 
 
43
  with self.lock:
44
  if self.is_game_active:
45
- return False
46
- self.reset()
47
- self.game_images = load_images()
48
- self.is_game_active = True
49
- return True
 
 
 
 
 
 
 
 
 
50
 
51
  def can_submit_guess(self) -> bool:
52
  with self.lock:
53
  return (
54
  self.is_game_active and
55
  not self.processing_submission and
56
- self.current_round < self.total_rounds
 
57
  )
58
 
59
  def start_submission(self) -> bool:
@@ -83,6 +101,18 @@ class GameState:
83
  return None
84
  return self.game_images[self.current_round]
85
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  def get_game_over_message(self) -> str:
87
  with self.lock:
88
  if self.user_score > self.model_score:
@@ -163,8 +193,6 @@ def process_image(image):
163
 
164
  return sorted_probs
165
 
166
- game_state = GameState()
167
-
168
  def load_images():
169
  real_image_folder = "real_images"
170
  fake_image_folder = "fake_images"
@@ -174,69 +202,81 @@ def load_images():
174
  random.shuffle(selected_images)
175
  return selected_images
176
 
177
- def create_score_html():
178
- with game_state.lock:
179
- results_html = ""
180
- if game_state.last_results:
181
- results_html = f"""
182
- <div style='margin-top: 1rem; padding: 1rem; background-color: #e0e0e0; border-radius: 8px; color: #333;'>
183
- <h4 style='color: #333; margin-bottom: 0.5rem;'>Last Round Results:</h4>
184
- <p style='color: #333;'>Your guess: {game_state.last_results.user_guess}</p>
185
- <p style='color: #333;'>Model's guess: {game_state.last_results.model_guess}</p>
186
- <p style='color: #333;'>Correct answer: {game_state.last_results.correct_answer}</p>
187
- </div>
188
- """
 
 
189
 
190
- current_display_round = min(game_state.current_round + 1, game_state.total_rounds)
191
-
192
- return f"""
193
- <div style='padding: 1rem; background-color: #f0f0f0; border-radius: 8px; color: #333;'>
194
- <h3 style='margin-bottom: 1rem; color: #333;'>Score Board</h3>
195
- <div style='display: flex; justify-content: space-around;'>
196
- <div>
197
- <h4 style='color: #333;'>You</h4>
198
- <p style='font-size: 1.5rem; color: #333;'>{game_state.user_score}</p>
199
- </div>
200
- <div>
201
- <h4 style='color: #333;'>AI Model</h4>
202
- <p style='font-size: 1.5rem; color: #333;'>{game_state.model_score}</p>
203
- </div>
204
  </div>
205
- <div style='margin-top: 1rem;'>
206
- <p style='color: #333;'>Round: {current_display_round}/{game_state.total_rounds}</p>
 
207
  </div>
208
- {results_html}
209
  </div>
210
- """
 
 
 
 
 
 
 
211
 
212
  def start_game():
213
- if not game_state.start_new_game():
214
- return [gr.update()] * 6
215
 
216
- current_image = Image.open(game_state.get_current_image())
 
 
217
 
218
- return (
219
- gr.update(value=current_image, visible=True),
220
- gr.update(visible=False),
221
- gr.update(visible=True, interactive=True),
222
- gr.update(visible=True, interactive=True),
223
- create_score_html(),
224
- gr.update(visible=False)
225
- )
 
 
 
 
 
 
 
226
 
227
  def submit_guess(user_guess: str):
228
- # Early return if we can't submit a guess
229
  if not game_state.can_submit_guess():
230
  return [gr.update()] * 6
231
 
232
- # Mark submission as being processed
233
  if not game_state.start_submission():
234
  return [gr.update()] * 6
235
 
236
  try:
237
- # Get current image and process it
238
  current_image_path = game_state.get_current_image()
239
  if not current_image_path:
 
240
  return [gr.update()] * 6
241
 
242
  current_image = Image.open(current_image_path)
@@ -244,11 +284,9 @@ def submit_guess(user_guess: str):
244
  model_guess = "Real" if model_prediction['Authentic'] > PROB_THRESHOLD else "Fake"
245
  correct_answer = "Real" if "real_images" in current_image_path else "Fake"
246
 
247
- # Update game state with results
248
  results = GameResults(user_guess, model_guess, correct_answer)
249
  game_state.finish_submission(results)
250
 
251
- # Check if game is over
252
  if not game_state.is_game_active:
253
  return (
254
  gr.update(value=None, visible=False),
@@ -259,7 +297,6 @@ def submit_guess(user_guess: str):
259
  gr.update(visible=True, value=game_state.get_game_over_message())
260
  )
261
 
262
- # Get next image for the next round
263
  next_image_path = game_state.get_current_image()
264
  if not next_image_path:
265
  return [gr.update()] * 6
@@ -275,9 +312,9 @@ def submit_guess(user_guess: str):
275
  gr.update(visible=False)
276
  )
277
  except Exception as e:
278
- # If any error occurs, reset the processing flag
279
  game_state.processing_submission = False
280
- raise e
281
 
282
  # Custom CSS
283
  custom_css = """
 
26
  class GameState:
27
  def __init__(self):
28
  self.lock = Lock()
29
+ self._reset()
30
+
31
+ def _reset(self):
32
+ """Internal reset method - should be called within a lock"""
33
+ self.user_score = 0
34
+ self.model_score = 0
35
+ self.current_round = 0
36
+ self.total_rounds = NUM_ROUNDS
37
+ self.game_images: List[str] = []
38
+ self.is_game_active = False
39
+ self.last_results: Optional[GameResults] = None
40
+ self.processing_submission = False
41
 
42
  def reset(self):
43
+ """Public reset method with lock protection"""
44
  with self.lock:
45
+ self._reset()
 
 
 
 
 
 
 
46
 
47
+ def start_new_game(self) -> tuple[bool, Optional[str]]:
48
+ """
49
+ Starts a new game and returns (success, first_image_path)
50
+ """
51
  with self.lock:
52
  if self.is_game_active:
53
+ return False, None
54
+
55
+ try:
56
+ self._reset()
57
+ self.game_images = load_images()
58
+ if not self.game_images:
59
+ return False, None
60
+
61
+ self.is_game_active = True
62
+ return True, self.game_images[0]
63
+ except Exception as e:
64
+ print(f"Error starting new game: {e}")
65
+ self._reset()
66
+ return False, None
67
 
68
  def can_submit_guess(self) -> bool:
69
  with self.lock:
70
  return (
71
  self.is_game_active and
72
  not self.processing_submission and
73
+ self.current_round < self.total_rounds and
74
+ len(self.game_images) > self.current_round
75
  )
76
 
77
  def start_submission(self) -> bool:
 
101
  return None
102
  return self.game_images[self.current_round]
103
 
104
+ def get_game_state(self):
105
+ """Get a snapshot of the current game state"""
106
+ with self.lock:
107
+ return {
108
+ 'is_active': self.is_game_active,
109
+ 'current_round': self.current_round,
110
+ 'total_rounds': self.total_rounds,
111
+ 'user_score': self.user_score,
112
+ 'model_score': self.model_score,
113
+ 'last_results': self.last_results
114
+ }
115
+
116
  def get_game_over_message(self) -> str:
117
  with self.lock:
118
  if self.user_score > self.model_score:
 
193
 
194
  return sorted_probs
195
 
 
 
196
  def load_images():
197
  real_image_folder = "real_images"
198
  fake_image_folder = "fake_images"
 
202
  random.shuffle(selected_images)
203
  return selected_images
204
 
205
+ def create_score_html() -> str:
206
+ game_state_snapshot = game_state.get_game_state()
207
+
208
+ results_html = ""
209
+ if game_state_snapshot['last_results']:
210
+ results = game_state_snapshot['last_results']
211
+ results_html = f"""
212
+ <div style='margin-top: 1rem; padding: 1rem; background-color: #e0e0e0; border-radius: 8px; color: #333;'>
213
+ <h4 style='color: #333; margin-bottom: 0.5rem;'>Last Round Results:</h4>
214
+ <p style='color: #333;'>Your guess: {results.user_guess}</p>
215
+ <p style='color: #333;'>Model's guess: {results.model_guess}</p>
216
+ <p style='color: #333;'>Correct answer: {results.correct_answer}</p>
217
+ </div>
218
+ """
219
 
220
+ current_display_round = min(game_state_snapshot['current_round'] + 1, game_state_snapshot['total_rounds'])
221
+
222
+ return f"""
223
+ <div style='padding: 1rem; background-color: #f0f0f0; border-radius: 8px; color: #333;'>
224
+ <h3 style='margin-bottom: 1rem; color: #333;'>Score Board</h3>
225
+ <div style='display: flex; justify-content: space-around;'>
226
+ <div>
227
+ <h4 style='color: #333;'>You</h4>
228
+ <p style='font-size: 1.5rem; color: #333;'>{game_state_snapshot['user_score']}</p>
 
 
 
 
 
229
  </div>
230
+ <div>
231
+ <h4 style='color: #333;'>AI Model</h4>
232
+ <p style='font-size: 1.5rem; color: #333;'>{game_state_snapshot['model_score']}</p>
233
  </div>
 
234
  </div>
235
+ <div style='margin-top: 1rem;'>
236
+ <p style='color: #333;'>Round: {current_display_round}/{game_state_snapshot['total_rounds']}</p>
237
+ </div>
238
+ {results_html}
239
+ </div>
240
+ """
241
+
242
+ game_state = GameState()
243
 
244
  def start_game():
245
+ """Initialize a new game"""
246
+ success, first_image_path = game_state.start_new_game()
247
 
248
+ if not success or not first_image_path:
249
+ print("Failed to start new game")
250
+ return [gr.update()] * 6
251
 
252
+ try:
253
+ current_image = Image.open(first_image_path)
254
+
255
+ return (
256
+ gr.update(value=current_image, visible=True),
257
+ gr.update(visible=False),
258
+ gr.update(visible=True, interactive=True),
259
+ gr.update(visible=True, interactive=True),
260
+ create_score_html(),
261
+ gr.update(visible=False)
262
+ )
263
+ except Exception as e:
264
+ print(f"Error starting game: {e}")
265
+ game_state.reset()
266
+ return [gr.update()] * 6
267
 
268
  def submit_guess(user_guess: str):
269
+ """Handle user guess submission"""
270
  if not game_state.can_submit_guess():
271
  return [gr.update()] * 6
272
 
 
273
  if not game_state.start_submission():
274
  return [gr.update()] * 6
275
 
276
  try:
 
277
  current_image_path = game_state.get_current_image()
278
  if not current_image_path:
279
+ game_state.processing_submission = False
280
  return [gr.update()] * 6
281
 
282
  current_image = Image.open(current_image_path)
 
284
  model_guess = "Real" if model_prediction['Authentic'] > PROB_THRESHOLD else "Fake"
285
  correct_answer = "Real" if "real_images" in current_image_path else "Fake"
286
 
 
287
  results = GameResults(user_guess, model_guess, correct_answer)
288
  game_state.finish_submission(results)
289
 
 
290
  if not game_state.is_game_active:
291
  return (
292
  gr.update(value=None, visible=False),
 
297
  gr.update(visible=True, value=game_state.get_game_over_message())
298
  )
299
 
 
300
  next_image_path = game_state.get_current_image()
301
  if not next_image_path:
302
  return [gr.update()] * 6
 
312
  gr.update(visible=False)
313
  )
314
  except Exception as e:
315
+ print(f"Error processing guess: {e}")
316
  game_state.processing_submission = False
317
+ return [gr.update()] * 6
318
 
319
  # Custom CSS
320
  custom_css = """