Muthuraja18 commited on
Commit
84be4a2
·
verified ·
1 Parent(s): 3ce199f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -37
app.py CHANGED
@@ -607,22 +607,26 @@ def join_game(game_id, username, avatar):
607
  def compute_score(questions, answers, times):
608
  total = 0
609
  flags = []
 
610
  for i, q in enumerate(questions):
611
  ans = answers[i] if i < len(answers) else ""
612
- try:
613
- correct = str(ans).strip().lower() == str(q[2]).strip().lower()
614
- except Exception:
615
- correct = False
 
616
  if correct:
617
  base = 10
618
  t = times[i] if i < len(times) and times[i] else 999
619
- bonus = max(0, int((max(0, 15 - min(t,15)) / 15) * 5))
620
  total += base + bonus
621
  flags.append("Yes")
622
  else:
623
  flags.append("No")
 
624
  return total, flags
625
 
 
626
  # ----------------- UI -----------------
627
  st.sidebar.title("Mode & Profile")
628
  mode_choice = st.sidebar.selectbox("Mode", ["Offline (local JSON)", "Online (Firebase)"], index=0)
@@ -788,26 +792,32 @@ if 'username' not in st.session_state:
788
 
789
  def create_game(host=None, topics=[], num_questions=5, auto_close=True, ai_topic=None):
790
  games = unified_get("games") or {}
791
- gid = f"GAME{int(time.time())}" # simple unique id
792
  host = host or st.session_state.get("username", "Host")
793
 
794
- # 🔹 Get questions
795
  questions = []
796
 
797
- # 1️⃣ AI questions if topic given
798
  if ai_topic:
799
  ai_questions = generate_ai_questions(ai_topic, num_questions=num_questions)
800
  if ai_questions:
801
- questions = ai_questions
 
 
 
 
 
802
 
803
- # 2️⃣ Fallback to static questions_db
804
  if not questions:
805
  for topic in topics:
806
- qs = questions_db.get(topic.lower(), questions_db.get("default", []))
807
- questions.extend(qs[:num_questions])
808
-
809
- # Ensure each question is a dict with keys: question, options, answer
810
- questions = [{"question": q["question"], "options": q["options"], "answer": q["answer"]} for q in questions]
 
 
811
 
812
  # 🔹 Store game
