diff --git a/lobby/views.py b/lobby/views.py index 222fe1e..6a44c9d 100644 --- a/lobby/views.py +++ b/lobby/views.py @@ -116,78 +116,6 @@ def _build_finish_game_response(session: GameSession) -> JsonResponse: ) -def _get_current_round_question(session: GameSession) -> RoundQuestion | None: - return ( - RoundQuestion.objects.filter(session=session, round_number=session.current_round) - .select_related("question") - .order_by("-id") - .first() - ) - - - -def _select_round_question(session: GameSession, round_config: RoundConfig) -> RoundQuestion: - existing_round_question = _get_current_round_question(session) - if existing_round_question is not None: - return existing_round_question - - used_question_ids = RoundQuestion.objects.filter(session=session).values_list("question_id", flat=True) - available_questions = Question.objects.filter( - category=round_config.category, - is_active=True, - ).exclude(pk__in=used_question_ids) - - if not available_questions.exists(): - raise ValueError("no_available_questions") - - question = random.choice(list(available_questions)) - return RoundQuestion.objects.create( - session=session, - round_number=session.current_round, - question=question, - correct_answer=question.correct_answer, - ) - - - -def _build_lie_started_payload(session: GameSession, round_config: RoundConfig, round_question: RoundQuestion) -> dict: - lie_deadline_at = round_question.shown_at + timedelta(seconds=round_config.lie_seconds) - return { - "round_number": session.current_round, - "category": {"slug": round_config.category.slug, "name": round_config.category.name}, - "round_question_id": round_question.id, - "prompt": round_question.question.prompt, - "shown_at": round_question.shown_at.isoformat(), - "lie_deadline_at": lie_deadline_at.isoformat(), - "lie_seconds": round_config.lie_seconds, - } - - - -def _prepare_mixed_answers(round_question: RoundQuestion) -> list[str]: - deduped_answers = list(round_question.mixed_answers or []) - if deduped_answers: - return deduped_answers - - lie_texts = list(round_question.lies.values_list("text", flat=True)) - seen = set() - for text in [round_question.correct_answer, *lie_texts]: - normalized = text.strip().casefold() - if not normalized or normalized in seen: - continue - seen.add(normalized) - deduped_answers.append(text.strip()) - - if len(deduped_answers) < 2: - raise ValueError("not_enough_answers_to_mix") - - random.shuffle(deduped_answers) - round_question.mixed_answers = deduped_answers - round_question.save(update_fields=["mixed_answers"]) - return deduped_answers - - - def _reset_round_question_bootstrap_state(round_question: RoundQuestion) -> RoundQuestion: Guess.objects.filter(round_question=round_question).delete() LieAnswer.objects.filter(round_question=round_question).delete() @@ -198,50 +126,6 @@ def _reset_round_question_bootstrap_state(round_question: RoundQuestion) -> Roun -def _resolve_scores(session: GameSession, round_question: RoundQuestion, round_config: RoundConfig) -> tuple[list[ScoreEvent], list[dict]]: - guesses = list(round_question.guesses.select_related("player")) - if not guesses: - raise ValueError("no_guesses_submitted") - - bluff_counts: dict[int, int] = {} - for guess in guesses: - if guess.fooled_player_id: - bluff_counts[guess.fooled_player_id] = bluff_counts.get(guess.fooled_player_id, 0) + 1 - - score_events = [] - - for guess in guesses: - if guess.is_correct: - guess.player.score += round_config.points_correct - guess.player.save(update_fields=["score"]) - score_events.append( - ScoreEvent( - session=session, - player=guess.player, - delta=round_config.points_correct, - reason="guess_correct", - meta={"round_question_id": round_question.id, "guess_id": guess.id}, - ) - ) - - for player_id, fooled_count in bluff_counts.items(): - delta = fooled_count * round_config.points_bluff - player = Player.objects.get(pk=player_id, session=session) - player.score += delta - player.save(update_fields=["score"]) - score_events.append( - ScoreEvent( - session=session, - player=player, - delta=delta, - reason="bluff_success", - meta={"round_question_id": round_question.id, "fooled_count": fooled_count}, - ) - ) - - ScoreEvent.objects.bulk_create(score_events) - return score_events, _build_leaderboard(session) - def _maybe_promote_reveal_to_scoreboard(session: GameSession) -> GameSession: if session.status != GameSession.Status.REVEAL: return session