iisadia commited on
Commit
1509f2d
Β·
verified Β·
1 Parent(s): 46452c1

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +224 -0
app.py ADDED
@@ -0,0 +1,224 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import time
3
+ import requests
4
+ from streamlit.components.v1 import html
5
+
6
+ # Cache the help agent
7
+ @st.cache_resource
8
+ def get_help_agent():
9
+ from transformers import pipeline
10
+ return pipeline("conversational", model="facebook/blenderbot-400M-distill")
11
+
12
+ # Custom CSS
13
+ def inject_custom_css():
14
+ st.markdown("""
15
+ <style>
16
+ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap');
17
+ * { font-family: 'Poppins', sans-serif; }
18
+ .title { font-size: 3rem !important; color: #6C63FF !important; text-align: center; }
19
+ .subtitle { font-size: 1.2rem !important; text-align: center; color: #666 !important; }
20
+ .question-box { background: #F8F9FA; border-radius: 15px; padding: 2rem; margin: 1.5rem 0; box-shadow: 0 4px 6px rgba(0,0,0,0.1); }
21
+ .answer-btn { border-radius: 12px !important; padding: 0.5rem 1.5rem !important; }
22
+ .yes-btn { background: #6C63FF !important; color: white !important; }
23
+ .no-btn { background: #FF6B6B !important; color: white !important; }
24
+ .final-reveal { animation: fadeIn 2s; font-size: 2.5rem; color: #6C63FF; text-align: center; margin: 2rem 0; }
25
+ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
26
+ .confetti { position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 1000; }
27
+ </style>
28
+ """, unsafe_allow_html=True)
29
+
30
+ # Confetti animation
31
+ def show_confetti():
32
+ html("""
33
+ <canvas id="confetti-canvas" class="confetti"></canvas>
34
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/confetti.browser.min.js"></script>
35
+ <script>
36
+ const canvas = document.getElementById('confetti-canvas');
37
+ const confetti = confetti.create(canvas, { resize: true });
38
+ confetti({ particleCount: 150, spread: 70, origin: { y: 0.6 } });
39
+ setTimeout(() => { canvas.remove(); }, 5000);
40
+ </script>
41
+ """)
42
+
43
+ # Improved question generation
44
+ def ask_llama(conversation_history, category, is_final_guess=False):
45
+ api_url = "https://api.groq.com/openai/v1/chat/completions"
46
+ headers = {
47
+ "Authorization": "Bearer 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",
48
+ "Content-Type": "application/json"
49
+ }
50
+
51
+ system_prompt = f"""You're playing 20 questions to guess a {category}. Follow these STRICT rules:
52
+ 1. FIRST determine category specifics:
53
+ - Person: Start with real/fictional, alive/dead, gender, profession
54
+ - Place: Start with continent, urban/rural, famous landmarks
55
+ - Object: Start with purpose, size, material, location used
56
+ 2. Ask SPECIFIC yes/no questions that eliminate possibilities
57
+ 3. Only guess when 95% confident using "Final Guess: [answer]"
58
+ 4. After guessing, immediately stop and verify
59
+ 5. Never repeat questions
60
+ 6. For objects: ask about usage, parts, location, materials
61
+ 7. For people: clarify fictional status early
62
+ 8. For places: ask about geography early"""
63
+
64
+ messages = [
65
+ {"role": "system", "content": system_prompt},
66
+ *conversation_history,
67
+ {"role": "user", "content": "Ask your next question:" if not is_final_guess else "Make your final guess:"}
68
+ ]
69
+
70
+ data = {
71
+ "model": "llama-3.3-70b-versatile",
72
+ "messages": messages,
73
+ "temperature": 0.3 if is_final_guess else 0.7,
74
+ "max_tokens": 100,
75
+ "top_p": 0.9,
76
+ "frequency_penalty": 0.5
77
+ }
78
+
79
+ try:
80
+ response = requests.post(api_url, headers=headers, json=data)
81
+ return response.json()["choices"][0]["message"]["content"]
82
+ except Exception as e:
83
+ st.error(f"API Error: {str(e)}")
84
+ return "Could not generate question"
85
+
86
+ # Help assistant
87
+ def ask_help_agent(query):
88
+ from transformers import Conversation
89
+ return get_help_agent()(Conversation(query)).generated_responses[-1]
90
+
91
+ # Main app
92
+ def main():
93
+ inject_custom_css()
94
+ st.markdown('<div class="title">KASOTI</div><div class="subtitle">The Smart Guessing Game</div>', unsafe_allow_html=True)
95
+
96
+ if 'game_state' not in st.session_state:
97
+ st.session_state.update({
98
+ 'game_state': "start",
99
+ 'questions': [],
100
+ 'current_q': 0,
101
+ 'answers': [],
102
+ 'conversation_history': [],
103
+ 'category': None,
104
+ 'final_guess': None,
105
+ 'help_conversation': []
106
+ })
107
+
108
+ # Start screen
109
+ if st.session_state.game_state == "start":
110
+ st.markdown("""
111
+ <div class="question-box">
112
+ <h3>Welcome to KASOTI 🎯</h3>
113
+ <p>Think of something and I'll guess it in 20 questions or less!</p>
114
+ <p>Choose category:</p>
115
+ <ul>
116
+ <li><strong>Person</strong> - real or fictional</li>
117
+ <li><strong>Place</strong> - any geographical location</li>
118
+ <li><strong>Object</strong> - any physical item</li>
119
+ </ul>
120
+ </div>
121
+ """, unsafe_allow_html=True)
122
+
123
+ with st.form("start_form"):
124
+ category = st.selectbox("Select category:", ["person", "place", "object"])
125
+ if st.form_submit_button("Start Game"):
126
+ st.session_state.category = category
127
+ first_question = ask_llama([], category)
128
+ st.session_state.questions = [first_question]
129
+ st.session_state.conversation_history = [{"role": "assistant", "content": first_question}]
130
+ st.session_state.game_state = "gameplay"
131
+ st.rerun()
132
+
133
+ # Gameplay screen
134
+ elif st.session_state.game_state == "gameplay":
135
+ current_question = st.session_state.questions[-1]
136
+
137
+ # Check for final guess
138
+ if "Final Guess:" in current_question:
139
+ st.session_state.final_guess = current_question.split("Final Guess:")[1].strip()
140
+ st.session_state.game_state = "confirm_guess"
141
+ st.rerun()
142
+
143
+ st.markdown(f'<div class="question-box">Question {st.session_state.current_q + 1}/20:<br><br><strong>{current_question}</strong></div>', unsafe_allow_html=True)
144
+
145
+ with st.form("answer_form"):
146
+ answer = st.radio("Your answer:", ["Yes", "No", "Both"], horizontal=True)
147
+ if st.form_submit_button("Submit"):
148
+ detailed_answer = {
149
+ "Yes": "Yes, that's correct.",
150
+ "No": "No, that's not correct.",
151
+ "Both": "It can be both depending on context."
152
+ }[answer]
153
+
154
+ st.session_state.answers.append(detailed_answer)
155
+ st.session_state.conversation_history.append({"role": "user", "content": detailed_answer})
156
+
157
+ # Generate next question
158
+ next_response = ask_llama(st.session_state.conversation_history, st.session_state.category)
159
+ st.session_state.questions.append(next_response)
160
+ st.session_state.conversation_history.append({"role": "assistant", "content": next_response})
161
+ st.session_state.current_q += 1
162
+
163
+ # Max 20 questions
164
+ if st.session_state.current_q >= 19:
165
+ st.session_state.game_state = "result"
166
+ st.rerun()
167
+
168
+ # Help section
169
+ with st.expander("πŸ’‘ Need Help?"):
170
+ help_query = st.text_input("Ask the AI Assistant:")
171
+ if st.button("Send"):
172
+ if help_query:
173
+ help_response = ask_help_agent(help_query)
174
+ st.session_state.help_conversation.append(f"You: {help_query}\nAssistant: {help_response}")
175
+ for msg in st.session_state.help_conversation[-3:]:
176
+ st.markdown(f"`{msg}`")
177
+
178
+ # Guess confirmation screen
179
+ elif st.session_state.game_state == "confirm_guess":
180
+ st.markdown(f'<div class="question-box">🎯 My Final Guess:<br><br><strong>Is it {st.session_state.final_guess}?</strong></div>', unsafe_allow_html=True)
181
+
182
+ col1, col2 = st.columns(2)
183
+ with col1:
184
+ if st.button("Yes! Correct!", key="correct", use_container_width=True):
185
+ st.session_state.game_state = "result"
186
+ st.rerun()
187
+ with col2:
188
+ if st.button("No, Keep Trying", key="wrong", use_container_width=True):
189
+ st.session_state.conversation_history.append({"role": "user", "content": "No, that's incorrect."})
190
+ next_response = ask_llama(st.session_state.conversation_history, st.session_state.category)
191
+ st.session_state.questions.append(next_response)
192
+ st.session_state.conversation_history.append({"role": "assistant", "content": next_response})
193
+ st.session_state.current_q += 1
194
+ st.session_state.game_state = "gameplay"
195
+ st.rerun()
196
+
197
+ # Result screen
198
+ elif st.session_state.game_state == "result":
199
+ if not st.session_state.final_guess:
200
+ # Fixed list comprehension with proper bracket closure
201
+ qa_history = "\n".join(
202
+ [f"Q{i+1}: {q}\nA: {a}"
203
+ for i, (q, a) in enumerate(zip(st.session_state.questions, st.session_state.answers))]
204
+ )
205
+
206
+ final_guess = ask_llama(
207
+ [{"role": "user", "content": qa_history}],
208
+ st.session_state.category,
209
+ is_final_guess=True
210
+ )
211
+ st.session_state.final_guess = final_guess.split("Final Guess:")[-1].strip()
212
+
213
+ show_confetti()
214
+ st.markdown(f'<div class="final-reveal">πŸŽ‰ It\'s...</div>', unsafe_allow_html=True)
215
+ time.sleep(1)
216
+ st.markdown(f'<div class="final-reveal" style="font-size:3.5rem;">{st.session_state.final_guess}</div>', unsafe_allow_html=True)
217
+ st.markdown(f"<p style='text-align:center'>Guessed in {len(st.session_state.questions)} questions</p>", unsafe_allow_html=True)
218
+
219
+ if st.button("Play Again", key="play_again"):
220
+ st.session_state.clear()
221
+ st.rerun()
222
+
223
+ if __name__ == "__main__":
224
+ main()