iisadia commited on
Commit
f34b1bf
ยท
verified ยท
1 Parent(s): 85fbfc1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +331 -178
app.py CHANGED
@@ -8,71 +8,125 @@ import os
8
  @st.cache_resource
9
  def get_help_agent():
10
  from transformers import pipeline
11
- # Using BlenderBot 400M Distill as the public conversational model (used elsewhere)
12
  return pipeline("conversational", model="facebook/blenderbot-400M-distill")
13
 
14
- # Custom CSS for professional look (fixed text color)
15
  def inject_custom_css():
16
  st.markdown("""
17
  <style>
18
- @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap');
19
 
20
  * {
21
- font-family: 'Poppins', sans-serif;
 
 
 
22
  }
23
 
24
- .title {
25
- font-size: 3rem !important;
26
- font-weight: 700 !important;
27
- color: #6C63FF !important;
 
 
 
 
 
 
 
 
 
28
  text-align: center;
 
 
 
 
 
 
29
  margin-bottom: 0.5rem;
30
  }
31
 
32
  .subtitle {
33
- font-size: 1.2rem !important;
34
- text-align: center;
35
- color: #666 !important;
36
- margin-bottom: 2rem;
37
  }
38
 
39
- .question-box {
40
- background: #F8F9FA;
41
- border-radius: 15px;
 
42
  padding: 2rem;
43
- margin: 1.5rem 0;
44
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
45
- color: black !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  }
47
 
48
- .answer-btn {
49
- border-radius: 12px !important;
50
- padding: 0.5rem 1.5rem !important;
51
- font-weight: 600 !important;
52
- margin: 0.5rem !important;
53
  }
54
 
55
  .yes-btn {
56
- background: #6C63FF !important;
57
  color: white !important;
58
  }
59
 
60
  .no-btn {
61
- background: #FF6B6B !important;
62
  color: white !important;
63
  }
64
 
65
- .final-reveal {
66
- animation: fadeIn 2s;
67
- font-size: 2.5rem;
68
- color: #6C63FF;
 
 
 
 
 
69
  text-align: center;
70
- margin: 2rem 0;
71
  }
72
 
73
- @keyframes fadeIn {
74
- from { opacity: 0; }
75
- to { opacity: 1; }
 
 
 
 
 
76
  }
77
 
78
  .confetti {
@@ -84,12 +138,32 @@ def inject_custom_css():
84
  pointer-events: none;
85
  z-index: 1000;
86
  }
87
-
88
- .confidence-meter {
89
- height: 10px;
90
- background: linear-gradient(90deg, #FF6B6B 0%, #6C63FF 100%);
91
- border-radius: 5px;
92
- margin: 10px 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  }
94
  </style>
95
  """, unsafe_allow_html=True)
@@ -100,13 +174,30 @@ def show_confetti():
100
  <canvas id="confetti-canvas" class="confetti"></canvas>
101
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/confetti.browser.min.js"></script>
102
  <script>
 
 
 
 
103
  const canvas = document.getElementById('confetti-canvas');
104
  const confetti = confetti.create(canvas, { resize: true });
