fix: rotace kostek v Tetrisu dle osy a proti směru hodinových ručiček, zrození kostky nad plochou
CI / Generate TypeScript types (push) Successful in 14s
CI / Server unit tests (push) Successful in 28s
CI / Build server (push) Successful in 34s
CI / Build client (push) Successful in 52s
CI / Playwright E2E tests (push) Successful in 1m54s
CI / Build and push Docker image (push) Successful in 44s
CI / Notify (push) Successful in 2s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stánek PavelandClaude Opus 5.5 committed 2026-10-20 10:26:47 +02:00
1 parent 304c7656e9
commit a8b67fd76e
2 files changed
+30 -15

No files matched your search

+26 -15
View File
@@ -10,23 +10,32 @@ export const GARBAGE = 8;
type Point = [number, number]; type Point = [number, number];
/** Kostky I, O, T, S, Z, J, L ve výchozí rotaci a velikost jejich čtverce pro rotaci. */ /**
const SHAPES: { cells: Point[], box: number }[] = [ * Kostky I, O, T, S, Z, J, L ve výchozí rotaci, velikost jejich čtverce pro rotaci
{ cells: [[0, 1], [1, 1], [2, 1], [3, 1]], box: 4 }, * a počet různých poloh (O jedna; I, S, Z jen dvě, aby se při otáčení neposouvaly).
{ cells: [[0, 0], [1, 0], [0, 1], [1, 1]], box: 2 }, */
{ cells: [[1, 0], [0, 1], [1, 1], [2, 1]], box: 3 }, const SHAPES: { cells: Point[], box: number, states: 1 | 2 | 4 }[] = [
{ cells: [[1, 0], [2, 0], [0, 1], [1, 1]], box: 3 }, { cells: [[0, 1], [1, 1], [2, 1], [3, 1]], box: 4, states: 2 },
{ cells: [[0, 0], [1, 0], [1, 1], [2, 1]], box: 3 }, { cells: [[0, 0], [1, 0], [0, 1], [1, 1]], box: 2, states: 1 },
{ cells: [[0, 0], [0, 1], [1, 1], [2, 1]], box: 3 }, { cells: [[1, 0], [0, 1], [1, 1], [2, 1]], box: 3, states: 4 },
{ cells: [[2, 0], [0, 1], [1, 1], [2, 1]], box: 3 }, { cells: [[1, 0], [2, 0], [0, 1], [1, 1]], box: 3, states: 2 },
{ cells: [[0, 0], [1, 0], [1, 1], [2, 1]], box: 3, states: 2 },
{ cells: [[0, 0], [0, 1], [1, 1], [2, 1]], box: 3, states: 4 },
{ cells: [[2, 0], [0, 1], [1, 1], [2, 1]], box: 3, states: 4 },
]; ];
/** Předpočítané rotace (po směru hodinových ručiček) pro každou kostku. */ /**
const ROTATIONS: Point[][][] = SHAPES.map(({ cells, box }) => { * Předpočítané rotace pro každou kostku; rot + 1 = otočení proti směru hodinových ručiček.
* T, J, L se otáčí kolem prostředního políčka. I, S, Z jen přepínají mezi vodorovnou
* a svislou polohou (svislá = vodorovná otočená po směru, stejná osa jako v klasickém Tetrisu).
*/
const ROTATIONS: Point[][][] = SHAPES.map(({ cells, box, states }) => {
const ccw = (pts: Point[]) => pts.map(([x, y]) => [y, box - 1 - x] as Point);
const cw = (pts: Point[]) => pts.map(([x, y]) => [box - 1 - y, x] as Point);
if (states === 1) return [cells, cells, cells, cells];
if (states === 2) return [cells, cw(cells), cells, cw(cells)];
const result = [cells]; const result = [cells];
for (let r = 1; r < 4; r++) { for (let r = 1; r < 4; r++) result.push(ccw(result[r - 1]));
result.push(result[r - 1].map(([x, y]) => [box - 1 - y, x] as Point));
}
return result; return result;
}); });
@@ -164,7 +173,9 @@ export class TetrisSession {
private spawn() { private spawn() {
const type = this.nextType; const type = this.nextType;
this.nextType = this.draw(); this.nextType = this.draw();
const piece: Piece = { type, rot: 0, x: type === 1 ? 4 : 3, y: type === 0 ? -1 : 0 }; // Kostka se objeví celá nad deskou, aby ji šlo otočit dřív, než vjede do hrací plochy
const bottom = Math.max(...ROTATIONS[type][0].map(([, y]) => y));
const piece: Piece = { type, rot: 0, x: type === 1 ? 4 : 3, y: -bottom - 1 };
if (!this.fits(piece)) { if (!this.fits(piece)) {
this.active = null; this.active = null;
this.die(); this.die();
+4
View File
@@ -0,0 +1,4 @@
[
"Tetris: kostky se otáčí proti směru hodinových ručiček kolem svého středu, tyčka a S/Z kostky už jen přepínají mezi vodorovnou a svislou polohou",
"Tetris: nová kostka se objeví nad hrací plochou, takže ji jde otočit dřív, než do plochy vjede"
]