forked from vergnet/application-amicale
122 lines
3.3 KiB
JavaScript
122 lines
3.3 KiB
JavaScript
// @flow
|
|
|
|
import Piece from './Piece';
|
|
import ScoreManager from './ScoreManager';
|
|
import type {CoordinatesType} from '../Shapes/BaseShape';
|
|
import type {GridType} from '../components/GridComponent';
|
|
import type {CellType} from '../components/CellComponent';
|
|
import type {CustomThemeType} from '../../../managers/ThemeManager';
|
|
|
|
/**
|
|
* Class used to manage the game grid
|
|
*/
|
|
export default class GridManager {
|
|
#currentGrid: GridType;
|
|
|
|
#theme: CustomThemeType;
|
|
|
|
/**
|
|
* Initializes a grid of the given size
|
|
*
|
|
* @param width The grid width
|
|
* @param height The grid height
|
|
* @param theme Object containing current theme
|
|
*/
|
|
constructor(width: number, height: number, theme: CustomThemeType) {
|
|
this.#theme = theme;
|
|
this.#currentGrid = this.getEmptyGrid(height, width);
|
|
}
|
|
|
|
/**
|
|
* Get the current grid
|
|
*
|
|
* @return {GridType} The current grid
|
|
*/
|
|
getCurrentGrid(): GridType {
|
|
return this.#currentGrid;
|
|
}
|
|
|
|
/**
|
|
* Get a new empty grid line of the given size
|
|
*
|
|
* @param width The line size
|
|
* @return {Array<CellType>}
|
|
*/
|
|
getEmptyLine(width: number): Array<CellType> {
|
|
const line = [];
|
|
for (let col = 0; col < width; col += 1) {
|
|
line.push({
|
|
color: this.#theme.colors.tetrisBackground,
|
|
isEmpty: true,
|
|
key: col.toString(),
|
|
});
|
|
}
|
|
return line;
|
|
}
|
|
|
|
/**
|
|
* Gets a new empty grid
|
|
*
|
|
* @param width The grid width
|
|
* @param height The grid height
|
|
* @return {GridType} A new empty grid
|
|
*/
|
|
getEmptyGrid(height: number, width: number): GridType {
|
|
const grid = [];
|
|
for (let row = 0; row < height; row += 1) {
|
|
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<number>, scoreManager: ScoreManager) {
|
|
lines.sort();
|
|
for (let i = 0; i < lines.length; i += 1) {
|
|
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 pos The piece's coordinates to check lines at
|
|
* @return {Array<number>} An array containing the line numbers to clear
|
|
*/
|
|
getLinesToClear(pos: Array<CoordinatesType>): Array<number> {
|
|
const rows = [];
|
|
for (let i = 0; i < pos.length; i += 1) {
|
|
let isLineFull = true;
|
|
for (let col = 0; col < this.#currentGrid[pos[i].y].length; col += 1) {
|
|
if (this.#currentGrid[pos[i].y][col].isEmpty) {
|
|
isLineFull = false;
|
|
break;
|
|
}
|
|
}
|
|
if (isLineFull && rows.indexOf(pos[i].y) === -1) rows.push(pos[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,
|
|
);
|
|
}
|
|
}
|