UNPKG

tetris-fumen

Version:
337 lines (336 loc) 13.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPieces = exports.getBlocks = exports.getBlockXYs = exports.getBlockPositions = exports.PlayField = exports.InnerField = exports.createInnerField = exports.createNewInnerField = void 0; var defines_1 = require("./defines"); var FieldConstants = { Width: 10, Height: 23, PlayBlocks: 23 * 10, // Height * Width }; function createNewInnerField() { return new InnerField({}); } exports.createNewInnerField = createNewInnerField; function createInnerField(field) { var innerField = new InnerField({}); for (var y = -1; y < FieldConstants.Height; y += 1) { for (var x = 0; x < FieldConstants.Width; x += 1) { var at = field.at(x, y); innerField.setNumberAt(x, y, (0, defines_1.parsePiece)(at)); } } return innerField; } exports.createInnerField = createInnerField; var InnerField = /** @class */ (function () { function InnerField(_a) { var _b = _a.field, field = _b === void 0 ? InnerField.create(FieldConstants.PlayBlocks) : _b, _c = _a.garbage, garbage = _c === void 0 ? InnerField.create(FieldConstants.Width) : _c; this.field = field; this.garbage = garbage; } InnerField.create = function (length) { return new PlayField({ length: length }); }; InnerField.prototype.fill = function (operation) { this.field.fill(operation); }; InnerField.prototype.fillAll = function (positions, type) { this.field.fillAll(positions, type); }; InnerField.prototype.canFill = function (piece, rotation, x, y) { var _this = this; var positions = getBlockPositions(piece, rotation, x, y); return positions.every(function (_a) { var px = _a[0], py = _a[1]; return 0 <= px && px < 10 && 0 <= py && py < FieldConstants.Height && _this.getNumberAt(px, py) === defines_1.Piece.Empty; }); }; InnerField.prototype.canFillAll = function (positions) { var _this = this; return positions.every(function (_a) { var x = _a.x, y = _a.y; return 0 <= x && x < 10 && 0 <= y && y < FieldConstants.Height && _this.getNumberAt(x, y) === defines_1.Piece.Empty; }); }; InnerField.prototype.isOnGround = function (piece, rotation, x, y) { return !this.canFill(piece, rotation, x, y - 1); }; InnerField.prototype.clearLine = function () { this.field.clearLine(); }; InnerField.prototype.riseGarbage = function () { this.field.up(this.garbage); this.garbage.clearAll(); }; InnerField.prototype.mirror = function () { this.field.mirror(); }; InnerField.prototype.shiftToLeft = function () { this.field.shiftToLeft(); }; InnerField.prototype.shiftToRight = function () { this.field.shiftToRight(); }; InnerField.prototype.shiftToUp = function () { this.field.shiftToUp(); }; InnerField.prototype.shiftToBottom = function () { this.field.shiftToBottom(); }; InnerField.prototype.copy = function () { return new InnerField({ field: this.field.copy(), garbage: this.garbage.copy() }); }; InnerField.prototype.equals = function (other) { return this.field.equals(other.field) && this.garbage.equals(other.garbage); }; InnerField.prototype.addNumber = function (x, y, value) { if (0 <= y) { this.field.addOffset(x, y, value); } else { this.garbage.addOffset(x, -(y + 1), value); } }; InnerField.prototype.setNumberFieldAt = function (index, value) { this.field.setAt(index, value); }; InnerField.prototype.setNumberGarbageAt = function (index, value) { this.garbage.setAt(index, value); }; InnerField.prototype.setNumberAt = function (x, y, value) { return 0 <= y ? this.field.set(x, y, value) : this.garbage.set(x, -(y + 1), value); }; InnerField.prototype.getNumberAt = function (x, y) { return 0 <= y ? this.field.get(x, y) : this.garbage.get(x, -(y + 1)); }; InnerField.prototype.getNumberAtIndex = function (index, isField) { if (isField) { return this.getNumberAt(index % 10, Math.floor(index / 10)); } return this.getNumberAt(index % 10, -(Math.floor(index / 10) + 1)); }; InnerField.prototype.toFieldNumberArray = function () { return this.field.toArray(); }; InnerField.prototype.toGarbageNumberArray = function () { return this.garbage.toArray(); }; return InnerField; }()); exports.InnerField = InnerField; var PlayField = /** @class */ (function () { function PlayField(_a) { var pieces = _a.pieces, _b = _a.length, length = _b === void 0 ? FieldConstants.PlayBlocks : _b; if (pieces !== undefined) { this.pieces = pieces; } else { this.pieces = Array.from({ length: length }).map(function () { return defines_1.Piece.Empty; }); } this.length = length; } PlayField.load = function () { var lines = []; for (var _i = 0; _i < arguments.length; _i++) { lines[_i] = arguments[_i]; } var blocks = lines.join('').trim(); return PlayField.loadInner(blocks); }; PlayField.loadMinify = function () { var lines = []; for (var _i = 0; _i < arguments.length; _i++) { lines[_i] = arguments[_i]; } var blocks = lines.join('').trim(); return PlayField.loadInner(blocks, blocks.length); }; PlayField.loadInner = function (blocks, length) { var len = length !== undefined ? length : blocks.length; if (len % 10 !== 0) { throw new Error('Num of blocks in field should be mod 10'); } var field = length !== undefined ? new PlayField({ length: length }) : new PlayField({}); for (var index = 0; index < len; index += 1) { var block = blocks[index]; field.set(index % 10, Math.floor((len - index - 1) / 10), (0, defines_1.parsePiece)(block)); } return field; }; PlayField.prototype.get = function (x, y) { return this.pieces[x + y * FieldConstants.Width]; }; PlayField.prototype.addOffset = function (x, y, value) { this.pieces[x + y * FieldConstants.Width] += value; }; PlayField.prototype.set = function (x, y, piece) { this.setAt(x + y * FieldConstants.Width, piece); }; PlayField.prototype.setAt = function (index, piece) { this.pieces[index] = piece; }; PlayField.prototype.fill = function (_a) { var type = _a.type, rotation = _a.rotation, x = _a.x, y = _a.y; var blocks = getBlocks(type, rotation); for (var _i = 0, blocks_1 = blocks; _i < blocks_1.length; _i++) { var block = blocks_1[_i]; var _b = [x + block[0], y + block[1]], nx = _b[0], ny = _b[1]; this.set(nx, ny, type); } }; PlayField.prototype.fillAll = function (positions, type) { for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) { var _a = positions_1[_i], x = _a.x, y = _a.y; this.set(x, y, type); } }; PlayField.prototype.clearLine = function () { var newField = this.pieces.concat(); var top = this.pieces.length / FieldConstants.Width - 1; for (var y = top; 0 <= y; y -= 1) { var line = this.pieces.slice(y * FieldConstants.Width, (y + 1) * FieldConstants.Width); var isFilled = line.every(function (value) { return value !== defines_1.Piece.Empty; }); if (isFilled) { var bottom = newField.slice(0, y * FieldConstants.Width); var over = newField.slice((y + 1) * FieldConstants.Width); newField = bottom.concat(over, Array.from({ length: FieldConstants.Width }).map(function () { return defines_1.Piece.Empty; })); } } this.pieces = newField; }; PlayField.prototype.up = function (blockUp) { this.pieces = blockUp.pieces.concat(this.pieces).slice(0, this.length); }; PlayField.prototype.mirror = function () { var newField = []; for (var y = 0; y < this.pieces.length; y += 1) { var line = this.pieces.slice(y * FieldConstants.Width, (y + 1) * FieldConstants.Width); line.reverse(); for (var _i = 0, line_1 = line; _i < line_1.length; _i++) { var obj = line_1[_i]; newField.push(obj); } } this.pieces = newField; }; PlayField.prototype.shiftToLeft = function () { var height = this.pieces.length / 10; for (var y = 0; y < height; y += 1) { for (var x = 0; x < FieldConstants.Width - 1; x += 1) { this.pieces[x + y * FieldConstants.Width] = this.pieces[x + 1 + y * FieldConstants.Width]; } this.pieces[9 + y * FieldConstants.Width] = defines_1.Piece.Empty; } }; PlayField.prototype.shiftToRight = function () { var height = this.pieces.length / 10; for (var y = 0; y < height; y += 1) { for (var x = FieldConstants.Width - 1; 1 <= x; x -= 1) { this.pieces[x + y * FieldConstants.Width] = this.pieces[x - 1 + y * FieldConstants.Width]; } this.pieces[y * FieldConstants.Width] = defines_1.Piece.Empty; } }; PlayField.prototype.shiftToUp = function () { var blanks = Array.from({ length: 10 }).map(function () { return defines_1.Piece.Empty; }); this.pieces = blanks.concat(this.pieces).slice(0, this.length); }; PlayField.prototype.shiftToBottom = function () { var blanks = Array.from({ length: 10 }).map(function () { return defines_1.Piece.Empty; }); this.pieces = this.pieces.slice(10, this.length).concat(blanks); }; PlayField.prototype.toArray = function () { return this.pieces.concat(); }; Object.defineProperty(PlayField.prototype, "numOfBlocks", { get: function () { return this.pieces.length; }, enumerable: false, configurable: true }); PlayField.prototype.copy = function () { return new PlayField({ pieces: this.pieces.concat(), length: this.length }); }; PlayField.prototype.toShallowArray = function () { return this.pieces; }; PlayField.prototype.clearAll = function () { this.pieces = this.pieces.map(function () { return defines_1.Piece.Empty; }); }; PlayField.prototype.equals = function (other) { if (this.pieces.length !== other.pieces.length) { return false; } for (var index = 0; index < this.pieces.length; index += 1) { if (this.pieces[index] !== other.pieces[index]) { return false; } } return true; }; return PlayField; }()); exports.PlayField = PlayField; function getBlockPositions(piece, rotation, x, y) { return getBlocks(piece, rotation).map(function (position) { position[0] += x; position[1] += y; return position; }); } exports.getBlockPositions = getBlockPositions; function getBlockXYs(piece, rotation, x, y) { return getBlocks(piece, rotation).map(function (position) { return { x: position[0] + x, y: position[1] + y }; }); } exports.getBlockXYs = getBlockXYs; function getBlocks(piece, rotation) { var blocks = getPieces(piece); switch (rotation) { case defines_1.Rotation.Spawn: return blocks; case defines_1.Rotation.Left: return rotateLeft(blocks); case defines_1.Rotation.Reverse: return rotateReverse(blocks); case defines_1.Rotation.Right: return rotateRight(blocks); } throw new Error('Unsupported block'); } exports.getBlocks = getBlocks; function getPieces(piece) { switch (piece) { case defines_1.Piece.I: return [[0, 0], [-1, 0], [1, 0], [2, 0]]; case defines_1.Piece.T: return [[0, 0], [-1, 0], [1, 0], [0, 1]]; case defines_1.Piece.O: return [[0, 0], [1, 0], [0, 1], [1, 1]]; case defines_1.Piece.L: return [[0, 0], [-1, 0], [1, 0], [1, 1]]; case defines_1.Piece.J: return [[0, 0], [-1, 0], [1, 0], [-1, 1]]; case defines_1.Piece.S: return [[0, 0], [-1, 0], [0, 1], [1, 1]]; case defines_1.Piece.Z: return [[0, 0], [1, 0], [0, 1], [-1, 1]]; } throw new Error('Unsupported rotation'); } exports.getPieces = getPieces; function rotateRight(positions) { return positions.map(function (current) { return [current[1], -current[0]]; }); } function rotateLeft(positions) { return positions.map(function (current) { return [-current[1], current[0]]; }); } function rotateReverse(positions) { return positions.map(function (current) { return [-current[0], -current[1]]; }); }