Spaces:
Running
Running
Update app.py
#91
by
Muthuraja18
- opened
app.py
CHANGED
|
@@ -651,28 +651,40 @@ def join_game(game_id, username, avatar):
|
|
| 651 |
|
| 652 |
return ok, msg
|
| 653 |
|
|
|
|
|
|
|
|
|
|
| 654 |
|
| 655 |
-
|
| 656 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 657 |
flags = []
|
| 658 |
|
| 659 |
-
for
|
| 660 |
-
|
|
|
|
| 661 |
|
| 662 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 663 |
|
| 664 |
-
|
|
|
|
|
|
|
|
|
|
| 665 |
|
| 666 |
-
|
| 667 |
-
base = 10
|
| 668 |
-
t = times[i] if i < len(times) and times[i] else 999
|
| 669 |
-
bonus = max(0, int((max(0, 15 - min(t, 15)) / 15) * 5))
|
| 670 |
-
total += base + bonus
|
| 671 |
-
flags.append("Yes")
|
| 672 |
-
else:
|
| 673 |
-
flags.append("No")
|
| 674 |
|
| 675 |
-
return total, flags
|
| 676 |
|
| 677 |
|
| 678 |
# ----------------- UI -----------------
|
|
@@ -904,52 +916,50 @@ def create_game(host=None, topics=[], num_questions=5, auto_close=True, ai_topic
|
|
| 904 |
|
| 905 |
st.success(f"Game created: {gid} with {len(questions)} questions.")
|
| 906 |
return gid
|
| 907 |
-
|
| 908 |
-
|
| 909 |
|
| 910 |
-
|
| 911 |
# -------------------------
|
| 912 |
# PLAY PAGE
|
| 913 |
# -------------------------
|
| 914 |
def play_page():
|
| 915 |
gid = st.session_state.get("active_game_id")
|
| 916 |
uname = st.session_state.get("username")
|
| 917 |
-
|
| 918 |
if not gid or not uname:
|
| 919 |
st.error("No active game or username found. Please join or create a game first.")
|
| 920 |
return
|
| 921 |
|
|
|
|
| 922 |
games = unified_get("games") or {}
|
| 923 |
game = games.get(gid)
|
| 924 |
if not game:
|
| 925 |
-
st.error("Game not found
|
|
|
|
|
|
|
|
|
|
| 926 |
return
|
| 927 |
|
| 928 |
-
questions =
|
| 929 |
if not questions:
|
| 930 |
-
st.
|
| 931 |
return
|
| 932 |
|
| 933 |
-
#
|
| 934 |
-
if
|
| 935 |
-
st.session_state[
|
| 936 |
-
|
| 937 |
-
|
| 938 |
-
|
| 939 |
-
|
| 940 |
-
if
|
| 941 |
-
st.session_state[
|
| 942 |
|
| 943 |
-
|
| 944 |
-
st.session_state['question_started_at'] = time.time()
|
| 945 |
-
|
| 946 |
-
idx = st.session_state['current_index']
|
| 947 |
|
|
|
|
| 948 |
if idx >= len(questions):
|
| 949 |
st.success("All done — submit your answers!")
|
| 950 |
return
|
| 951 |
|
| 952 |
-
# ----------------
|
| 953 |
q = questions[idx]
|
| 954 |
st.subheader(f"Question {idx+1}/{len(questions)}")
|
| 955 |
st.write(q["question"])
|
|
@@ -958,49 +968,42 @@ def play_page():
|
|
| 958 |
time_limit = 15
|
| 959 |
st.markdown(f"**Time left:** {max(0, time_limit - elapsed)} seconds")
|
| 960 |
|
| 961 |
-
# ----------------
|
| 962 |
choice = st.radio(
|
| 963 |
"Choose an answer:",
|
| 964 |
q["options"],
|
|
|
|
| 965 |
key=f"choice_{gid}_{idx}"
|
| 966 |
)
|
| 967 |
|
| 968 |
col1, col2 = st.columns(2)
|
| 969 |
|
| 970 |
-
# ----------------
|
| 971 |
with col1:
|
| 972 |
if st.button("Next", key=f"next_{gid}_{idx}"):
|
| 973 |
-
|
| 974 |
-
|
| 975 |
-
|
| 976 |
-
|
| 977 |
-
|
| 978 |
-
answers[idx] = choice
|
| 979 |
-
times[idx] = taken
|
| 980 |
-
|
| 981 |
st.session_state['current_index'] = idx + 1
|
| 982 |
st.session_state['question_started_at'] = time.time()
|
| 983 |
st.rerun()
|
| 984 |
|
| 985 |
-
# ----------------
|
| 986 |
-
# ---------------- SUBMIT ----------------
|
| 987 |
with col2:
|
| 988 |
if idx == len(questions) - 1:
|
| 989 |
if st.button("Submit All Answers", key=f"submit_{gid}_{idx}"):
|
|
|
|
|
|
|
|
|
|
|
|
|
| 990 |
answers = st.session_state['answers']
|
| 991 |
times = st.session_state['answer_times']
|
| 992 |
-
|
| 993 |
-
answers[idx] = choice
|
| 994 |
-
times[idx] = time.time() - st.session_state['question_started_at']
|
| 995 |
|
| 996 |
# Compute score
|
| 997 |
-
score, flags = compute_score(
|
| 998 |
-
questions,
|
| 999 |
-
answers,
|
| 1000 |
-
times
|
| 1001 |
-
)
|
| 1002 |
percentage = int(score / (len(questions) * 15) * 100)
|
| 1003 |
-
|
| 1004 |
# Update players dict
|
| 1005 |
players = unified_get("players") or {}
|
| 1006 |
players.setdefault(gid, {})
|
|
@@ -1013,7 +1016,8 @@ def play_page():
|
|
| 1013 |
"timestamp": now_iso()
|
| 1014 |
}
|
| 1015 |
unified_set("players", players)
|
| 1016 |
-
|
|
|
|
| 1017 |
row = {
|
| 1018 |
"name": uname,
|
| 1019 |
"avatar": st.session_state.get("avatar", "🎮"),
|
|
@@ -1026,22 +1030,25 @@ def play_page():
|
|
| 1026 |
"answers": answers,
|
| 1027 |
"correct_flags": flags
|
| 1028 |
}
|
| 1029 |
-
unified_push_leaderboard(row)
|
| 1030 |
-
|
| 1031 |
# Auto-close game if needed
|
| 1032 |
if game.get('auto_close', True):
|
| 1033 |
games[gid]['closed'] = True
|
| 1034 |
games[gid]['closed_at'] = now_iso()
|
| 1035 |
unified_set("games", games)
|
| 1036 |
|
| 1037 |
-
|
| 1038 |
-
|
| 1039 |
-
)
|
| 1040 |
st.balloons()
|
| 1041 |
st.session_state['last_score'] = score
|
| 1042 |
st.session_state['last_game'] = gid
|
| 1043 |
st.session_state['current_index'] = 0
|
|
|
|
|
|
|
| 1044 |
st.rerun()
|
|
|
|
|
|
|
| 1045 |
|
| 1046 |
# Join game
|
| 1047 |
def join_game_page():
|
|
|
|
| 651 |
|
| 652 |
return ok, msg
|
| 653 |
|
| 654 |
+
def compute_score(questions, answers, times=None):
|
| 655 |
+
"""
|
| 656 |
+
Compute the total score and correctness flags for each question.
|
| 657 |
|
| 658 |
+
Args:
|
| 659 |
+
questions (list): List of question dicts. Each dict must have 'answer' key.
|
| 660 |
+
answers (list): List of user's answers corresponding to questions.
|
| 661 |
+
times (list, optional): Time taken for each question (in seconds).
|
| 662 |
+
|
| 663 |
+
Returns:
|
| 664 |
+
score (int): Total score.
|
| 665 |
+
flags (list): List of correctness flags: True if correct, False if incorrect.
|
| 666 |
+
"""
|
| 667 |
+
score_per_question = 15
|
| 668 |
+
score = 0
|
| 669 |
flags = []
|
| 670 |
|
| 671 |
+
for idx, q in enumerate(questions):
|
| 672 |
+
correct_ans = q.get("answer")
|
| 673 |
+
user_ans = answers[idx] if idx < len(answers) else None
|
| 674 |
|
| 675 |
+
if user_ans == correct_ans:
|
| 676 |
+
score += score_per_question
|
| 677 |
+
flags.append(True)
|
| 678 |
+
else:
|
| 679 |
+
flags.append(False)
|
| 680 |
|
| 681 |
+
# Optional: implement time-based penalties if needed
|
| 682 |
+
# if times:
|
| 683 |
+
# if times[idx] > 15: # example: 15 sec limit
|
| 684 |
+
# score -= 5 # penalty
|
| 685 |
|
| 686 |
+
return score, flags
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 687 |
|
|
|
|
| 688 |
|
| 689 |
|
| 690 |
# ----------------- UI -----------------
|
|
|
|
| 916 |
|
| 917 |
st.success(f"Game created: {gid} with {len(questions)} questions.")
|
| 918 |
return gid
|
|
|
|
|
|
|
| 919 |
|
|
|
|
| 920 |
# -------------------------
|
| 921 |
# PLAY PAGE
|
| 922 |
# -------------------------
|
| 923 |
def play_page():
|
| 924 |
gid = st.session_state.get("active_game_id")
|
| 925 |
uname = st.session_state.get("username")
|
|
|
|
| 926 |
if not gid or not uname:
|
| 927 |
st.error("No active game or username found. Please join or create a game first.")
|
| 928 |
return
|
| 929 |
|
| 930 |
+
# Fetch game and questions
|
| 931 |
games = unified_get("games") or {}
|
| 932 |
game = games.get(gid)
|
| 933 |
if not game:
|
| 934 |
+
st.error("Game not found.")
|
| 935 |
+
return
|
| 936 |
+
if game.get("closed"):
|
| 937 |
+
st.warning("This game has already ended.")
|
| 938 |
return
|
| 939 |
|
| 940 |
+
questions = game.get("questions", [])
|
| 941 |
if not questions:
|
| 942 |
+
st.info("No questions loaded.")
|
| 943 |
return
|
| 944 |
|
| 945 |
+
# Initialize session state
|
| 946 |
+
if "current_index" not in st.session_state:
|
| 947 |
+
st.session_state["current_index"] = 0
|
| 948 |
+
if "answers" not in st.session_state:
|
| 949 |
+
st.session_state["answers"] = [None] * len(questions)
|
| 950 |
+
if "answer_times" not in st.session_state:
|
| 951 |
+
st.session_state["answer_times"] = [0] * len(questions)
|
| 952 |
+
if "question_started_at" not in st.session_state:
|
| 953 |
+
st.session_state["question_started_at"] = time.time()
|
| 954 |
|
| 955 |
+
idx = st.session_state["current_index"]
|
|
|
|
|
|
|
|
|
|
| 956 |
|
| 957 |
+
# ---------------- End of questions ----------------
|
| 958 |
if idx >= len(questions):
|
| 959 |
st.success("All done — submit your answers!")
|
| 960 |
return
|
| 961 |
|
| 962 |
+
# ---------------- Question UI ----------------
|
| 963 |
q = questions[idx]
|
| 964 |
st.subheader(f"Question {idx+1}/{len(questions)}")
|
| 965 |
st.write(q["question"])
|
|
|
|
| 968 |
time_limit = 15
|
| 969 |
st.markdown(f"**Time left:** {max(0, time_limit - elapsed)} seconds")
|
| 970 |
|
| 971 |
+
# ---------------- Stable Radio ----------------
|
| 972 |
choice = st.radio(
|
| 973 |
"Choose an answer:",
|
| 974 |
q["options"],
|
| 975 |
+
index=st.session_state['answers'][idx] if st.session_state['answers'][idx] in q["options"] else 0,
|
| 976 |
key=f"choice_{gid}_{idx}"
|
| 977 |
)
|
| 978 |
|
| 979 |
col1, col2 = st.columns(2)
|
| 980 |
|
| 981 |
+
# ---------------- Next Button ----------------
|
| 982 |
with col1:
|
| 983 |
if st.button("Next", key=f"next_{gid}_{idx}"):
|
| 984 |
+
# Record answer and time
|
| 985 |
+
st.session_state['answers'][idx] = choice
|
| 986 |
+
st.session_state['answer_times'][idx] = time.time() - st.session_state['question_started_at']
|
| 987 |
+
# Move to next question
|
|
|
|
|
|
|
|
|
|
|
|
|
| 988 |
st.session_state['current_index'] = idx + 1
|
| 989 |
st.session_state['question_started_at'] = time.time()
|
| 990 |
st.rerun()
|
| 991 |
|
| 992 |
+
# ---------------- Submit Button ----------------
|
|
|
|
| 993 |
with col2:
|
| 994 |
if idx == len(questions) - 1:
|
| 995 |
if st.button("Submit All Answers", key=f"submit_{gid}_{idx}"):
|
| 996 |
+
# Record last question
|
| 997 |
+
st.session_state['answers'][idx] = choice
|
| 998 |
+
st.session_state['answer_times'][idx] = time.time() - st.session_state['question_started_at']
|
| 999 |
+
|
| 1000 |
answers = st.session_state['answers']
|
| 1001 |
times = st.session_state['answer_times']
|
|
|
|
|
|
|
|
|
|
| 1002 |
|
| 1003 |
# Compute score
|
| 1004 |
+
score, flags = compute_score(questions, answers, times)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1005 |
percentage = int(score / (len(questions) * 15) * 100)
|
| 1006 |
+
|
| 1007 |
# Update players dict
|
| 1008 |
players = unified_get("players") or {}
|
| 1009 |
players.setdefault(gid, {})
|
|
|
|
| 1016 |
"timestamp": now_iso()
|
| 1017 |
}
|
| 1018 |
unified_set("players", players)
|
| 1019 |
+
|
| 1020 |
+
# Push to leaderboard
|
| 1021 |
row = {
|
| 1022 |
"name": uname,
|
| 1023 |
"avatar": st.session_state.get("avatar", "🎮"),
|
|
|
|
| 1030 |
"answers": answers,
|
| 1031 |
"correct_flags": flags
|
| 1032 |
}
|
| 1033 |
+
unified_push_leaderboard(row)
|
| 1034 |
+
|
| 1035 |
# Auto-close game if needed
|
| 1036 |
if game.get('auto_close', True):
|
| 1037 |
games[gid]['closed'] = True
|
| 1038 |
games[gid]['closed_at'] = now_iso()
|
| 1039 |
unified_set("games", games)
|
| 1040 |
|
| 1041 |
+
# Reset session state
|
| 1042 |
+
st.success(f"Submitted! Score: {score} / {len(questions)*15} ({percentage}%)")
|
|
|
|
| 1043 |
st.balloons()
|
| 1044 |
st.session_state['last_score'] = score
|
| 1045 |
st.session_state['last_game'] = gid
|
| 1046 |
st.session_state['current_index'] = 0
|
| 1047 |
+
st.session_state['answers'] = []
|
| 1048 |
+
st.session_state['answer_times'] = []
|
| 1049 |
st.rerun()
|
| 1050 |
+
|
| 1051 |
+
|
| 1052 |
|
| 1053 |
# Join game
|
| 1054 |
def join_game_page():
|