File size: 6,396 Bytes
2fe6b7b
372b191
 
 
 
 
 
07d1fd0
372b191
1083254
09e445b
 
372b191
1083254
 
 
372b191
 
 
 
 
 
 
1083254
372b191
1083254
 
 
372b191
 
1083254
372b191
 
1083254
 
372b191
1083254
372b191
 
 
 
 
 
 
 
 
 
1083254
 
 
 
372b191
1083254
 
372b191
 
1083254
372b191
 
1083254
 
372b191
 
1083254
372b191
 
1083254
372b191
 
1083254
372b191
 
1083254
 
372b191
1083254
 
 
 
372b191
1083254
 
372b191
 
 
1083254
372b191
1083254
 
 
 
 
 
 
 
 
 
 
 
 
 
372b191
1083254
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
07d1fd0
 
1083254
 
 
 
 
07d1fd0
 
 
 
 
 
 
 
 
 
 
 
1083254
 
 
 
 
 
 
 
 
07d1fd0
1083254
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import streamlit as st
import speech_recognition as sr
import tempfile
import scipy.io.wavfile
import os
import requests
import numpy as np
from streamlit_audio_recorder import st_audiorec  # Make sure this is in requirements.txt

# Set API Keys
os.environ["MISTRAL_API_KEY"] = "cNjUx79Hl0A2AeiAMf6yi7o7ah4APoZy"
os.environ["GROQ_API_KEY"] = "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"

# Initialize session state
if "game_state" not in st.session_state:
    st.session_state.game_state = {
        "active": False,
        "questions_asked": 0,
        "answers": [],
        "current_question": None,
        "consult_mode": False
    }

def transcribe_audio(audio_bytes, language):
    try:
        with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp:
            tmp.write(audio_bytes)
            tmp_path = tmp.name

        recognizer = sr.Recognizer()
        with sr.AudioFile(tmp_path) as source:
            audio = recognizer.record(source)
            lang_code = "en-US" if language == "English" else "ur-PK"
            text = recognizer.recognize_google(audio, language=lang_code)
            return text.lower()
    except Exception as e:
        return f"⚠️ Transcription failed: {e}"

def query_llm(api, messages, model=None):
    headers = {
        "Authorization": f"Bearer {os.environ[f'{api}_API_KEY']}",
        "Content-Type": "application/json"
    }
    payload = {
        "messages": messages,
        "model": model or ("llama3-70b-8192" if api == "GROQ" else "mistral-medium")
    }
    endpoint = {
        "MISTRAL": "https://api.mistral.ai/v1/chat/completions",
        "GROQ": "https://api.groq.com/openai/v1/chat/completions"
    }[api]

    response = requests.post(endpoint, headers=headers, json=payload)
    return response.json()["choices"][0]["message"]["content"] if response.status_code == 200 else None

def generate_question(answers):
    prompt = "You are playing Kasoti. Based on these yes/no answers, ask the next best question:\n\n"
    for i, (q, a) in enumerate(answers, 1):
        prompt += f"{i}. Q: {q}\n   A: {a}\n"
    prompt += "\nAsk ONLY the next best yes/no question."
    return query_llm("GROQ", [{"role": "user", "content": prompt}]) or "Is it something you can hold?"

def make_guess(answers):
    prompt = "Based on this history, make a guess:\n\n"
    for i, (q, a) in enumerate(answers, 1):
        prompt += f"{i}. Q: {q}\n   A: {a}\n"
    return query_llm("GROQ", [{"role": "user", "content": prompt}]) or "I need more information."

def get_hint(question, answers):
    prompt = f"The player is unsure about answering: '{question}'. Previous history:\n"
    for q, a in answers:
        prompt += f"- Q: {q}\n  A: {a}\n"
    prompt += "\nSuggest a helpful hint."
    return query_llm("MISTRAL", [{"role": "user", "content": prompt}]) or "Try to think about what it really means."

def normalize_answer(ans):
    ans = ans.strip().lower()
    return {"yes": "yes", "y": "yes", "ہاں": "yes", "haan": "yes",
            "no": "no", "n": "no", "نہیں": "no", "nahi": "no"}.get(ans, None)

def start_game():
    st.session_state.game_state.update({
        "active": True,
        "questions_asked": 1,
        "answers": [],
        "current_question": "Is it a living thing?"
    })
    st.success("🎯 Think of something. I’ll guess it in 20 questions or less!")
    st.info(st.session_state.game_state["current_question"])

def handle_answer(user_input):
    gs = st.session_state.game_state
    norm_ans = normalize_answer(user_input)
    if not norm_ans:
        st.warning("Please answer 'yes' or 'no' (or ہاں / نہیں).")
        return

    if gs["current_question"] and "is this correct?" in gs["current_question"].lower():
        if norm_ans == "yes":
            st.success("🎉 YAY! I guessed it!")
            gs["active"] = False
        else:
            q = generate_question(gs["answers"])
            gs["current_question"] = q
            gs["questions_asked"] += 1
            st.info(q)
        return

    gs["answers"].append((gs["current_question"], norm_ans))
    if gs["questions_asked"] >= 20:
        final = make_guess(gs["answers"])
        st.error(f"🎮 Game Over! My final guess: {final}")
        gs["active"] = False
        return

    if gs["questions_asked"] % 5 == 0:
        guess = make_guess(gs["answers"])
        if guess.startswith("I think it's"):
            gs["current_question"] = guess + " Is this correct?"
            st.warning(gs["current_question"])
            return

    next_q = generate_question(gs["answers"])
    gs["current_question"] = next_q
    gs["questions_asked"] += 1
    st.info(next_q)

# UI
st.set_page_config(page_title="Kasoti Game 🎮", layout="centered")
st.title("🎮 Kasoti - 20 Questions Game")
st.markdown("Think of a **person, place, or object**. Answer with **yes/no** or **ہاں/نہیں**. I will guess!")

if st.button("Start Game"):
    start_game()

language = st.selectbox("Select Language for Audio Input", ["English", "Urdu"])

# Uploaded Audio File
audio_input = st.file_uploader("🎤 Upload your Answer (WAV format)", type=["wav"])
if audio_input:
    transcribed = transcribe_audio(audio_input.read(), language)
    st.text_area("Transcribed Answer", value=transcribed, key="text_input")

# Audio Recorder UI
st.markdown("### 🎙️ Or Record Your Answer")
audio_bytes = st_audiorec()

if audio_bytes is not None:
    st.success("✅ Recording complete!")
    if st.button("Transcribe Recorded Audio"):
        transcribed = transcribe_audio(audio_bytes, language)
        st.session_state.text_input = transcribed  # Store for answer processing
        st.text_area("Transcribed Answer", value=transcribed, key="text_input")

# Manual Input
manual_input = st.text_input("Or type your answer here (yes/no/ہاں/نہیں):")

if st.button("Submit Answer"):
    answer_text = manual_input or st.session_state.get("text_input", "")
    if not answer_text:
        st.warning("Please provide an answer.")
    else:
        handle_answer(answer_text)

# Hint mode
if st.checkbox("Enable Consult Mode"):
    st.session_state.game_state["consult_mode"] = True
    if st.button("🔍 Get Hint"):
        hint = get_hint(
            st.session_state.game_state["current_question"],
            st.session_state.game_state["answers"]
        )
        st.info(f"💡 Hint: {hint}")