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?.players.map(p => - {p.login}{p.login === state.host && ' 👑'}
)}
+ {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 => {