feat(phase3): Implement complete game logic with WebSocket events
Timer System: - Add TimerManager service with asyncio for server-side timers - Support steal time reduction (50% time) - Automatic timer cancellation on answer Question Loading: - Add QuestionService to load daily questions from PostgreSQL - Generate 8×5 board (categories × difficulties) - Filter by date_active and approved status Database Integration: - Create GameSession in PostgreSQL when game starts - Update scores during game and on finish - Store db_session_id in Redis for cross-reference Replay Integration: - Save all game events: question_selected, answer_submitted, steal_attempted, steal_passed, game_finished - Generate unique replay code on game finish Achievement Integration: - Initialize PlayerStats in Redis when joining room - Update stats on every answer (streak, category, speed, etc.) - Check achievements on game finish for all players Game Finish: - Automatic finish when all questions answered - Manual finish by host - Emit game_finished with winner, scores, replay_code, achievements Phase 3 tasks completed: - F3.1: Timer manager with asyncio - F3.2: Question service for board loading - F3.3: GameSession PostgreSQL integration - F3.4: Replay event saving - F3.5: Achievement stats tracking - F3.6: Complete game finish flow Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -168,6 +168,38 @@ class RoomManager:
|
||||
return json.loads(data)
|
||||
return None
|
||||
|
||||
async def get_player_stats(self, room_code: str, player_name: str) -> Optional[dict]:
|
||||
"""Obtiene stats de un jugador."""
|
||||
await self.connect()
|
||||
data = await self.redis.get(f"stats:{room_code}:{player_name}")
|
||||
if data:
|
||||
return json.loads(data)
|
||||
return None
|
||||
|
||||
async def set_player_stats(self, room_code: str, player_name: str, stats: dict) -> None:
|
||||
"""Guarda stats de un jugador."""
|
||||
await self.connect()
|
||||
await self.redis.setex(
|
||||
f"stats:{room_code}:{player_name}",
|
||||
3600 * 3,
|
||||
json.dumps(stats)
|
||||
)
|
||||
|
||||
async def init_player_stats(self, room_code: str, player_name: str) -> dict:
|
||||
"""Inicializa stats para un nuevo jugador."""
|
||||
stats = {
|
||||
"player_name": player_name,
|
||||
"current_streak": 0,
|
||||
"total_correct": 0,
|
||||
"total_steals": 0,
|
||||
"successful_steals": 0,
|
||||
"category_correct": {},
|
||||
"fastest_answer_seconds": None,
|
||||
"questions_500_correct": 0
|
||||
}
|
||||
await self.set_player_stats(room_code, player_name, stats)
|
||||
return stats
|
||||
|
||||
|
||||
# Singleton instance
|
||||
room_manager = RoomManager()
|
||||
|
||||
Reference in New Issue
Block a user