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
JavaScript
"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,
};
}