fix. férovější výběr cíle u Tetrisu, odrážení odpadu
This commit is contained in:
5 files changed
+79
-17
No files matched your search
@@ -186,8 +186,8 @@ export default function TetrisGame() {
|
||||
if (practice || phase !== 'playing' || !isPlayer || state?.seed === undefined || sessionSeed.current === state.seed) return;
|
||||
sessionSeed.current = state.seed;
|
||||
sessionRef.current = new TetrisSession(state.seed, {
|
||||
onLock: cleared => {
|
||||
if (cleared >= 2) send('tetris:cleared', { count: cleared });
|
||||
onLock: (cleared, attack) => {
|
||||
if (attack > 0) send('tetris:cleared', { count: cleared, sent: attack });
|
||||
sendSnapshot();
|
||||
setVersion(v => v + 1);
|
||||
},
|
||||
@@ -335,7 +335,8 @@ export default function TetrisGame() {
|
||||
return (
|
||||
<p>
|
||||
Tetris pro více hráčů. Všichni dostávají stejné kostky; kdo smaže 2, 3 nebo 4 řádky naráz,
|
||||
pošle náhodnému soupeři 1, 2 nebo 4 odpadní řádky. Vyhrává poslední hráč ve hře.
|
||||
pošle 1, 2 nebo 4 odpadní řádky soupeři, který jich zatím dostal nejméně. Smazáním řádků
|
||||
lze zároveň odrazit odpad, který na vás čeká. Vyhrává poslední hráč ve hře.
|
||||
Hrát se dá i sólo, nebo si kdykoli zatrénovat jen pro sebe.
|
||||
</p>
|
||||
);
|
||||
|
||||
@@ -36,6 +36,9 @@ const KICKS: Point[] = [[0, 0], [-1, 0], [1, 0], [0, -1], [-2, 0], [2, 0]];
|
||||
/** Body za smazání 0–4 řádků naráz (násobí se úrovní). */
|
||||
const LINE_SCORES = [0, 100, 300, 500, 800];
|
||||
|
||||
/** Odpadní řádky za smazání 0–4 řádků naráz (musí odpovídat GARBAGE_FOR_LINES na serveru). */
|
||||
const ATTACK_FOR_LINES = [0, 0, 1, 2, 4];
|
||||
|
||||
export type Piece = { type: number, rot: number, x: number, y: number };
|
||||
|
||||
/** Deterministický generátor (mulberry32) — stejný seed = stejné pořadí kostek u všech. */
|
||||
@@ -53,8 +56,11 @@ function mulberry32(seed: number) {
|
||||
export const pieceCells = (p: Piece): Point[] => ROTATIONS[p.type][p.rot].map(([x, y]) => [p.x + x, p.y + y]);
|
||||
|
||||
export type SessionCallbacks = {
|
||||
/** Kostka dopadla; `cleared` = počet smazaných řádků. */
|
||||
onLock: (cleared: number) => void,
|
||||
/**
|
||||
* Kostka dopadla; `cleared` = počet smazaných řádků,
|
||||
* `attack` = odpadní řádky pro soupeře po odražení vlastního čekajícího odpadu.
|
||||
*/
|
||||
onLock: (cleared: number, attack: number) => void,
|
||||
onDeath: () => void,
|
||||
};
|
||||
|
||||
@@ -128,7 +134,7 @@ export class TetrisSession {
|
||||
}
|
||||
}
|
||||
|
||||
/** Odpadní řádky se přidají až po dopadu aktuální kostky (jako v klasickém battle módu). */
|
||||
/** Odpadní řádky čekají a přidají se po dopadu kostky, která nic nesmaže (jako v klasickém battle módu). */
|
||||
receiveGarbage(lines: number) {
|
||||
this.pendingGarbage += lines;
|
||||
}
|
||||
@@ -192,12 +198,19 @@ export class TetrisSession {
|
||||
this.active = null;
|
||||
|
||||
const cleared = this.clearLines();
|
||||
let attack = 0;
|
||||
if (cleared > 0) {
|
||||
this.score += LINE_SCORES[cleared] * (this.level + 1);
|
||||
this.lines += cleared;
|
||||
// Útok nejdřív odráží čekající odpad, soupeři jde jen zbytek
|
||||
attack = ATTACK_FOR_LINES[cleared] ?? 0;
|
||||
const cancelled = Math.min(attack, this.pendingGarbage);
|
||||
this.pendingGarbage -= cancelled;
|
||||
attack -= cancelled;
|
||||
}
|
||||
this.callbacks.onLock(cleared);
|
||||
if (this.pendingGarbage > 0) {
|
||||
this.callbacks.onLock(cleared, attack);
|
||||
// Dokud hráč maže řádky, zbylý odpad ještě čeká
|
||||
if (cleared === 0 && this.pendingGarbage > 0) {
|
||||
const overflow = this.addGarbage(this.pendingGarbage);
|
||||
this.pendingGarbage = 0;
|
||||
if (overflow) {
|
||||
|
||||
Reference in new issue
Block a user