KASOTI / app.py
iisadia's picture
Update app.py
8622a36 verified
raw
history blame
8.72 kB
import streamlit as st
import time
import requests
import json
from streamlit.components.v1 import html
# Custom CSS for professional look
def inject_custom_css():
st.markdown("""
<style>
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap');
* {
font-family: 'Poppins', sans-serif;
}
.title {
font-size: 3rem !important;
font-weight: 700 !important;
color: #6C63FF !important;
text-align: center;
margin-bottom: 0.5rem;
}
.subtitle {
font-size: 1.2rem !important;
text-align: center;
color: #666 !important;
margin-bottom: 2rem;
}
.question-box {
background: #F8F9FA;
border-radius: 15px;
padding: 2rem;
margin: 1.5rem 0;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
color: black;
}
.answer-btn {
border-radius: 12px !important;
padding: 0.5rem 1.5rem !important;
font-weight: 600 !important;
margin: 0.5rem !important;
}
.yes-btn {
background: #6C63FF !important;
color: white !important;
}
.no-btn {
background: #FF6B6B !important;
color: white !important;
}
.final-reveal {
animation: fadeIn 2s;
font-size: 2.5rem;
color: #6C63FF;
text-align: center;
margin: 2rem 0;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.confetti {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1000;
}
</style>
""", unsafe_allow_html=True)
# Confetti animation (for final reveal)
def show_confetti():
html("""
<canvas id="confetti-canvas" class="confetti"></canvas>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/confetti.browser.min.js"></script>
<script>
const canvas = document.getElementById('confetti-canvas');
const confetti = confetti.create(canvas, { resize: true });
confetti({
particleCount: 150,
spread: 70,
origin: { y: 0.6 }
});
setTimeout(() => {
canvas.remove();
}, 5000);
</script>
""")
# Mistral AI API call
def ask_mistral(conversation_history, category):
api_url = "https://api.mistral.ai/v1/chat/completions"
headers = {
"Authorization": "Bearer gz6lDXokxgR6cLY72oomALWcm7vhjzQ",
"Content-Type": "application/json"
}
messages = [
{
"role": "system",
"content": f"You're playing 20 questions to guess a {category}. Ask strategic yes/no questions."
}
] + conversation_history
data = {
"model": "mistral-tiny",
"messages": messages,
"temperature": 0.7,
"max_tokens": 100
}
try:
response = requests.post(api_url, headers=headers, json=data)
response.raise_for_status()
return response.json()["choices"][0]["message"]["content"]
except Exception as e:
st.error(f"Error calling Mistral API: {str(e)}")
return "Could not generate question"
# Game logic
def main():
inject_custom_css()
st.markdown('<div class="title">KASOTI</div>', unsafe_allow_html=True)
st.markdown('<div class="subtitle">The Ultimate Guessing Game</div>', unsafe_allow_html=True)
if 'game_state' not in st.session_state:
st.session_state.game_state = "start"
st.session_state.questions = []
st.session_state.current_q = 0
st.session_state.answers = []
st.session_state.conversation_history = []
st.session_state.category = None
# Start screen
if st.session_state.game_state == "start":
st.markdown("""
<div class="question-box">
<h3>Welcome to <span style='color:#6C63FF;'>KASOTI ๐ŸŽฏ</span></h3>
<p>This is a fun guessing game! You'll think of something, and I'll ask maximum 20 Yes/No questions to guess what it is.</p>
<p>You can choose from three categories:</p>
<ul>
<li><strong>person</strong> โ€“ like a celebrity, fictional character, etc.</li>
<li><strong>place</strong> โ€“ like a city, country, or location</li>
<li><strong>object</strong> โ€“ like something you can touch or use</li>
</ul>
<p><strong>Type one of these categories below</strong> to begin: <code>person</code>, <code>place</code>, or <code>object</code>.</p>
</div>
""", unsafe_allow_html=True)
with st.form("start_form"):
category_input = st.text_input("Enter category (person / place / object):").strip().lower()
if st.form_submit_button("Start Game"):
if not category_input:
st.error("Please enter a category!")
elif category_input not in ["person", "place", "object"]:
st.error("Please enter either 'person', 'place', or 'object'!")
else:
st.session_state.category = category_input
# Generate first question
first_question = ask_mistral([
{"role": "user", "content": "Ask your first yes/no question."}
], category_input)
st.session_state.questions = [first_question]
st.session_state.conversation_history = [
{"role": "assistant", "content": first_question}
]
st.session_state.game_state = "gameplay"
st.rerun()
# Gameplay screen
elif st.session_state.game_state == "gameplay":
current_question = st.session_state.questions[st.session_state.current_q]
st.markdown(f'<div class="question-box">Question {st.session_state.current_q + 1}/20:<br><br>'
f'<strong>{current_question}</strong></div>',
unsafe_allow_html=True)
with st.form("answer_form"):
answer_input = st.text_input("Your answer (yes/no):").strip().lower()
if st.form_submit_button("Submit"):
if answer_input not in ["yes", "no"]:
st.error("Please answer with 'yes' or 'no'!")
else:
# Record answer
st.session_state.answers.append(answer_input)
st.session_state.conversation_history.append(
{"role": "user", "content": answer_input}
)
# Check if we've reached max questions
if st.session_state.current_q >= 19: # 0-based index
st.session_state.game_state = "result"
else:
# Generate next question
next_question = ask_mistral(
st.session_state.conversation_history,
st.session_state.category
)
st.session_state.questions.append(next_question)
st.session_state.conversation_history.append(
{"role": "assistant", "content": next_question}
)
st.session_state.current_q += 1
st.rerun()
# Result screen
elif st.session_state.game_state == "result":
# Generate final guess
final_guess = ask_mistral(
st.session_state.conversation_history + [
{"role": "user", "content": "Based on all my answers, what is your final guess? Just state the guess directly."}
],
st.session_state.category
)
show_confetti()
st.markdown('<div class="final-reveal">๐ŸŽ‰ I think it\'s...</div>', unsafe_allow_html=True)
time.sleep(1)
st.markdown(f'<div class="final-reveal" style="font-size:3.5rem;color:#6C63FF;">{final_guess}</div>',
unsafe_allow_html=True)
if st.button("Play Again", key="play_again"):
st.session_state.clear()
st.rerun()
if __name__ == "__main__":
main()