feat: sistema de 2 rondas con puntos dobles

Ronda 1: 5 categorías con puntos normales (100-500)
Ronda 2: 5 categorías diferentes con puntos x2 (200-1000)

Backend:
- question_service: soporta excluir categorías y multiplicador de puntos
- game_manager: trackea current_round, start_round_2() carga nuevo tablero
- game_events: emite round_started al completar ronda 1

Frontend:
- useSocket: escucha evento round_started
- Game.tsx: muestra indicador de ronda actual
- types: GameRoom incluye current_round

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-27 02:28:28 +00:00
parent e017c5804c
commit be5b1775a0
6 changed files with 151 additions and 10 deletions

View File

@@ -85,6 +85,14 @@ export function useSocket() {
soundPlayer.play('game_start', volume)
})
socket.on('round_started', (data: { room: GameRoom; round: number; message: string }) => {
setRoom(data.room)
setCurrentQuestion(null)
// Play sound for new round
const volume = useSoundStore.getState().volume
soundPlayer.play('game_start', volume)
})
socket.on('question_selected', (data: { room: GameRoom; question_id: number }) => {
setRoom(data.room)
// Find the question in the board and set it as current

View File

@@ -157,7 +157,7 @@ export default function Game() {
return (
<div className="min-h-screen p-2 md:p-4 overflow-hidden" style={styles.bgPrimary}>
<div className="max-w-7xl mx-auto">
{/* Header with Room Code */}
{/* Header with Room Code and Round */}
<div className="text-center mb-4">
<motion.h1
initial={{ y: -20, opacity: 0 }}
@@ -167,8 +167,21 @@ export default function Game() {
>
TRIVY
</motion.h1>
<div className="text-xs opacity-60" style={{ color: config.colors.textMuted }}>
Sala: {room.code}
<div className="flex items-center justify-center gap-3 text-xs" style={{ color: config.colors.textMuted }}>
<span className="opacity-60">Sala: {room.code}</span>
<span className="opacity-40">|</span>
<motion.span
key={room.current_round}
initial={{ scale: 1.5, color: config.colors.accent }}
animate={{ scale: 1, color: config.colors.textMuted }}
className="font-bold"
style={{
color: room.current_round === 2 ? config.colors.accent : config.colors.textMuted
}}
>
Ronda {room.current_round || 1}
{room.current_round === 2 && ' (x2)'}
</motion.span>
</div>
</div>

View File

@@ -45,6 +45,7 @@ export interface GameRoom {
can_steal: boolean
scores: { A: number; B: number }
board: Record<string, Question[]>
current_round?: number
}
export interface ChatMessage {