// @flow import Piece from "./Piece"; import ScoreManager from "./ScoreManager"; import type {coordinates} from './Shapes/BaseShape'; export type cell = {color: string, isEmpty: boolean}; export type grid = Array>; /** * Class used to manage the game grid * */ export default class GridManager { #currentGrid: grid; #colors: Object; /** * Initializes a grid of the given size * * @param width The grid width * @param height The grid height * @param colors Object containing current theme colors */ constructor(width: number, height: number, colors: Object) { this.#colors = colors; this.#currentGrid = this.getEmptyGrid(height, width); } /** * Get the current grid * * @return {grid} The current grid */ getCurrentGrid(): grid { return this.#currentGrid; } /** * Get a new empty grid line of the given size * * @param width The line size * @return {Array} */ getEmptyLine(width: number): Array { let line = []; for (let col = 0; col < width; col++) { line.push({ color: this.#colors.tetrisBackground, isEmpty: true, }); } return line; } /** * Gets a new empty grid * * @param width The grid width * @param height The grid height * @return {grid} A new empty grid */ getEmptyGrid(height: number, width: number): grid { let grid = []; for (let row = 0; row < height; row++) { grid.push(this.getEmptyLine(width)); } return grid; } /** * Removes the given lines from the grid, * shifts down every line on top and adds new empty lines on top. * * @param lines An array of line numbers to remove * @param scoreManager A reference to the score manager */ clearLines(lines: Array, scoreManager: ScoreManager) { lines.sort(); for (let i = 0; i < lines.length; i++) { this.#currentGrid.splice(lines[i], 1); this.#currentGrid.unshift(this.getEmptyLine(this.#currentGrid[0].length)); } scoreManager.addLinesRemovedPoints(lines.length); } /** * Gets the lines to clear around the given piece's coordinates. * The piece's coordinates are used for optimization and to prevent checking the whole grid. * * @param coord The piece's coordinates to check lines at * @return {Array} An array containing the line numbers to clear */ getLinesToClear(coord: Array): Array { let rows = []; for (let i = 0; i < coord.length; i++) { let isLineFull = true; for (let col = 0; col < this.#currentGrid[coord[i].y].length; col++) { if (this.#currentGrid[coord[i].y][col].isEmpty) { isLineFull = false; break; } } if (isLineFull && rows.indexOf(coord[i].y) === -1) rows.push(coord[i].y); } return rows; } /** * Freezes the given piece to the grid * * @param currentObject The piece to freeze * @param scoreManager A reference to the score manager */ freezeTetromino(currentObject: Piece, scoreManager: ScoreManager) { this.clearLines(this.getLinesToClear(currentObject.getCoordinates()), scoreManager); } }