From 304c7656e987ad67e6577c621752e162b86375b0 Mon Sep 17 00:00:00 2001 From: Martin Berka Date: Tue, 20 Oct 2026 09:47:00 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20znemo=C5=BEn=C4=9Bn=C3=AD=20spu=C5=A1t?= =?UTF-8?q?=C4=9Bn=C3=AD=20Tetrisu=20v=20jednom=20hr=C3=A1=C4=8Di?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/TetrisGame.tsx | 4 +++- server/src/tests/tetrisGame.test.ts | 14 ++++++++++++-- server/src/tetrisGame.ts | 7 ++++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/client/src/components/TetrisGame.tsx b/client/src/components/TetrisGame.tsx index f6b617c..41b8061 100644 --- a/client/src/components/TetrisGame.tsx +++ b/client/src/components/TetrisGame.tsx @@ -431,6 +431,8 @@ export default function TetrisGame() { + {state && state.players.length < state.minPlayers && +

Čeká se na další hráče… Pro hru o samotě použijte Trénink.

} {renderSettings()} ); @@ -503,7 +505,7 @@ export default function TetrisGame() { ); if (login === state?.host) { buttons.push(); + disabled={(state?.players.length ?? 0) < (state?.minPlayers ?? 2)}>Spustit hru); } } buttons.push(); diff --git a/server/src/tests/tetrisGame.test.ts b/server/src/tests/tetrisGame.test.ts index 8745c7d..934e032 100644 --- a/server/src/tests/tetrisGame.test.ts +++ b/server/src/tests/tetrisGame.test.ts @@ -4,12 +4,12 @@ import { fakeClock } from './helpers/fakeClock'; const BOARD = '0'.repeat(BOARD_WIDTH * (BOARD_HEIGHT - 1)) + '1'.repeat(BOARD_WIDTH); -function setup() { +function setup(minPlayers = 1) { const clock = fakeClock(); const all: TetrisState[] = []; const watched: TetrisState[] = []; const garbage: GarbageEvent[] = []; - const game = new TetrisGame(s => all.push(s), s => watched.push(s), e => garbage.push(e), 1, clock); + const game = new TetrisGame(s => all.push(s), s => watched.push(s), e => garbage.push(e), minPlayers, clock); const last = () => all[all.length - 1]; const startWith = (settings: Partial, ...logins: string[]) => { logins.forEach(l => game.join(l)); @@ -22,6 +22,16 @@ function setup() { } describe('tetris', () => { + test('společnou hru nejde spustit jen s jedním hráčem', () => { + const ctx = setup(2); + ctx.game.join('alice'); + expect(() => ctx.game.start('alice')).toThrow(GameError); + expect(ctx.last()).toMatchObject({ phase: 'lobby' }); + ctx.game.join('bob'); + ctx.game.start('alice'); + expect(ctx.last()).toMatchObject({ phase: 'countdown' }); + }); + test('po odpočtu začne hra se společným seedem', () => { const ctx = setup(); ctx.startGame('alice', 'bob'); diff --git a/server/src/tetrisGame.ts b/server/src/tetrisGame.ts index 4b8e23f..2d8f1fb 100644 --- a/server/src/tetrisGame.ts +++ b/server/src/tetrisGame.ts @@ -1,5 +1,5 @@ import { Server } from "socket.io"; -import { Clock, defaultClock, GameError, gameHandler } from "./minigames"; +import { Clock, defaultClock, GameError, gameHandler, minPlayersForEnv } from "./minigames"; /** * Multiplayerový Tetris (battle) přes websocket. @@ -124,7 +124,7 @@ export class TetrisGame { private readonly broadcastAll: (state: TetrisState) => void, private readonly broadcastWatchers: (state: TetrisState) => void, private readonly sendGarbage: (event: GarbageEvent) => void, - private readonly minPlayers = 1, + private readonly minPlayers = 2, private readonly clock: Clock = defaultClock, ) { } @@ -366,7 +366,8 @@ export function registerTetrisGame(io: Server) { state => io.emit('tetris:state', state), state => io.to(WATCH_ROOM).emit('tetris:state', state), event => io.to(WATCH_ROOM).emit('tetris:garbage', event), - 1, // Tetris se dá hrát i sólo + // Sólo hra je jen Trénink v prohlížeči, společná hra by blokovala ostatní + minPlayersForEnv(2), ); io.on('connection', socket => {