Files changed (1) hide show
  1. app.py +41 -37
app.py CHANGED
@@ -883,40 +883,42 @@ def join_game_page():
883
 
884
  # ----------------- Play Page -----------------
885
  def play_page():
886
- st.header("Play")
887
- gid = st.session_state.get('game_id')
888
  uname = st.session_state.get('username')
889
- avatar = st.session_state.get('avatar','🎮')
890
- if not gid or not uname:
891
- st.info("Join a game first.")
892
- return
893
 
894
- ok, msg = claim_session_unified(gid, uname)
895
- if not ok:
896
- st.error(msg)
897
  return
898
 
899
- heartbeat_unified(gid, uname)
900
-
901
  games = unified_get("games") or {}
902
  game = games.get(gid)
903
  if not game:
904
  st.error("Game not found.")
905
  return
906
- if game.get('closed'):
907
- st.error("Game closed.")
908
- return
909
 
910
- # Ensure questions exist
911
  questions = st.session_state.get('game_questions') or game.get('questions', [])
912
  if not questions:
913
  st.error("No questions loaded.")
914
  return
915
 
916
- # Ensure timer exists
 
 
 
 
 
 
 
 
 
 
917
  if 'question_started_at' not in st.session_state or st.session_state['question_started_at'] is None:
918
  st.session_state['question_started_at'] = time.time()
919
 
 
920
  idx = st.session_state.get('current_index', 0)
921
  if idx >= len(questions):
922
  st.success("All done — submit!")
@@ -930,79 +932,81 @@ def play_page():
930
  time_limit = 15
931
  st.markdown(f"**Time left:** {max(0, time_limit - elapsed)} seconds")
932
 
 
933
  choice = st.radio("Choose an answer:", q["options"], key=f"choice_{idx}")
934
 
935
-
936
  col1, col2 = st.columns(2)
937
 
 
938
  with col1:
939
  if st.button("Next"):
940
- taken = time.time() - st.session_state.get('question_started_at', time.time())
941
-
942
  answers = st.session_state.get('answers', [""] * len(questions))
943
  times = st.session_state.get('answer_times', [None] * len(questions))
944
-
945
  answers[idx] = choice
946
  times[idx] = taken
947
-
948
  st.session_state['answers'] = answers
949
  st.session_state['answer_times'] = times
950
  st.session_state['current_index'] = idx + 1
 
951
 
952
- # Do NOT reset question_started_at to None
953
- st.session_state['question_started_at'] = time.time() # reset for next question
954
-
955
  players = unified_get("players") or {}
956
  if players.get(gid, {}).get(uname):
957
  players[gid][uname]['last_heartbeat'] = now_iso()
958
  unified_set("players", players)
959
-
960
  heartbeat_unified(gid, uname)
961
  st.rerun()
962
 
 
963
  with col2:
964
- if idx == len(questions)-1:
965
  if st.button("Submit All Answers"):
966
- answers = st.session_state.get('answers', [""]*len(questions))
967
- times = st.session_state.get('answer_times', [None]*len(questions))
 
968
  answers[idx] = choice
969
- times[idx] = time.time() - st.session_state.get('question_started_at', time.time())
970
  st.session_state['answers'] = answers
971
  st.session_state['answer_times'] = times
 
 
972
  score, flags = compute_score(questions, answers, times)
973
  now = now_iso()
974
  row = {
975
  "name": uname,
976
  "score": score,
977
  "game_id": gid,
978
- "topics": ",".join(game.get('topics',[])),
979
  "timestamp": now,
980
  "avatar": avatar,
981
  "questions": " || ".join([q["question"] for q in questions]),
982
  "answers": " || ".join([str(a) for a in answers]),
983
- "correct_flags": " || ".join(flags)
 
984
  }
985
  unified_push_leaderboard(row)
986
- players[gid][uname]['score'] = score
987
- players[gid][uname]['percentage'] = round((score / len(questions)) * 100, 2)
988
  players = unified_get("players") or {}
989
  if players.get(gid) and players[gid].get(uname):
990
  players[gid][uname]['submitted'] = True
991
  players[gid][uname]['submitted_at'] = now
992
  players[gid][uname]['score'] = score
993
- players[gid][uname]['percentage'] = round((score / len(questions)) * 100, 2)
994
  unified_set("players", players)
 
 
995
  if game.get('auto_close', True):
996
- games = unified_get("games") or {}
997
  games[gid]['closed_at'] = now
998
  unified_set("games", games)
 
999
  st.success(f"Submitted! Score: {score}")
1000
  st.balloons()
1001
  st.session_state['last_score'] = score
1002
  st.session_state['last_game'] = gid
1003
  st.session_state['current_index'] = 0
1004
- st.rerun()
1005
-
1006
  # Friends page
1007
  def friends_page():
1008
  st.header("Friends")
 
883
 
