UNPKG

nes-tetris-representation

Version:

A set of types and classes that represent the pieces, movement, and rng of NES Tetris

286 lines (285 loc) 10.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPieceGrid = exports.getPiece = exports.movePiece = void 0; const lodash_1 = require("lodash"); const piece_types_1 = require("./piece-types"); function movePiece(grid, currentPiece, newPiece) { const orientedNewPiece = getPiece(newPiece); const blocked = orientedNewPiece.blocks.some((block) => { return (block.row < 0 || block.row >= 22 || block.column < 0 || block.column >= 10 || (grid[block.row] && grid[block.row][block.column] !== 0)); }); if (blocked) { return currentPiece; } return orientedNewPiece; } exports.movePiece = movePiece; const getMap = { [piece_types_1.Piece.O]: getO, [piece_types_1.Piece.I]: getI, [piece_types_1.Piece.T]: getT, [piece_types_1.Piece.L]: getL, [piece_types_1.Piece.J]: getJ, [piece_types_1.Piece.S]: getS, [piece_types_1.Piece.Z]: getZ, }; function getPiece(piece) { const result = getResultPlacement(getMap[piece.type](piece.row, piece.column, piece.orientation)); if (lodash_1.isError(result)) { throw result; } return result; } exports.getPiece = getPiece; function getPieceGrid(piece) { const pieceGrid = getMap[piece](0, 0, 0); const rows = pieceGrid.blocks.map((block) => block.row); const columns = pieceGrid.blocks.map((block) => block.column); const minRow = Math.min(...rows); const maxRow = Math.max(...rows); const minColumn = Math.min(...columns); const maxColumn = Math.max(...columns); const grid = []; for (let i = 0; i <= maxRow - minRow; i++) { const row = []; for (let j = 0; j <= maxColumn - minColumn; j++) { row.push(0); } grid.push(row); } pieceGrid.blocks.forEach((block) => { if (block.value) { grid[block.row - minRow][block.column - minColumn] = block.value; } }); return grid; } exports.getPieceGrid = getPieceGrid; const getResultPlacement = (piece) => { const rows = piece.blocks.map(block => block.row); const maxRow = Math.max(...rows); const minRow = Math.min(...rows); const columns = piece.blocks.map(block => block.column); const maxColumn = Math.max(...columns); const minColumn = Math.min(...columns); if (maxRow <= 21 && minRow >= 0 && maxColumn <= 9 && minColumn >= 0) { return piece; } return new Error('Invalid position'); }; function getO(row, column, orientation) { return { type: piece_types_1.Piece.O, row, column, orientation, blocks: [ { row, column, value: 3 }, { row, column: column - 1, value: 3 }, { row: row + 1, column, value: 3 }, { row: row + 1, column: column - 1, value: 3 }, ], }; } function getI(row, column, orientation) { const blocks = []; switch (orientation) { case piece_types_1.Orientation.Down: case piece_types_1.Orientation.Up: blocks.push({ row, column: column - 2, value: 3 }); blocks.push({ row, column: column - 1, value: 3 }); blocks.push({ row, column, value: 3 }); blocks.push({ row, column: column + 1, value: 3 }); break; case piece_types_1.Orientation.Left: case piece_types_1.Orientation.Right: blocks.push({ row: row - 2, column, value: 3 }); blocks.push({ row: row - 1, column, value: 3 }); blocks.push({ row, column, value: 3 }); blocks.push({ row: row + 1, column, value: 3 }); break; default: throw new Error('Unknown orientation'); } return { type: piece_types_1.Piece.I, row, column, orientation, blocks, }; } function getT(row, column, orientation) { const blocks = []; switch (orientation) { case piece_types_1.Orientation.Down: blocks.push({ row, column: column - 1, value: 3 }); blocks.push({ row, column, value: 3 }); blocks.push({ row, column: column + 1, value: 3 }); blocks.push({ row: row + 1, column, value: 3 }); break; case piece_types_1.Orientation.Left: blocks.push({ row: row - 1, column, value: 3 }); blocks.push({ row, column: column - 1, value: 3 }); blocks.push({ row, column, value: 3 }); blocks.push({ row: row + 1, column, value: 3 }); break; case piece_types_1.Orientation.Up: blocks.push({ row: row - 1, column, value: 3 }); blocks.push({ row, column: column - 1, value: 3 }); blocks.push({ row, column, value: 3 }); blocks.push({ row, column: column + 1, value: 3 }); break; case piece_types_1.Orientation.Right: blocks.push({ row: row - 1, column, value: 3 }); blocks.push({ row, column: column + 1, value: 3 }); blocks.push({ row, column, value: 3 }); blocks.push({ row: row + 1, column, value: 3 }); break; default: throw new Error('Unknown orientation'); } return { type: piece_types_1.Piece.T, row, column, orientation, blocks, }; } function getL(row, column, orientation) { const blocks = []; switch (orientation) { case piece_types_1.Orientation.Down: blocks.push({ row, column: column - 1, value: 1 }); blocks.push({ row, column, value: 1 }); blocks.push({ row, column: column + 1, value: 1 }); blocks.push({ row: row + 1, column: column - 1, value: 1 }); break; case piece_types_1.Orientation.Left: blocks.push({ row: row - 1, column, value: 1 }); blocks.push({ row, column, value: 1 }); blocks.push({ row: row + 1, column, value: 1 }); blocks.push({ row: row + 1, column: column + 1, value: 1 }); break; case piece_types_1.Orientation.Up: blocks.push({ row: row - 1, column: column + 1, value: 1 }); blocks.push({ row, column: column - 1, value: 1 }); blocks.push({ row, column, value: 1 }); blocks.push({ row, column: column + 1, value: 1 }); break; case piece_types_1.Orientation.Right: blocks.push({ row: row - 1, column, value: 1 }); blocks.push({ row: row - 1, column: column - 1, value: 1 }); blocks.push({ row, column, value: 1 }); blocks.push({ row: row + 1, column, value: 1 }); break; default: throw new Error('Unknown orientation'); } return { type: piece_types_1.Piece.L, row, column, orientation, blocks, }; } function getJ(row, column, orientation) { const blocks = []; switch (orientation) { case piece_types_1.Orientation.Down: blocks.push({ row, column: column - 1, value: 2 }); blocks.push({ row, column, value: 2 }); blocks.push({ row, column: column + 1, value: 2 }); blocks.push({ row: row + 1, column: column + 1, value: 2 }); break; case piece_types_1.Orientation.Left: blocks.push({ row: row - 1, column, value: 2 }); blocks.push({ row: row - 1, column: column + 1, value: 2 }); blocks.push({ row, column, value: 2 }); blocks.push({ row: row + 1, column, value: 2 }); break; case piece_types_1.Orientation.Up: blocks.push({ row: row - 1, column: column - 1, value: 2 }); blocks.push({ row, column: column - 1, value: 2 }); blocks.push({ row, column, value: 2 }); blocks.push({ row, column: column + 1, value: 2 }); break; case piece_types_1.Orientation.Right: blocks.push({ row: row - 1, column, value: 2 }); blocks.push({ row, column, value: 2 }); blocks.push({ row: row + 1, column, value: 2 }); blocks.push({ row: row + 1, column: column - 1, value: 2 }); break; default: throw new Error('Unknown orientation'); } return { type: piece_types_1.Piece.J, row, column, orientation, blocks, }; } function getS(row, column, orientation) { const blocks = []; switch (orientation) { case piece_types_1.Orientation.Down: case piece_types_1.Orientation.Up: blocks.push({ row, column, value: 2 }); blocks.push({ row, column: column + 1, value: 2 }); blocks.push({ row: row + 1, column, value: 2 }); blocks.push({ row: row + 1, column: column - 1, value: 2 }); break; case piece_types_1.Orientation.Left: case piece_types_1.Orientation.Right: blocks.push({ row: row - 1, column, value: 2 }); blocks.push({ row, column, value: 2 }); blocks.push({ row, column: column + 1, value: 2 }); blocks.push({ row: row + 1, column: column + 1, value: 2 }); break; default: throw new Error('Unknown orientation'); } return { type: piece_types_1.Piece.S, row, column, orientation, blocks, }; } function getZ(row, column, orientation) { const blocks = []; switch (orientation) { case piece_types_1.Orientation.Down: case piece_types_1.Orientation.Up: blocks.push({ row, column: column - 1, value: 1 }); blocks.push({ row, column, value: 1 }); blocks.push({ row: row + 1, column, value: 1 }); blocks.push({ row: row + 1, column: column + 1, value: 1 }); break; case piece_types_1.Orientation.Left: case piece_types_1.Orientation.Right: blocks.push({ row: row - 1, column: column + 1, value: 1 }); blocks.push({ row, column, value: 1 }); blocks.push({ row, column: column + 1, value: 1 }); blocks.push({ row: row + 1, column, value: 1 }); break; default: throw new Error('Unknown orientation'); } return { type: piece_types_1.Piece.Z, row, column, orientation, blocks, }; }