813
  games[gid] = {
@@ -819,16 +829,31 @@ def create_game(host=None, topics=[], num_questions=5, auto_close=True, ai_topic
819
  "closed": False,
820
  "auto_close": auto_close
821
  }
 
822
  unified_set("games", games)
 
 
 
 
 
 
 
 
 
 
823
  st.success(f"Game created: {gid} with {len(questions)} questions.")
824
  return gid
825
 
 
 
 
826
  # -------------------------
827
  # PLAY PAGE
828
  # -------------------------
829
  def play_page():
830
  gid = st.session_state.get("active_game_id")
831
  uname = st.session_state.get("username")
 
832
  if not gid or not uname:
833
  st.error("No active game or username found. Please join or create a game first.")
834
  return
@@ -844,15 +869,26 @@ def play_page():
844
  st.error("No questions loaded.")
845
  return
846
 
847
- # Ensure timer exists
 
 
 
 
 
 
 
 
 
848
  if 'question_started_at' not in st.session_state or st.session_state['question_started_at'] is None:
849
  st.session_state['question_started_at'] = time.time()
850
 
851
- idx = st.session_state.get('current_index', 0)
 
852
  if idx >= len(questions):
853
  st.success("All done — submit your answers!")
854
  return
855
 
 
856
  q = questions[idx]
857
  st.subheader(f"Question {idx+1}/{len(questions)}")
858
  st.write(q["question"])
@@ -861,36 +897,49 @@ def play_page():
861
  time_limit = 15
862
  st.markdown(f"**Time left:** {max(0, time_limit - elapsed)} seconds")
863
 
864
- choice = st.radio("Choose an answer:", q["options"], key=f"choice_{idx}")
 
 
 
 
 
865
 
866
  col1, col2 = st.columns(2)
867
 
 
868
  with col1:
869
- if st.button("Next", key=f"next_{idx}"):
870
  taken = time.time() - st.session_state['question_started_at']
871
- answers = st.session_state.get('answers', [""] * len(questions))
872
- times = st.session_state.get('answer_times', [None] * len(questions))
 
 
873
  answers[idx] = choice
874
  times[idx] = taken
875
- st.session_state['answers'] = answers
876
- st.session_state['answer_times'] = times
877
  st.session_state['current_index'] = idx + 1
878
  st.session_state['question_started_at'] = time.time()
879
- st.experimental_rerun()
880
 
 
881
  with col2:
882
- if idx == len(questions)-1:
883
- if st.button("Submit All Answers", key=f"submit_{idx}"):
884
- answers = st.session_state.get('answers', [""]*len(questions))
885
- times = st.session_state.get('answer_times', [None]*len(questions))
 
 
886
  answers[idx] = choice
887
- times[idx] = time.time() - st.session_state.get('question_started_at', time.time())
888
- st.session_state['answers'] = answers
889
- st.session_state['answer_times'] = times
 
 
 
 
 
890
 
891
- # Compute score
892
- score = sum([1 for i,q in enumerate(questions) if answers[i] == q["answer"]])
893
- percentage = int(score / len(questions) * 100)
894
 
895
  # Update players
896
  players = unified_get("players") or {}
@@ -911,11 +960,16 @@ def play_page():
911
  games[gid]['closed_at'] = now_iso()
912
  unified_set("games", games)
913
 
914
- st.success(f"Submitted! Score: {score} / {len(questions)} ({percentage}%)")
 
 
915
  st.balloons()
 
916
  st.session_state['last_score'] = score
917
  st.session_state['last_game'] = gid
918
  st.session_state['current_index'] = 0
 
 
919
  # Join game
920
  def join_game_page():
921
  st.header("Join Game")
@@ -933,20 +987,32 @@ def join_game_page():
933
  if ok:
934
  st.success(f"Joined game {game_id} successfully!")
935
 
936
- # Safe way to get questions
937
  games = unified_get("games") or {}
938
  g = games.get(game_id, {})
939
 
940
- # Ensure 'questions' key exists
941
  st.session_state['game_questions'] = g.get('questions', [])
942
 
 
943
  st.session_state['game_id'] = game_id
 
 
 
 
 
 
 
 
944
  st.session_state['username'] = username
945
  st.session_state['avatar'] = avatar
 
 
946
  else:
947
  st.error(msg)
948
 
949
 
 
950
  # Play page
951
  # ----------------- Create Game -----------------
952
 
 
607
  def compute_score(questions, answers, times):
608
  total = 0
609
  flags = []
610
+
611
  for i, q in enumerate(questions):
612
  ans = answers[i] if i < len(answers) else ""
613
+
614
+ correct_ans = q.get("answer", "")
615
+
616
+ correct = str(ans).strip().lower() == str(correct_ans).strip().lower()
617
+
618
  if correct:
619
  base = 10
620
  t = times[i] if i < len(times) and times[i] else 999
621
+ bonus = max(0, int((max(0, 15 - min(t, 15)) / 15) * 5))
622
  total += base + bonus
623
  flags.append("Yes")
624
  else:
625
  flags.append("No")
626
+
627
  return total, flags
628
 
629
+
630
  # ----------------- UI -----------------
631
  st.sidebar.title("Mode & Profile")
632
  mode_choice = st.sidebar.selectbox("Mode", ["Offline (local JSON)", "Online (Firebase)"], index=0)
 
792
 
793
  def create_game(host=None, topics=[], num_questions=5, auto_close=True, ai_topic=None):
794
  games = unified_get("games") or {}
795
+ gid = f"GAME{int(time.time())}"
796
  host = host or st.session_state.get("username", "Host")
797
 
 
798
  questions = []
799
 
800
+ # 1️⃣ AI questions (already dict format)
801
  if ai_topic:
802
  ai_questions = generate_ai_questions(ai_topic, num_questions=num_questions)
803
  if ai_questions:
804
+ for q in ai_questions:
805
+ questions.append({
806
+ "question": q.get("question", ""),
807
+ "options": q.get("options", []),
808
+ "answer": q.get("answer", "")
809
+ })
810
 
811
+ # 2️⃣ Static fallback (tuple → dict conversion)
812
  if not questions:
813
  for topic in topics:
814
+ qs = questions_db.get(topic, [])
815
+ for q in qs[:num_questions]:
816
+ questions.append({
817
+ "question": q[0],
818
+ "options": q[1],
819
+ "answer": q[2]
820
+ })
821
 
822
  # 🔹 Store game
823
  games[gid] = {
 
829
  "closed": False,
830
  "auto_close": auto_close
831
  }
832
+
833
  unified_set("games", games)
834
+
835
+ # ✅ REQUIRED: prepare play state
836
+ st.session_state['game_id'] = gid
837
+ st.session_state['active_game_id'] = gid
838
+ st.session_state['game_questions'] = questions
839
+ st.session_state['current_index'] = 0
840
+ st.session_state['answers'] = [""] * len(questions)
841
+ st.session_state['answer_times'] = [None] * len(questions)
842
+ st.session_state['question_started_at'] = None
843
+
844
  st.success(f"Game created: {gid} with {len(questions)} questions.")
845
  return gid
846
 
847
+
848
+
849
+
850
  # -------------------------
851
  # PLAY PAGE
852
  # -------------------------
853
  def play_page():
854
  gid = st.session_state.get("active_game_id")
855
  uname = st.session_state.get("username")
856
+
857
  if not gid or not uname:
858
  st.error("No active game or username found. Please join or create a game first.")
859
  return
 
869
  st.error("No questions loaded.")
870
  return
871
 
872
+ # ---------------- FIX 3 : SAFE SESSION INIT ----------------
873
+ if 'current_index' not in st.session_state or st.session_state['current_index'] is None:
874
+ st.session_state['current_index'] = 0
875
+
876
+ if 'answers' not in st.session_state or len(st.session_state['answers']) != len(questions):
877
+ st.session_state['answers'] = [""] * len(questions)
878
+
879
+ if 'answer_times' not in st.session_state or len(st.session_state['answer_times']) != len(questions):
880
+ st.session_state['answer_times'] = [None] * len(questions)
881
+
882
  if 'question_started_at' not in st.session_state or st.session_state['question_started_at'] is None:
883
  st.session_state['question_started_at'] = time.time()
884
 
885
+ idx = st.session_state['current_index']
886
+
887
  if idx >= len(questions):
888
  st.success("All done — submit your answers!")
889
  return
890
 
891
+ # ---------------- QUESTION UI ----------------
892
  q = questions[idx]
893
  st.subheader(f"Question {idx+1}/{len(questions)}")
894
  st.write(q["question"])
 
897
  time_limit = 15
898
  st.markdown(f"**Time left:** {max(0, time_limit - elapsed)} seconds")
899
 
900
+ # ---------------- FIX 4 : STABLE RADIO ----------------
901
+ choice = st.radio(
902
+ "Choose an answer:",
903
+ q["options"],
904
+ key=f"choice_{gid}_{idx}"
905
+ )
906
 
907
  col1, col2 = st.columns(2)
908
 
909
+ # ---------------- NEXT ----------------
910
  with col1:
911
+ if st.button("Next", key=f"next_{gid}_{idx}"):
912
  taken = time.time() - st.session_state['question_started_at']
913
+
914
+ answers = st.session_state['answers']
915
+ times = st.session_state['answer_times']
916
+
917
  answers[idx] = choice
918
  times[idx] = taken
919
+
 
920
  st.session_state['current_index'] = idx + 1
921
  st.session_state['question_started_at'] = time.time()
922
+ st.rerun()
923
 
924
+ # ---------------- SUBMIT ----------------
925
  with col2:
926
+ if idx == len(questions) - 1:
927
+ if st.button("Submit All Answers", key=f"submit_{gid}_{idx}"):
928
+
929
+ answers = st.session_state['answers']
930
+ times = st.session_state['answer_times']
931
+
932
  answers[idx] = choice
933
+ times[idx] = time.time() - st.session_state['question_started_at']
934
+
935
+ # ---------------- FIX 5 : CORRECT SCORING ----------------
936
+ score, flags = compute_score(
937
+ questions,
938
+ answers,
939
+ times
940
+ )
941
 
942
+ percentage = int(score / (len(questions) * 15) * 100)
 
 
943
 
944
  # Update players
945
  players = unified_get("players") or {}
 
960
  games[gid]['closed_at'] = now_iso()
961
  unified_set("games", games)
962
 
963
+ st.success(
964
+ f"Submitted! Score: {score} / {len(questions) * 15} ({percentage}%)"
965
+ )
966
  st.balloons()
967
+
968
  st.session_state['last_score'] = score
969
  st.session_state['last_game'] = gid
970
  st.session_state['current_index'] = 0
971
+
972
+
973
  # Join game
974
  def join_game_page():
975
  st.header("Join Game")
 
987
  if ok:
988
  st.success(f"Joined game {game_id} successfully!")
989
 
990
+ # Load game safely
991
  games = unified_get("games") or {}
992
  g = games.get(game_id, {})
993
 
994
+ # REQUIRED: set questions
995
  st.session_state['game_questions'] = g.get('questions', [])
996
 
997
+ # ✅ REQUIRED: set BOTH ids
998
  st.session_state['game_id'] = game_id
999
+ st.session_state['active_game_id'] = game_id
1000
+
1001
+ # ✅ REQUIRED: reset play state (prevents stored answer bugs)
1002
+ st.session_state['current_index'] = 0
1003
+ st.session_state['answers'] = [""] * len(st.session_state['game_questions'])
1004
+ st.session_state['answer_times'] = [None] * len(st.session_state['game_questions'])
1005
+ st.session_state['question_started_at'] = None
1006
+
1007
  st.session_state['username'] = username
1008
  st.session_state['avatar'] = avatar
1009
+
1010
+ st.rerun()
1011
  else:
1012
  st.error(msg)
1013
 
1014
 
1015
+
1016
  # Play page
1017
  # ----------------- Create Game -----------------
1018