Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -775,37 +775,74 @@ def home_page():
|
|
| 775 |
|
| 776 |
# ----------------------------
|
| 777 |
# Play Page
|
| 778 |
-
# ----------------------------
|
| 779 |
def play_page():
|
| 780 |
-
|
| 781 |
-
|
| 782 |
-
|
| 783 |
-
|
| 784 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 785 |
|
|
|
|
| 786 |
games = unified_get("games") or {}
|
| 787 |
game = games.get(gid)
|
| 788 |
if not game:
|
| 789 |
-
st.error("Game not found.")
|
| 790 |
return
|
| 791 |
|
| 792 |
-
questions = st.session_state.get(
|
| 793 |
if not questions:
|
| 794 |
-
st.error("No questions loaded.")
|
| 795 |
return
|
| 796 |
|
| 797 |
-
# Timer
|
| 798 |
if 'question_started_at' not in st.session_state or st.session_state['question_started_at'] is None:
|
| 799 |
st.session_state['question_started_at'] = time.time()
|
| 800 |
|
| 801 |
idx = st.session_state.get('current_index', 0)
|
| 802 |
if idx >= len(questions):
|
| 803 |
-
st.success("All done โ submit!")
|
| 804 |
return
|
| 805 |
|
| 806 |
q = questions[idx]
|
| 807 |
st.subheader(f"Question {idx+1}/{len(questions)}")
|
| 808 |
st.write(q["question"])
|
|
|
|
| 809 |
elapsed = int(time.time() - st.session_state['question_started_at'])
|
| 810 |
time_limit = 15
|
| 811 |
st.markdown(f"**Time left:** {max(0, time_limit - elapsed)} seconds")
|
|
@@ -814,38 +851,35 @@ def play_page():
|
|
| 814 |
|
| 815 |
col1, col2 = st.columns(2)
|
| 816 |
with col1:
|
| 817 |
-
if st.button("Next
|
| 818 |
-
|
| 819 |
-
answers = st.session_state.get('answers', [""]*len(questions))
|
| 820 |
-
times = st.session_state.get('answer_times', [None]*len(questions))
|
| 821 |
answers[idx] = choice
|
| 822 |
-
times[idx] =
|
| 823 |
st.session_state['answers'] = answers
|
| 824 |
st.session_state['answer_times'] = times
|
|
|
|
| 825 |
st.session_state['current_index'] = idx + 1
|
| 826 |
st.session_state['question_started_at'] = time.time()
|
| 827 |
-
|
| 828 |
-
# Update heartbeat
|
| 829 |
-
players = unified_get("players") or {}
|
| 830 |
-
if players.get(gid, {}).get(uname):
|
| 831 |
-
players[gid][uname]['last_heartbeat'] = now_iso()
|
| 832 |
-
unified_set("players", players)
|
| 833 |
-
heartbeat_unified(gid, uname)
|
| 834 |
st.experimental_rerun()
|
| 835 |
|
| 836 |
with col2:
|
| 837 |
-
if idx == len(questions)
|
| 838 |
-
if st.button("Submit All Answers"
|
| 839 |
-
answers = st.session_state.get('answers', [""]*len(questions))
|
| 840 |
-
times = st.session_state.get('answer_times', [None]*len(questions))
|
| 841 |
answers[idx] = choice
|
| 842 |
-
times[idx] = time.time() - st.session_state
|
|
|
|
| 843 |
st.session_state['answers'] = answers
|
| 844 |
st.session_state['answer_times'] = times
|
| 845 |
|
|
|
|
| 846 |
score, flags = compute_score(questions, answers, times)
|
| 847 |
-
now =
|
| 848 |
-
avatar = "๐ฎ"
|
|
|
|
| 849 |
row = {
|
| 850 |
"name": uname,
|
| 851 |
"score": score,
|
|
@@ -855,21 +889,20 @@ def play_page():
|
|
| 855 |
"avatar": avatar,
|
| 856 |
"questions": " || ".join([q["question"] for q in questions]),
|
| 857 |
"answers": " || ".join([str(a) for a in answers]),
|
| 858 |
-
"correct_flags": " || ".join(flags)
|
| 859 |
-
"percentage": round(score / len(questions) * 100, 2)
|
| 860 |
}
|
| 861 |
unified_push_leaderboard(row)
|
| 862 |
|
| 863 |
-
# Mark player submitted
|
| 864 |
players = unified_get("players") or {}
|
| 865 |
if players.get(gid) and players[gid].get(uname):
|
| 866 |
players[gid][uname]['submitted'] = True
|
| 867 |
players[gid][uname]['submitted_at'] = now
|
| 868 |
players[gid][uname]['score'] = score
|
| 869 |
-
players[gid][uname]['percentage'] =
|
| 870 |
unified_set("players", players)
|
| 871 |
|
| 872 |
-
# Auto
|
| 873 |
if game.get('auto_close', True):
|
| 874 |
games[gid]['closed'] = True
|
| 875 |
games[gid]['closed_at'] = now
|
|
@@ -880,6 +913,7 @@ def play_page():
|
|
| 880 |
st.session_state['last_score'] = score
|
| 881 |
st.session_state['last_game'] = gid
|
| 882 |
st.session_state['current_index'] = 0
|
|
|
|
| 883 |
# ---------- PLAY PAGE ----------
|
| 884 |
|
| 885 |
# Create game
|
|
|
|
| 775 |
|
| 776 |
# ----------------------------
|
| 777 |
# Play Page
|
|
|
|
| 778 |
def play_page():
|
| 779 |
+
st.header("๐ฎ Play Game")
|
| 780 |
+
|
| 781 |
+
# โ
Ensure username
|
| 782 |
+
if "username" not in st.session_state or not st.session_state["username"]:
|
| 783 |
+
uname = st.text_input("Enter your username to play:", key="username_input")
|
| 784 |
+
if not uname:
|
| 785 |
+
st.info("Please enter a username to continue.")
|
| 786 |
+
return
|
| 787 |
+
st.session_state["username"] = uname
|
| 788 |
+
else:
|
| 789 |
+
uname = st.session_state["username"]
|
| 790 |
+
|
| 791 |
+
# โ
Ensure current game
|
| 792 |
+
if "current_game_id" not in st.session_state or not st.session_state["current_game_id"]:
|
| 793 |
+
# Fetch available games
|
| 794 |
+
games = unified_get("games") or {}
|
| 795 |
+
if not games:
|
| 796 |
+
st.info("No active games available. Please create a game first.")
|
| 797 |
+
return
|
| 798 |
+
|
| 799 |
+
game_options = [f"{g['game_id']} (Host: {g['host']})" for g in games.values()]
|
| 800 |
+
selected = st.selectbox("Select a game to join:", game_options)
|
| 801 |
+
|
| 802 |
+
if st.button("Join Game"):
|
| 803 |
+
gid = selected.split(" ")[0] # Extract game_id
|
| 804 |
+
st.session_state["current_game_id"] = gid
|
| 805 |
+
|
| 806 |
+
# Mark player as joined
|
| 807 |
+
players = unified_get("players") or {}
|
| 808 |
+
if gid not in players:
|
| 809 |
+
players[gid] = {}
|
| 810 |
+
players[gid][uname] = {"joined_at": datetime.utcnow().isoformat(), "submitted": False}
|
| 811 |
+
unified_set("players", players)
|
| 812 |
+
|
| 813 |
+
st.success(f"Joined game {gid} successfully!")
|
| 814 |
+
st.experimental_rerun()
|
| 815 |
+
else:
|
| 816 |
+
st.info("Select a game and click 'Join Game'.")
|
| 817 |
+
return
|
| 818 |
+
else:
|
| 819 |
+
gid = st.session_state["current_game_id"]
|
| 820 |
|
| 821 |
+
# โ
Fetch questions
|
| 822 |
games = unified_get("games") or {}
|
| 823 |
game = games.get(gid)
|
| 824 |
if not game:
|
| 825 |
+
st.error("Game not found. Please join a valid game.")
|
| 826 |
return
|
| 827 |
|
| 828 |
+
questions = st.session_state.get('game_questions') or game.get('questions', [])
|
| 829 |
if not questions:
|
| 830 |
+
st.error("No questions loaded for this game.")
|
| 831 |
return
|
| 832 |
|
| 833 |
+
# Timer setup
|
| 834 |
if 'question_started_at' not in st.session_state or st.session_state['question_started_at'] is None:
|
| 835 |
st.session_state['question_started_at'] = time.time()
|
| 836 |
|
| 837 |
idx = st.session_state.get('current_index', 0)
|
| 838 |
if idx >= len(questions):
|
| 839 |
+
st.success("All done โ submit your answers!")
|
| 840 |
return
|
| 841 |
|
| 842 |
q = questions[idx]
|
| 843 |
st.subheader(f"Question {idx+1}/{len(questions)}")
|
| 844 |
st.write(q["question"])
|
| 845 |
+
|
| 846 |
elapsed = int(time.time() - st.session_state['question_started_at'])
|
| 847 |
time_limit = 15
|
| 848 |
st.markdown(f"**Time left:** {max(0, time_limit - elapsed)} seconds")
|
|
|
|
| 851 |
|
| 852 |
col1, col2 = st.columns(2)
|
| 853 |
with col1:
|
| 854 |
+
if st.button("Next Question"):
|
| 855 |
+
# Save answer
|
| 856 |
+
answers = st.session_state.get('answers', [""] * len(questions))
|
| 857 |
+
times = st.session_state.get('answer_times', [None] * len(questions))
|
| 858 |
answers[idx] = choice
|
| 859 |
+
times[idx] = time.time() - st.session_state['question_started_at']
|
| 860 |
st.session_state['answers'] = answers
|
| 861 |
st.session_state['answer_times'] = times
|
| 862 |
+
|
| 863 |
st.session_state['current_index'] = idx + 1
|
| 864 |
st.session_state['question_started_at'] = time.time()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 865 |
st.experimental_rerun()
|
| 866 |
|
| 867 |
with col2:
|
| 868 |
+
if idx == len(questions)-1:
|
| 869 |
+
if st.button("Submit All Answers"):
|
| 870 |
+
answers = st.session_state.get('answers', [""] * len(questions))
|
| 871 |
+
times = st.session_state.get('answer_times', [None] * len(questions))
|
| 872 |
answers[idx] = choice
|
| 873 |
+
times[idx] = time.time() - st.session_state['question_started_at']
|
| 874 |
+
|
| 875 |
st.session_state['answers'] = answers
|
| 876 |
st.session_state['answer_times'] = times
|
| 877 |
|
| 878 |
+
# Compute score & save
|
| 879 |
score, flags = compute_score(questions, answers, times)
|
| 880 |
+
now = datetime.utcnow().isoformat()
|
| 881 |
+
avatar = "๐ฎ" # or fetch avatar
|
| 882 |
+
|
| 883 |
row = {
|
| 884 |
"name": uname,
|
| 885 |
"score": score,
|
|
|
|
| 889 |
"avatar": avatar,
|
| 890 |
"questions": " || ".join([q["question"] for q in questions]),
|
| 891 |
"answers": " || ".join([str(a) for a in answers]),
|
| 892 |
+
"correct_flags": " || ".join(flags)
|
|
|
|
| 893 |
}
|
| 894 |
unified_push_leaderboard(row)
|
| 895 |
|
| 896 |
+
# Mark player as submitted
|
| 897 |
players = unified_get("players") or {}
|
| 898 |
if players.get(gid) and players[gid].get(uname):
|
| 899 |
players[gid][uname]['submitted'] = True
|
| 900 |
players[gid][uname]['submitted_at'] = now
|
| 901 |
players[gid][uname]['score'] = score
|
| 902 |
+
players[gid][uname]['percentage'] = round((score / len(questions)) * 100, 2)
|
| 903 |
unified_set("players", players)
|
| 904 |
|
| 905 |
+
# Auto-close game
|
| 906 |
if game.get('auto_close', True):
|
| 907 |
games[gid]['closed'] = True
|
| 908 |
games[gid]['closed_at'] = now
|
|
|
|
| 913 |
st.session_state['last_score'] = score
|
| 914 |
st.session_state['last_game'] = gid
|
| 915 |
st.session_state['current_index'] = 0
|
| 916 |
+
|
| 917 |
# ---------- PLAY PAGE ----------
|
| 918 |
|
| 919 |
# Create game
|