diff --git a/apps/server/src/game/engine.test.ts b/apps/server/src/game/engine.test.ts index cb8f010..991b29d 100644 --- a/apps/server/src/game/engine.test.ts +++ b/apps/server/src/game/engine.test.ts @@ -46,7 +46,7 @@ const dummyRound: GameRound = { } return deltas }, - recap: () => ({ label: "2+2 ?", answer: "4" }), + recap: () => ({ label: "2+2 ?", answer: "4", answers: [] }), } function setup(roundDurationSec: number): { diff --git a/apps/server/src/game/modes/blindtest/blindtest-round.ts b/apps/server/src/game/modes/blindtest/blindtest-round.ts index 70ae6b6..20a46c9 100644 --- a/apps/server/src/game/modes/blindtest/blindtest-round.ts +++ b/apps/server/src/game/modes/blindtest/blindtest-round.ts @@ -160,13 +160,43 @@ export class BlindtestRound implements GameRound { recap(ctx: RoundContext): RoundRecapInfo { const { track } = ctx.data as BlindtestRoundData + const mode = ctx.room.settings.blindtestMode const submitter = ctx.room.players.get(track.submittedBy) + const nameOf = (id?: string) => + (id && ctx.room.players.get(id)?.name) || "?" + + const answers = [] + for (const [playerId, vote] of ctx.votes) { + if (playerId === track.submittedBy) { + continue + } + const a = vote as { + title?: string + artist?: string + guessedPlayerId?: string + } + let text = "" + if (mode === "who_added") { + text = nameOf(a.guessedPlayerId) + } else if (mode === "title_artist") { + text = `${a.title ?? ""} / ${a.artist ?? ""}` + } else { + text = `${a.title ?? ""} / ${a.artist ?? ""} → ${nameOf(a.guessedPlayerId)}` + } + answers.push({ + playerId, + answer: text, + correct: voterResult(mode, vote, track).points > 0, + }) + } + return { label: "Blindtest", answer: `${track.title} — ${track.artist}`, youtubeId: track.youtubeId, url: track.url, addedBy: submitter?.name ?? "?", + answers, } } } diff --git a/apps/server/src/game/modes/quiz/quiz-round.ts b/apps/server/src/game/modes/quiz/quiz-round.ts index 056f138..54250a1 100644 --- a/apps/server/src/game/modes/quiz/quiz-round.ts +++ b/apps/server/src/game/modes/quiz/quiz-round.ts @@ -152,12 +152,28 @@ export class QuizRound implements GameRound { const answer = isTextFormat(question) ? (question.acceptedAnswers?.[0] ?? "") : (question.choices?.[question.correctIndex ?? 0] ?? "") + const answers = [] + for (const player of ctx.room.players.values()) { + const vote = ctx.votes.get(player.id) + if (!vote) { + continue + } + const text = isTextFormat(question) + ? (asText(vote) ?? "") + : (question.choices?.[asChoice(vote) ?? -1] ?? "?") + answers.push({ + playerId: player.id, + answer: text, + correct: isCorrect(question, vote), + }) + } return { label: question.prompt, answer, category: question.category, imageUrl: question.format === "image_reveal" ? question.imageUrl : undefined, + answers, } } } diff --git a/apps/web/src/components/game-end-view.tsx b/apps/web/src/components/game-end-view.tsx index c232202..1434dab 100644 --- a/apps/web/src/components/game-end-view.tsx +++ b/apps/web/src/components/game-end-view.tsx @@ -332,47 +332,72 @@ function RoundsRecap({ Récapitulatif des manches ({recap.length}) ) diff --git a/packages/shared/src/domain.ts b/packages/shared/src/domain.ts index a460365..8afd99e 100644 --- a/packages/shared/src/domain.ts +++ b/packages/shared/src/domain.ts @@ -90,6 +90,13 @@ export interface RoundRecapScorer { points: number } +/** Réponse d'un joueur sur une manche (récap). */ +export interface RoundPlayerAnswer { + playerId: string + answer: string + correct: boolean +} + /** Récapitulatif d'une manche jouée (affiché en fin de partie). */ export interface RoundRecap { index: number @@ -106,6 +113,8 @@ export interface RoundRecap { addedBy?: string /** Joueurs ayant marqué sur cette manche. */ scorers: RoundRecapScorer[] + /** Réponse de chaque joueur ayant répondu. */ + answers: RoundPlayerAnswer[] } // --- Snapshot diffusé au client (room:state) -----------------------------