fix(ui): unify tie-for-lead result across lobby + game (shared victory, not a draw)
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 1m7s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m41s

Bring the online lobby badge and the in-game 'you won/lost' text to the
same competition ranking the hotseat seat medals use: in a 3-4 player game
a TIE for the lead is a SHARED victory for the top scorers and a placed
finish for those below — not a full draw for everyone (winner() is -1 on
any tie, so isWinner alone conflated them). An aborted game and a genuine
all-level finish stay a draw; a win by resignation (winner at a not-higher
score) is unchanged.
- result.ts: resultBadge no-winner branch ranks by final score; placeBadge
  helper; resigned seats excluded from the ranking.
- Game.svelte: resultText aligned (shared lead = won, below = lost).
This commit is contained in:
Ilia Denisov
2026-07-07 15:47:34 +02:00
parent 1e087be90a
commit 80cc2a76e8
3 changed files with 45 additions and 10 deletions
+12
View File
@@ -75,6 +75,18 @@ describe('resultBadge', () => {
const second = game([seat(0, 'me', 300), seat(1, 'a', 400, true), seat(2, 'b', 200), seat(3, 'c', 100)]);
expect(resultBadge(second, 'me')).toEqual({ key: 'result.place2', emoji: '🥈' });
});
it('tie for the lead (3-4p): a shared victory for the leaders, a placed finish for those below', () => {
// The reported case, viewer-side: two seats tie for the lead (-8), one is last (-14) — no single
// winner(), so this must NOT read as a full draw for everyone.
expect(resultBadge(game([seat(0, 'me', -8), seat(1, 'a', -14), seat(2, 'b', -8)]), 'me')).toEqual({ key: 'result.victory', emoji: '🏆' });
expect(resultBadge(game([seat(0, 'x', -8), seat(1, 'me', -14), seat(2, 'b', -8)]), 'me')).toEqual({ key: 'result.place3', emoji: '🥉' });
});
it('an aborted game reads as a draw for everyone, whatever the scores', () => {
const g = { ...game([seat(0, 'me', 50), seat(1, 'a', 30)]), endReason: 'aborted' };
expect(resultBadge(g, 'me')).toEqual({ key: 'result.draw', emoji: '🏅' });
});
});
describe('seatMedal', () => {