105
- confetti({
106
- particleCount: 150,
107
- spread: 70,
108
- origin: { y: 0.6 }
109
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  setTimeout(() => { canvas.remove(); }, 5000);
111
  </script>
112
  """)
@@ -193,12 +284,45 @@ def ask_help_agent(query):
193
  except Exception as e:
194
  return f"Error in help agent: {str(e)}"
195
 
196
- # Main game logic
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  def main():
198
  inject_custom_css()
199
 
200
- st.markdown('<div class="title">KASOTI</div>', unsafe_allow_html=True)
201
- st.markdown('<div class="subtitle">The Smart Guessing Game</div>', unsafe_allow_html=True)
 
 
 
 
 
 
202
 
203
  if 'game_state' not in st.session_state:
204
  st.session_state.game_state = "start"
@@ -208,138 +332,161 @@ def main():
208
  st.session_state.conversation_history = []
209
  st.session_state.category = None
210
  st.session_state.final_guess = None
211
- st.session_state.help_conversation = [] # separate history for help agent
212
 
213
  # Start screen
214
  if st.session_state.game_state == "start":
215
- st.markdown("""
216
- <div class="question-box">
217
- <h3>Welcome to <span style='color:#6C63FF;'>KASOTI ๐ŸŽฏ</span></h3>
218
- <p>Think of something and I'll try to guess it in 20 questions or less!</p>
219
- <p>Choose a category:</p>
220
- <ul>
221
- <li><strong>Person</strong> - celebrity, fictional character, historical figure</li>
222
- <li><strong>Place</strong> - city, country, landmark, geographical location</li>
223
- <li><strong>Object</strong> - everyday item, tool, vehicle, etc.</li>
224
- </ul>
225
- <p>Type your category below to begin:</p>
226
- </div>
227
- """, unsafe_allow_html=True)
228
-
229
- with st.form("start_form"):
230
- category_input = st.text_input("Enter category (person/place/object):").strip().lower()
231
- if st.form_submit_button("Start Game"):
232
- if not category_input:
233
- st.error("Please enter a category!")
234
- elif category_input not in ["person", "place", "object"]:
235
- st.error("Please enter either 'person', 'place', or 'object'!")
236
- else:
237
- st.session_state.category = category_input
238
- first_question = ask_llama([
239
- {"role": "user", "content": "Ask your first strategic yes/no question."}
240
- ], category_input)
241
- st.session_state.questions = [first_question]
242
- st.session_state.conversation_history = [
243
- {"role": "assistant", "content": first_question}
244
- ]
245
- st.session_state.game_state = "gameplay"
246
- st.experimental_rerun()
 
 
 
 
 
 
 
 
 
 
247
 
248
  # Gameplay screen
249
  elif st.session_state.game_state == "gameplay":
250
- current_question = st.session_state.questions[st.session_state.current_q]
251
-
252
- # Check if AI made a guess
253
- if "Final Guess:" in current_question:
254
- st.session_state.final_guess = current_question.split("Final Guess:")[1].strip()
255
- st.session_state.game_state = "confirm_guess"
256
- st.experimental_rerun()
257
-
258
- st.markdown(f'<div class="question-box">Question {st.session_state.current_q + 1}/20:<br><br>'
259
- f'<strong>{current_question}</strong></div>',
260
- unsafe_allow_html=True)
261
-
262
- with st.form("answer_form"):
263
- answer_input = st.text_input("Your answer (yes/no/both):",
264
- key=f"answer_{st.session_state.current_q}").strip().lower()
265
- if st.form_submit_button("Submit"):
266
- if answer_input not in ["yes", "no", "both"]:
267
- st.error("Please answer with 'yes', 'no', or 'both'!")
268
- else:
269
- st.session_state.answers.append(answer_input)
270
- st.session_state.conversation_history.append(
271
- {"role": "user", "content": answer_input}
272
- )
273
-
274
- # Generate next response
275
- next_response = ask_llama(
276
- st.session_state.conversation_history,
277
- st.session_state.category
278
- )
279
-
280
- # Check if AI made a guess
281
- if "Final Guess:" in next_response:
282
- st.session_state.final_guess = next_response.split("Final Guess:")[1].strip()
283
- st.session_state.game_state = "confirm_guess"
284
- else:
285
- st.session_state.questions.append(next_response)
286
- st.session_state.conversation_history.append(
287
- {"role": "assistant", "content": next_response}
288
- )
289
- st.session_state.current_q += 1
290
-
291
- # Stop after 20 questions max
292
- if st.session_state.current_q >= 20:
293
- st.session_state.game_state = "result"
294
-
295
- st.experimental_rerun()
296
-
297
- # Side Help Option: independent chat with an AI help assistant using Hugging Face model
298
- with st.expander("Need Help? Chat with AI Assistant"):
299
- help_query = st.text_input("Enter your help query:", key="help_query")
300
- if st.button("Send", key="send_help"):
301
  if help_query:
302
  help_response = ask_help_agent(help_query)
303
  st.session_state.help_conversation.append({"query": help_query, "response": help_response})
304
- else:
305
- st.error("Please enter a query!")
306
  if st.session_state.help_conversation:
307
- for msg in st.session_state.help_conversation:
 
308
  st.markdown(f"**You:** {msg['query']}")
309
- st.markdown(f"**Help Assistant:** {msg['response']}")
 
310
 
311
- # Guess confirmation screen using text input response
312
  elif st.session_state.game_state == "confirm_guess":
313
- st.markdown(f'<div class="question-box">๐Ÿค– My Final Guess:<br><br>'
314
- f'<strong>Is it {st.session_state.final_guess}?</strong></div>',
315
- unsafe_allow_html=True)
316
-
317
- with st.form("confirm_form"):
318
- confirm_input = st.text_input("Type your answer (yes/no/both):", key="confirm_input").strip().lower()
319
- if st.form_submit_button("Submit"):
320
- if confirm_input not in ["yes", "no", "both"]:
321
- st.error("Please answer with 'yes', 'no', or 'both'!")
322
- else:
323
- if confirm_input == "yes":
324
- st.session_state.game_state = "result"
325
- st.experimental_rerun()
326
- st.stop() # Immediately halt further execution
327
- else:
328
- # Add negative response to history and continue gameplay
329
- st.session_state.conversation_history.append(
330
- {"role": "user", "content": "no"}
331
- )
332
- st.session_state.game_state = "gameplay"
333
- next_response = ask_llama(
334
- st.session_state.conversation_history,
335
- st.session_state.category
336
- )
337
- st.session_state.questions.append(next_response)
338
- st.session_state.conversation_history.append(
339
- {"role": "assistant", "content": next_response}
340
- )
341
- st.session_state.current_q += 1
342
- st.experimental_rerun()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343
 
344
  # Result screen
345
  elif st.session_state.game_state == "result":
@@ -357,17 +504,23 @@ def main():
357
  )
358
  st.session_state.final_guess = final_guess.split("Final Guess:")[-1].strip()
359
 
360
- show_confetti()
361
- st.markdown(f'<div class="final-reveal">๐ŸŽ‰ It\'s...</div>', unsafe_allow_html=True)
362
- time.sleep(1)
363
- st.markdown(f'<div class="final-reveal" style="font-size:3.5rem;color:#6C63FF;">{st.session_state.final_guess}</div>',
364
- unsafe_allow_html=True)
365
- st.markdown(f"<p style='text-align:center'>Guessed in {len(st.session_state.questions)} questions</p>",
366
- unsafe_allow_html=True)
367
-
368
- if st.button("Play Again", key="play_again"):
369
- st.session_state.clear()
370
- st.experimental_rerun()
 
 
 
 
 
 
371
 
372
  if __name__ == "__main__":
373
- main()
 
8
  @st.cache_resource
9
  def get_help_agent():
10
  from transformers import pipeline
 
11
  return pipeline("conversational", model="facebook/blenderbot-400M-distill")
12
 
13
+ # Enhanced Custom CSS with modern design
14
  def inject_custom_css():
15
  st.markdown("""
16
  <style>
17
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
18
 
19
  * {
20
+ font-family: 'Inter', sans-serif;
21
+ margin: 0;
22
+ padding: 0;
23
+ box-sizing: border-box;
24
  }
25
 
26
+ .container {
27
+ max-width: 800px;
28
+ margin: 0 auto;
29
+ padding: 2rem;
30
+ }
31
+
32
+ .gradient-header {
33
+ background: linear-gradient(135deg, #6366f1 0%, #a855f7 50%, #ec4899 100%);
34
+ color: white;
35
+ padding: 4rem 1rem;
36
+ border-radius: 0 0 2rem 2rem;
37
+ margin-bottom: 2rem;
38
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
39
  text-align: center;
40
+ }
41
+
42
+ .title {
43
+ font-size: 2.5rem;
44
+ font-weight: 700;
45
+ letter-spacing: -0.05em;
46
  margin-bottom: 0.5rem;
47
  }
48
 
49
  .subtitle {
50
+ font-size: 1.1rem;
51
+ opacity: 0.9;
52
+ font-weight: 400;
 
53
  }
54
 
55
+ .game-card {
56
+ background: rgba(255, 255, 255, 0.95);
57
+ backdrop-filter: blur(10px);
58
+ border-radius: 1.5rem;
59
  padding: 2rem;
60
+ margin: 1rem 0;
61
+ box-shadow: 0 4px 20px rgba(0,0,0,0.08);
62
+ border: 1px solid rgba(255,255,255,0.2);
63
+ }
64
+
65
+ .question-number {
66
+ font-size: 0.9rem;
67
+ color: #6b7280;
68
+ margin-bottom: 0.5rem;
69
+ }
70
+
71
+ .question-text {
72
+ font-size: 1.2rem;
73
+ color: #1f2937;
74
+ margin: 1rem 0;
75
+ line-height: 1.5;
76
+ font-weight: 500;
77
+ }
78
+
79
+ .answer-buttons {
80
+ display: flex;
81
+ gap: 1rem;
82
+ margin-top: 1.5rem;
83
+ justify-content: center;
84
+ }
85
+
86
+ .stButton>button {
87
+ transition: all 0.2s ease;
88
+ border-radius: 12px;
89
+ padding: 0.75rem 2rem;
90
+ font-weight: 600;
91
+ border: none;
92
  }
93
 
94
+ .stButton>button:hover {
95
+ transform: translateY(-2px);
96
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
 
 
97
  }
98
 
99
  .yes-btn {
100
+ background: #10b981 !important;
101
  color: white !important;
102
  }
103
 
104
  .no-btn {
105
+ background: #ef4444 !important;
106
  color: white !important;
107
  }
108
 
109
+ .both-btn {
110
+ background: #f59e0b !important;
111
+ color: white !important;
112
+ }
113
+
114
+ .result-card {
115
+ background: linear-gradient(135deg, #f0fdfa 0%, #f8fafc 100%);
116
+ border-radius: 1.5rem;
117
+ padding: 3rem 2rem;
118
  text-align: center;
119
+ animation: fadeIn 1s ease;
120
  }
121
 
122
+ .result-text {
123
+ font-size: 2rem;
124
+ font-weight: 700;
125
+ color: #1f2937;
126
+ margin: 1rem 0;
127
+ background: linear-gradient(135deg, #6366f1 0%, #ec4899 100%);
128
+ -webkit-background-clip: text;
129
+ -webkit-text-fill-color: transparent;
130
  }
131
 
132
  .confetti {
 
138
  pointer-events: none;
139
  z-index: 1000;
140
  }
141
+
142
+ @keyframes fadeIn {
143
+ from { opacity: 0; transform: translateY(20px); }
144
+ to { opacity: 1; transform: translateY(0); }
145
+ }
146
+
147
+ .progress-bar {
148
+ height: 8px;
149
+ background: #e5e7eb;
150
+ border-radius: 4px;
151
+ overflow: hidden;
152
+ margin: 1.5rem 0;
153
+ }
154
+
155
+ .progress-fill {
156
+ height: 100%;
157
+ background: linear-gradient(90deg, #6366f1 0%, #a855f7 100%);
158
+ transition: width 0.3s ease;
159
+ }
160
+
161
+ .help-sidebar {
162
+ background: rgba(255,255,255,0.9);
163
+ backdrop-filter: blur(10px);
164
+ padding: 1.5rem;
165
+ border-radius: 1rem;
166
+ border: 1px solid rgba(0,0,0,0.1);
167
  }
168
  </style>
169
  """, unsafe_allow_html=True)
 
174
  <canvas id="confetti-canvas" class="confetti"></canvas>
175
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/confetti.browser.min.js"></script>
176
  <script>
177
+ function randomInRange(min, max) {
178
+ return Math.random() * (max - min) + min;
179
+ }
180
+
181
  const canvas = document.getElementById('confetti-canvas');
182
  const confetti = confetti.create(canvas, { resize: true });
183
+
184
+ const count = 200;
185
+ const defaults = {
186
+ origin: { y: 0.7 }
187
+ };
188
+
189
+ function fire(particleRatio, opts) {
190
+ confetti(Object.assign({}, defaults, opts, {
191
+ particleCount: Math.floor(count * particleRatio)
192
+ }));
193
+ }
194
+
195
+ fire(0.25, { spread: 26, startVelocity: 55 });
196
+ fire(0.2, { spread: 60 });
197
+ fire(0.35, { spread: 100, decay: 0.91, scalar: 0.8 });
198
+ fire(0.1, { spread: 120, startVelocity: 25, decay: 0.92, scalar: 1.2 });
199
+ fire(0.1, { spread: 120, startVelocity: 45 });
200
+
201
  setTimeout(() => { canvas.remove(); }, 5000);
202
  </script>
203
  """)
 
284
  except Exception as e:
285
  return f"Error in help agent: {str(e)}"
286
 
287
+ def handle_answer(answer):
288
+ st.session_state.conversation_history.append(
289
+ {"role": "user", "content": answer}
290
+ )
291
+
292
+ # Generate next response
293
+ next_response = ask_llama(
294
+ st.session_state.conversation_history,
295
+ st.session_state.category
296
+ )
297
+
298
+ # Check if AI made a guess
299
+ if "Final Guess:" in next_response:
300
+ st.session_state.final_guess = next_response.split("Final Guess:")[1].strip()
301
+ st.session_state.game_state = "confirm_guess"
302
+ else:
303
+ st.session_state.questions.append(next_response)
304
+ st.session_state.conversation_history.append(
305
+ {"role": "assistant", "content": next_response}
306
+ )
307
+ st.session_state.current_q += 1
308
+
309
+ # Stop after 20 questions max
310
+ if st.session_state.current_q >= 20:
311
+ st.session_state.game_state = "result"
312
+
313
+ st.experimental_rerun()
314
+
315
  def main():
316
  inject_custom_css()
317
 
318
+ st.markdown("""
319
+ <div class="gradient-header">
320
+ <div class="container">
321
+ <h1 class="title">KASOTI</h1>
322
+ <p class="subtitle">AI-Powered Guessing Game</p>
323
+ </div>
324
+ </div>
325
+ """, unsafe_allow_html=True)
326
 
327
  if 'game_state' not in st.session_state:
328
  st.session_state.game_state = "start"
 
332
  st.session_state.conversation_history = []
333
  st.session_state.category = None
334
  st.session_state.final_guess = None
335
+ st.session_state.help_conversation = []
336
 
337
  # Start screen
338
  if st.session_state.game_state == "start":
339
+ with st.container():
340
+ st.markdown("""
341
+ <div class="container">
342
+ <div class="game-card">
343
+ <h3>๐ŸŽฎ How to Play</h3>
344
+ <p style="margin: 1rem 0; color: #4b5563;">
345
+ 1. Choose a category<br>
346
+ 2. Think of a specific item<br>
347
+ 3. Answer AI's questions<br>
348
+ 4. Try to stump the AI!
349
+ </p>
350
+ <div style="margin: 2rem 0;">
351
+ <div class="progress-bar">
352
+ <div class="progress-fill" style="width: 0%"></div>
353
+ </div>
354
+ </div>
355
+ """, unsafe_allow_html=True)
356
+
357
+ with st.form("start_form"):
358
+ col1, col2, col3 = st.columns(3)
359
+ with col2:
360
+ category = st.selectbox(
361
+ "Choose Category",
362
+ ["Person", "Place", "Object"],
363
+ index=None,
364
+ placeholder="Select category"
365
+ )
366
+ if st.form_submit_button("Start Game", use_container_width=True):
367
+ if not category:
368
+ st.error("Please select a category!")
369
+ else:
370
+ # Initialize game state
371
+ st.session_state.category = category.lower()
372
+ first_question = ask_llama([
373
+ {"role": "user", "content": "Ask your first strategic yes/no question."}
374
+ ], st.session_state.category)
375
+ st.session_state.questions = [first_question]
376
+ st.session_state.conversation_history = [
377
+ {"role": "assistant", "content": first_question}
378
+ ]
379
+ st.session_state.game_state = "gameplay"
380
+ st.experimental_rerun()
381
 
382
  # Gameplay screen
383
  elif st.session_state.game_state == "gameplay":
384
+ with st.container():
385
+ st.markdown(f"""
386
+ <div class="game-card">
387
+ <div class="question-number">
388
+ Question {st.session_state.current_q + 1}/20
389
+ </div>
390
+ <div class="question-text">
391
+ {st.session_state.questions[st.session_state.current_q]}
392
+ </div>
393
+ </div>
394
+ """, unsafe_allow_html=True)
395
+
396
+ # Progress bar
397
+ progress = (st.session_state.current_q + 1) / 20
398
+ st.markdown(f"""
399
+ <div class="progress-bar">
400
+ <div class="progress-fill" style="width: {progress * 100}%"></div>
401
+ </div>
402
+ """, unsafe_allow_html=True)
403
+
404
+ # Answer buttons
405
+ col1, col2, col3 = st.columns([1,1,1])
406
+ with col1:
407
+ if st.button("Yes โœ…", key="yes_btn", use_container_width=True, type="primary"):
408
+ st.session_state.answers.append("yes")
409
+ handle_answer("yes")
410
+ with col2:
411
+ if st.button("No โŒ", key="no_btn", use_container_width=True, type="primary"):
412
+ st.session_state.answers.append("no")
413
+ handle_answer("no")
414
+ with col3:
415
+ if st.button("Both ๐Ÿค”", key="both_btn", use_container_width=True, type="primary"):
416
+ st.session_state.answers.append("both")
417
+ handle_answer("both")
418
+
419
+ # Help sidebar
420
+ with st.sidebar:
421
+ st.markdown("""
422
+ <div class="help-sidebar">
423
+ <h3>๐Ÿค– AI Assistant</h3>
424
+ <p>Need help? Chat with our AI helper:</p>
425
+ """, unsafe_allow_html=True)
426
+
427
+ help_query = st.text_input("Type your question...", key="help_query")
428
+ if st.button("Send", use_container_width=True):
 
 
 
 
 
 
429
  if help_query:
430
  help_response = ask_help_agent(help_query)
431
  st.session_state.help_conversation.append({"query": help_query, "response": help_response})
432
+
 
433
  if st.session_state.help_conversation:
434
+ st.markdown("---")
435
+ for msg in st.session_state.help_conversation[-3:]: # Show last 3 messages
436
  st.markdown(f"**You:** {msg['query']}")
437
+ st.markdown(f"**Assistant:** {msg['response']}")
438
+ st.markdown("</div>", unsafe_allow_html=True)
439
 
440
+ # Confirm guess screen
441
  elif st.session_state.game_state == "confirm_guess":
442
+ with st.container():
443
+ st.markdown(f"""
444
+ <div class="game-card">
445
+ <h3>๐Ÿค– My Final Guess</h3>
446
+ <div class="question-text">
447
+ Is it {st.session_state.final_guess}?
448
+ </div>
449
+ </div>
450
+ """, unsafe_allow_html=True)
451
+
452
+ # Answer buttons
453
+ col1, col2, col3 = st.columns([1,1,1])
454
+ with col1:
455
+ if st.button("Yes โœ…", key="confirm_yes", use_container_width=True, type="primary"):
456
+ st.session_state.game_state = "result"
457
+ st.experimental_rerun()
458
+ with col2:
459
+ if st.button("No โŒ", key="confirm_no", use_container_width=True, type="primary"):
460
+ st.session_state.conversation_history.append(
461
+ {"role": "user", "content": "no"}
462
+ )
463
+ st.session_state.game_state = "gameplay"
464
+ next_response = ask_llama(
465
+ st.session_state.conversation_history,
466
+ st.session_state.category
467
+ )
468
+ st.session_state.questions.append(next_response)
469
+ st.session_state.conversation_history.append(
470
+ {"role": "assistant", "content": next_response}
471
+ )
472
+ st.session_state.current_q += 1
473
+ st.experimental_rerun()
474
+ with col3:
475
+ if st.button("Both ๐Ÿค”", key="confirm_both", use_container_width=True, type="primary"):
476
+ st.session_state.conversation_history.append(
477
+ {"role": "user", "content": "both"}
478
+ )
479
+ st.session_state.game_state = "gameplay"
480
+ next_response = ask_llama(
481
+ st.session_state.conversation_history,
482
+ st.session_state.category
483
+ )
484
+ st.session_state.questions.append(next_response)
485
+ st.session_state.conversation_history.append(
486
+ {"role": "assistant", "content": next_response}
487
+ )
488
+ st.session_state.current_q += 1
489
+ st.experimental_rerun()
490
 
491
  # Result screen
492
  elif st.session_state.game_state == "result":
 
504
  )
505
  st.session_state.final_guess = final_guess.split("Final Guess:")[-1].strip()
506
 
507
+ with st.container():
508
+ show_confetti()
509
+ st.markdown(f"""
510
+ <div class="result-card">
511
+ <h3>๐ŸŽ‰ Game Over!</h3>
512
+ <div class="result-text">
513
+ {st.session_state.final_guess}
514
+ </div>
515
+ <p style="color: #6b7280;">
516
+ Guessed in {len(st.session_state.questions)} questions
517
+ </p>
518
+ </div>
519
+ """, unsafe_allow_html=True)
520
+
521
+ if st.button("Play Again ๐Ÿ”„", use_container_width=True, type="primary"):
522
+ st.session_state.clear()
523
+ st.experimental_rerun()
524
 
525
  if __name__ == "__main__":
526
+ main()