Application Android et IOS pour l'amicale des élèves
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GridManager.js 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // @flow
  2. import Piece from "./Piece";
  3. import ScoreManager from "./ScoreManager";
  4. import type {coordinates} from './Shapes/BaseShape';
  5. export type cell = {color: string, isEmpty: boolean, key: string};
  6. export type grid = Array<Array<cell>>;
  7. /**
  8. * Class used to manage the game grid
  9. *
  10. */
  11. export default class GridManager {
  12. #currentGrid: grid;
  13. #colors: Object;
  14. /**
  15. * Initializes a grid of the given size
  16. *
  17. * @param width The grid width
  18. * @param height The grid height
  19. * @param colors Object containing current theme colors
  20. */
  21. constructor(width: number, height: number, colors: Object) {
  22. this.#colors = colors;
  23. this.#currentGrid = this.getEmptyGrid(height, width);
  24. }
  25. /**
  26. * Get the current grid
  27. *
  28. * @return {grid} The current grid
  29. */
  30. getCurrentGrid(): grid {
  31. return this.#currentGrid;
  32. }
  33. /**
  34. * Get a new empty grid line of the given size
  35. *
  36. * @param width The line size
  37. * @return {Array<cell>}
  38. */
  39. getEmptyLine(width: number): Array<cell> {
  40. let line = [];
  41. for (let col = 0; col < width; col++) {
  42. line.push({
  43. color: this.#colors.tetrisBackground,
  44. isEmpty: true,
  45. key: col.toString(),
  46. });
  47. }
  48. return line;
  49. }
  50. /**
  51. * Gets a new empty grid
  52. *
  53. * @param width The grid width
  54. * @param height The grid height
  55. * @return {grid} A new empty grid
  56. */
  57. getEmptyGrid(height: number, width: number): grid {
  58. let grid = [];
  59. for (let row = 0; row < height; row++) {
  60. grid.push(this.getEmptyLine(width));
  61. }
  62. return grid;
  63. }
  64. /**
  65. * Removes the given lines from the grid,
  66. * shifts down every line on top and adds new empty lines on top.
  67. *
  68. * @param lines An array of line numbers to remove
  69. * @param scoreManager A reference to the score manager
  70. */
  71. clearLines(lines: Array<number>, scoreManager: ScoreManager) {
  72. lines.sort();
  73. for (let i = 0; i < lines.length; i++) {
  74. this.#currentGrid.splice(lines[i], 1);
  75. this.#currentGrid.unshift(this.getEmptyLine(this.#currentGrid[0].length));
  76. }
  77. scoreManager.addLinesRemovedPoints(lines.length);
  78. }
  79. /**
  80. * Gets the lines to clear around the given piece's coordinates.
  81. * The piece's coordinates are used for optimization and to prevent checking the whole grid.
  82. *
  83. * @param coord The piece's coordinates to check lines at
  84. * @return {Array<number>} An array containing the line numbers to clear
  85. */
  86. getLinesToClear(coord: Array<coordinates>): Array<number> {
  87. let rows = [];
  88. for (let i = 0; i < coord.length; i++) {
  89. let isLineFull = true;
  90. for (let col = 0; col < this.#currentGrid[coord[i].y].length; col++) {
  91. if (this.#currentGrid[coord[i].y][col].isEmpty) {
  92. isLineFull = false;
  93. break;
  94. }
  95. }
  96. if (isLineFull && rows.indexOf(coord[i].y) === -1)
  97. rows.push(coord[i].y);
  98. }
  99. return rows;
  100. }
  101. /**
  102. * Freezes the given piece to the grid
  103. *
  104. * @param currentObject The piece to freeze
  105. * @param scoreManager A reference to the score manager
  106. */
  107. freezeTetromino(currentObject: Piece, scoreManager: ScoreManager) {
  108. this.clearLines(this.getLinesToClear(currentObject.getCoordinates()), scoreManager);
  109. }
  110. }