fix: znemožnění spuštění Tetrisu v jednom hráči
CI / Generate TypeScript types (push) Successful in 10s
CI / Server unit tests (push) Successful in 26s
CI / Build server (push) Successful in 29s
CI / Build client (push) Successful in 43s
CI / Playwright E2E tests (push) Successful in 2m2s
CI / Build and push Docker image (push) Successful in 52s
CI / Notify (push) Successful in 4s
CI / Generate TypeScript types (push) Successful in 10s
CI / Server unit tests (push) Successful in 26s
CI / Build server (push) Successful in 29s
CI / Build client (push) Successful in 43s
CI / Playwright E2E tests (push) Successful in 2m2s
CI / Build and push Docker image (push) Successful in 52s
CI / Notify (push) Successful in 4s
This commit is contained in:
3 files changed
+19
-6
No files matched your search
@@ -431,6 +431,8 @@ export default function TetrisGame() {
|
|||||||
<ul className="tetris-players">
|
<ul className="tetris-players">
|
||||||
{state?.players.map(p => <li key={p.login}>{p.login}{p.login === state.host && ' 👑'}</li>)}
|
{state?.players.map(p => <li key={p.login}>{p.login}{p.login === state.host && ' 👑'}</li>)}
|
||||||
</ul>
|
</ul>
|
||||||
|
{state && state.players.length < state.minPlayers &&
|
||||||
|
<p className="text-muted">Čeká se na další hráče… Pro hru o samotě použijte Trénink.</p>}
|
||||||
{renderSettings()}
|
{renderSettings()}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@@ -503,7 +505,7 @@ export default function TetrisGame() {
|
|||||||
</Button>);
|
</Button>);
|
||||||
if (login === state?.host) {
|
if (login === state?.host) {
|
||||||
buttons.push(<Button key="start" onClick={() => send('tetris:start')}
|
buttons.push(<Button key="start" onClick={() => send('tetris:start')}
|
||||||
disabled={(state?.players.length ?? 0) < (state?.minPlayers ?? 1)}>Spustit hru</Button>);
|
disabled={(state?.players.length ?? 0) < (state?.minPlayers ?? 2)}>Spustit hru</Button>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buttons.push(<Button key="close" variant="secondary" onClick={() => setOpen(false)}>Zavřít</Button>);
|
buttons.push(<Button key="close" variant="secondary" onClick={() => setOpen(false)}>Zavřít</Button>);
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import { fakeClock } from './helpers/fakeClock';
|
|||||||
|
|
||||||
const BOARD = '0'.repeat(BOARD_WIDTH * (BOARD_HEIGHT - 1)) + '1'.repeat(BOARD_WIDTH);
|
const BOARD = '0'.repeat(BOARD_WIDTH * (BOARD_HEIGHT - 1)) + '1'.repeat(BOARD_WIDTH);
|
||||||
|
|
||||||
function setup() {
|
function setup(minPlayers = 1) {
|
||||||
const clock = fakeClock();
|
const clock = fakeClock();
|
||||||
const all: TetrisState[] = [];
|
const all: TetrisState[] = [];
|
||||||
const watched: TetrisState[] = [];
|
const watched: TetrisState[] = [];
|
||||||
const garbage: GarbageEvent[] = [];
|
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 last = () => all[all.length - 1];
|
||||||
const startWith = (settings: Partial<TetrisSettings>, ...logins: string[]) => {
|
const startWith = (settings: Partial<TetrisSettings>, ...logins: string[]) => {
|
||||||
logins.forEach(l => game.join(l));
|
logins.forEach(l => game.join(l));
|
||||||
@@ -22,6 +22,16 @@ function setup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('tetris', () => {
|
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', () => {
|
test('po odpočtu začne hra se společným seedem', () => {
|
||||||
const ctx = setup();
|
const ctx = setup();
|
||||||
ctx.startGame('alice', 'bob');
|
ctx.startGame('alice', 'bob');
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Server } from "socket.io";
|
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.
|
* Multiplayerový Tetris (battle) přes websocket.
|
||||||
@@ -124,7 +124,7 @@ export class TetrisGame {
|
|||||||
private readonly broadcastAll: (state: TetrisState) => void,
|
private readonly broadcastAll: (state: TetrisState) => void,
|
||||||
private readonly broadcastWatchers: (state: TetrisState) => void,
|
private readonly broadcastWatchers: (state: TetrisState) => void,
|
||||||
private readonly sendGarbage: (event: GarbageEvent) => void,
|
private readonly sendGarbage: (event: GarbageEvent) => void,
|
||||||
private readonly minPlayers = 1,
|
private readonly minPlayers = 2,
|
||||||
private readonly clock: Clock = defaultClock,
|
private readonly clock: Clock = defaultClock,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
@@ -366,7 +366,8 @@ export function registerTetrisGame(io: Server) {
|
|||||||
state => io.emit('tetris:state', state),
|
state => io.emit('tetris:state', state),
|
||||||
state => io.to(WATCH_ROOM).emit('tetris:state', state),
|
state => io.to(WATCH_ROOM).emit('tetris:state', state),
|
||||||
event => io.to(WATCH_ROOM).emit('tetris:garbage', event),
|
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 => {
|
io.on('connection', socket => {
|
||||||
|
|||||||
Reference in new issue
Block a user