Files changed (1) hide show
  1. app.py +57 -71
app.py CHANGED
@@ -776,118 +776,103 @@ def home_page():
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.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")
849
 
850
- choice = st.radio("Choose an answer:", q["options"], key=f"choice_{idx}")
 
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.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,
886
  "game_id": gid,
887
- "topics": ",".join(game.get('topics', [])),
888
  "timestamp": now,
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
  }
@@ -899,14 +884,15 @@ def play_page():
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
909
- unified_set("games", games)
 
 
910
 
911
  st.success(f"Submitted! Score: {score}")
912
  st.balloons()
 
776
  # ----------------------------
777
  # Play Page
778
  def play_page():
779
+ # Get active game and username
780
+ gid = st.session_state.get('active_game')
781
+ uname = st.session_state.get('username')
782
+ avatar = st.session_state.get('avatar', '๐ŸŽฎ')
783
 
784
+ if not gid or not uname:
785
+ st.warning("No active game or username found. Please join or create a game first.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
786
  return
787
 
788
+ # Load questions from session or game
789
+ questions = st.session_state.get('game_questions') or st.session_state.get('game_data', {}).get('questions', [])
790
  if not questions:
791
+ st.error("No questions loaded.")
792
  return
793
 
794
+ # Ensure timer exists
795
  if 'question_started_at' not in st.session_state or st.session_state['question_started_at'] is None:
796
  st.session_state['question_started_at'] = time.time()
797
 
798
+ # Current question index
799
  idx = st.session_state.get('current_index', 0)
800
  if idx >= len(questions):
801
+ st.success("All questions done โ€” submit!")
802
  return
803
 
804
+ # Get current question safely (dict or list)
805
  q = questions[idx]
806
+ if isinstance(q, dict):
807
+ question_text = q.get("question", "")
808
+ options = q.get("options", [])
809
+ elif isinstance(q, list):
810
+ # Assumes format: [question, options_list, answer]
811
+ question_text = q[0]
812
+ options = q[1]
813
+ else:
814
+ st.error(f"Invalid question format at index {idx}.")
815
+ return
816
+
817
  st.subheader(f"Question {idx+1}/{len(questions)}")
818
+ st.write(question_text)
819
 
820
+ # Timer
821
  elapsed = int(time.time() - st.session_state['question_started_at'])
822
  time_limit = 15
823
  st.markdown(f"**Time left:** {max(0, time_limit - elapsed)} seconds")
824
 
825
+ # Choice selection
826
+ choice = st.radio("Choose an answer:", options, key=f"choice_{idx}")
827
 
828
  col1, col2 = st.columns(2)
829
+
830
+ # Next button
831
  with col1:
832
+ if st.button("Next"):
833
+ taken = time.time() - st.session_state['question_started_at']
834
+
835
  answers = st.session_state.get('answers', [""] * len(questions))
836
  times = st.session_state.get('answer_times', [None] * len(questions))
837
+
838
  answers[idx] = choice
839
+ times[idx] = taken
840
+
841
  st.session_state['answers'] = answers
842
  st.session_state['answer_times'] = times
 
843
  st.session_state['current_index'] = idx + 1
844
+ st.session_state['question_started_at'] = time.time() # reset timer for next question
 
845
 
846
+ st.experimental_rerun()
847
+
848
+ # Submit button on last question
849
  with col2:
850
+ if idx == len(questions) - 1:
851
  if st.button("Submit All Answers"):
852
  answers = st.session_state.get('answers', [""] * len(questions))
853
  times = st.session_state.get('answer_times', [None] * len(questions))
854
+
855
+ # Save last answer
856
+ taken = time.time() - st.session_state.get('question_started_at', time.time())
857
  answers[idx] = choice
858
+ times[idx] = taken
859
 
860
  st.session_state['answers'] = answers
861
  st.session_state['answer_times'] = times
862
 
863
+ # Compute score (you already have this function)
864
  score, flags = compute_score(questions, answers, times)
865
+ now = now_iso()
 
866
 
867
+ # Push leaderboard
868
  row = {
869
  "name": uname,
870
  "score": score,
871
  "game_id": gid,
872
+ "topics": ",".join(st.session_state.get('game_data', {}).get('topics', [])),
873
  "timestamp": now,
874
  "avatar": avatar,
875
+ "questions": " || ".join([q[0] if isinstance(q, list) else q.get("question","") for q in questions]),
876
  "answers": " || ".join([str(a) for a in answers]),
877
  "correct_flags": " || ".join(flags)
878
  }
 
884
  players[gid][uname]['submitted'] = True
885
  players[gid][uname]['submitted_at'] = now
886
  players[gid][uname]['score'] = score
 
887
  unified_set("players", players)
888
 
889
+ # Auto-close game if enabled
890
+ games = unified_get("games") or {}
891
+ if st.session_state.get('game_data', {}).get('auto_close', True):
892
+ if gid in games:
893
+ games[gid]['closed'] = True
894
+ games[gid]['closed_at'] = now
895
+ unified_set("games", games)
896
 
897
  st.success(f"Submitted! Score: {score}")
898
  st.balloons()