feat: add unified contest pool and realtime game modes

This commit is contained in:
2026-08-10 00:31:21 +08:00
parent 97ca20413e
commit 40e9462842
18 changed files with 822 additions and 152 deletions
+14 -4
View File
@@ -57,6 +57,7 @@ def _grid_from_text(value):
def game_payload(attempt):
return {
"attempt_id": attempt.id,
"match_id": attempt.match_id,
"kind": attempt.kind,
"difficulty": attempt.difficulty,
"status": attempt.status,
@@ -68,7 +69,7 @@ def game_payload(attempt):
}
def start_game(user, kind, difficulty):
def build_game(kind, difficulty=MathGameAttempt.Difficulty.STANDARD):
if kind not in MathGameAttempt.Kind.values:
raise ValidationError({"kind": "不支持的数学玩法"})
if difficulty not in MathGameAttempt.Difficulty.values:
@@ -82,6 +83,11 @@ def start_game(user, kind, difficulty):
secrets.SystemRandom().shuffle(numbers)
puzzle = {"numbers": numbers}
solution = {"target": 24}
return puzzle, solution
def start_game(user, kind, difficulty=MathGameAttempt.Difficulty.STANDARD):
puzzle, solution = build_game(kind, difficulty)
attempt = MathGameAttempt.objects.create(
user=user,
kind=kind,
@@ -164,10 +170,14 @@ def _validate_sudoku_grid(raw_grid, puzzle, solution):
@transaction.atomic
def submit_game(user, attempt_id, submission, submission_key):
attempt = MathGameAttempt.objects.select_for_update().get(id=attempt_id, user=user)
if attempt.status == MathGameAttempt.Status.COMPLETED:
if submission_key and attempt.submission_key == submission_key:
if attempt.status != MathGameAttempt.Status.ACTIVE:
if (
attempt.status == MathGameAttempt.Status.COMPLETED
and submission_key
and attempt.submission_key == submission_key
):
return game_payload(attempt)
raise ValidationError("这局游戏已经完成")
raise ValidationError("这局游戏已经结束")
if not submission_key:
raise ValidationError({"Idempotency-Key": "提交必须提供幂等键"})