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];
/** Kostky I, O, T, S, Z, J, L ve výchozí rotaci a velikost jejich čtverce pro rotaci. */
const SHAPES: { cells: Point[], box: number }[] = [
{ cells: [[0, 1], [1, 1], [2, 1], [3, 1]], box: 4 },
{ cells: [[0, 0], [1, 0], [0, 1], [1, 1]], box: 2 },
{ cells: [[1, 0], [0, 1], [1, 1], [2, 1]], box: 3 },
{ cells: [[1, 0], [2, 0], [0, 1], [1, 1]], box: 3 },
{ cells: [[0, 0], [1, 0], [1, 1], [2, 1]], box: 3 },
{ cells: [[0, 0], [0, 1], [1, 1], [2, 1]], box: 3 },
{ cells: [[2, 0], [0, 1], [1, 1], [2, 1]], box: 3 },
/**
* Kostky I, O, T, S, Z, J, L ve výchozí rotaci, velikost jejich čtverce pro rotaci
* a počet různých poloh (O jedna; I, S, Z jen dvě, aby se při otáčení neposouvaly).
*/
const SHAPES: { cells: Point[], box: number, states: 1 | 2 | 4 }[] = [
{ cells: [[0, 1], [1, 1], [2, 1], [3, 1]], box: 4, states: 2 },
{ cells: [[0, 0], [1, 0], [0, 1], [1, 1]], box: 2, states: 1 },
{ cells: [[1, 0], [0, 1], [1, 1], [2, 1]], box: 3, states: 4 },
{ 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];
for (let r = 1; r < 4; r++) {
result.push(result[r - 1].map(([x, y]) => [box - 1 - y, x] as Point));
}
for (let r = 1; r < 4; r++) result.push(ccw(result[r - 1]));
return result;
});
@@ -164,7 +173,9 @@ export class TetrisSession {
private spawn() {
const type = this.nextType;
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)) {
this.active = null;
this.die();