884
  # ----------------- Play Page -----------------
885
  def play_page():
886
+ # Fetch game info
887
+ gid = st.session_state.get('current_game_id')
888
  uname = st.session_state.get('username')
889
+ avatar = st.session_state.get('avatar', '🎮')
 
 
 
890
 
891
+ if not gid or not uname:
892
+ st.error("No active game or username found.")
 
893
  return
894
 
 
 
895
  games = unified_get("games") or {}
896
  game = games.get(gid)
897
  if not game:
898
  st.error("Game not found.")
899
  return
 
 
 
900
 
901
+ # Load questions
902
  questions = st.session_state.get('game_questions') or game.get('questions', [])
903
  if not questions:
904
  st.error("No questions loaded.")
905
  return
906
 
907
+ # Normalize questions to dict format
908
+ for i, q in enumerate(questions):
909
+ if isinstance(q, list) or isinstance(q, tuple):
910
+ questions[i] = {
911
+ "question": q[0],
912
+ "options": q[1],
913
+ "answer": q[2] if len(q) > 2 else ""
914
+ }
915
+ st.session_state['game_questions'] = questions
916
+
917
+ # Initialize timer
918
  if 'question_started_at' not in st.session_state or st.session_state['question_started_at'] is None:
919
  st.session_state['question_started_at'] = time.time()
920
 
921
+ # Current question index
922
  idx = st.session_state.get('current_index', 0)
923
  if idx >= len(questions):
924
  st.success("All done — submit!")
 
932
  time_limit = 15
933
  st.markdown(f"**Time left:** {max(0, time_limit - elapsed)} seconds")
934
 
935
+ # Choice selection
936
  choice = st.radio("Choose an answer:", q["options"], key=f"choice_{idx}")
937
 
 
938
  col1, col2 = st.columns(2)
939
 
940
+ # NEXT button
941
  with col1:
942
  if st.button("Next"):
943
+ taken = time.time() - st.session_state['question_started_at']
 
944
  answers = st.session_state.get('answers', [""] * len(questions))
945
  times = st.session_state.get('answer_times', [None] * len(questions))
 
946
  answers[idx] = choice
947
  times[idx] = taken
 
948
  st.session_state['answers'] = answers
949
  st.session_state['answer_times'] = times
950
  st.session_state['current_index'] = idx + 1
951
+ st.session_state['question_started_at'] = time.time() # reset timer
952
 
953
+ # Update heartbeat
 
 
954
  players = unified_get("players") or {}
955
  if players.get(gid, {}).get(uname):
956
  players[gid][uname]['last_heartbeat'] = now_iso()
957
  unified_set("players", players)
 
958
  heartbeat_unified(gid, uname)
959
  st.rerun()
960
 
961
+ # SUBMIT ALL button
962
  with col2:
963
+ if idx == len(questions) - 1:
964
  if st.button("Submit All Answers"):
965
+ taken = time.time() - st.session_state.get('question_started_at', time.time())
966
+ answers = st.session_state.get('answers', [""] * len(questions))
967
+ times = st.session_state.get('answer_times', [None] * len(questions))
968
  answers[idx] = choice
969
+ times[idx] = taken
970
  st.session_state['answers'] = answers
971
  st.session_state['answer_times'] = times
972
+
973
+ # Compute score
974
  score, flags = compute_score(questions, answers, times)
975
  now = now_iso()
976
  row = {
977
  "name": uname,
978
  "score": score,
979
  "game_id": gid,
980
+ "topics": ",".join(game.get('topics', [])),
981
  "timestamp": now,
982
  "avatar": avatar,
983
  "questions": " || ".join([q["question"] for q in questions]),
984
  "answers": " || ".join([str(a) for a in answers]),
985
+ "correct_flags": " || ".join(flags),
986
+ "percentage": round(score / len(questions) * 100, 2)
987
  }
988
  unified_push_leaderboard(row)
989
+
990
+ # Update player submission
991
  players = unified_get("players") or {}
992
  if players.get(gid) and players[gid].get(uname):
993
  players[gid][uname]['submitted'] = True
994
  players[gid][uname]['submitted_at'] = now
995
  players[gid][uname]['score'] = score
996
+ players[gid][uname]['percentage'] = round(score / len(questions) * 100, 2)
997
  unified_set("players", players)
998
+
999
+ # Auto-close game if enabled
1000
  if game.get('auto_close', True):
1001
+ games[gid]['closed'] = True
1002
  games[gid]['closed_at'] = now
1003
  unified_set("games", games)
1004
+
1005
  st.success(f"Submitted! Score: {score}")
1006
  st.balloons()
1007
  st.session_state['last_score'] = score
1008
  st.session_state['last_game'] = gid
1009
  st.session_state['current_index'] = 0
 
 
1010
  # Friends page
1011
  def friends_page():
1012
  st.header("Friends")