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.ts 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * Copyright (c) 2019 - 2020 Arnaud Vergnet.
  3. *
  4. * This file is part of Campus INSAT.
  5. *
  6. * Campus INSAT is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Campus INSAT is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. import Piece from './Piece';
  20. import ScoreManager from './ScoreManager';
  21. import type {CoordinatesType} from '../Shapes/BaseShape';
  22. import type {GridType} from '../components/GridComponent';
  23. import type {CellType} from '../components/CellComponent';
  24. /**
  25. * Class used to manage the game grid
  26. */
  27. export default class GridManager {
  28. #currentGrid: GridType;
  29. #theme: ReactNativePaper.Theme;
  30. /**
  31. * Initializes a grid of the given size
  32. *
  33. * @param width The grid width
  34. * @param height The grid height
  35. * @param theme Object containing current theme
  36. */
  37. constructor(width: number, height: number, theme: ReactNativePaper.Theme) {
  38. this.#theme = theme;
  39. this.#currentGrid = this.getEmptyGrid(height, width);
  40. }
  41. /**
  42. * Get the current grid
  43. *
  44. * @return {GridType} The current grid
  45. */
  46. getCurrentGrid(): GridType {
  47. return this.#currentGrid;
  48. }
  49. /**
  50. * Get a new empty grid line of the given size
  51. *
  52. * @param width The line size
  53. * @return {Array<CellType>}
  54. */
  55. getEmptyLine(width: number): Array<CellType> {
  56. const line = [];
  57. for (let col = 0; col < width; col += 1) {
  58. line.push({
  59. color: this.#theme.colors.tetrisBackground,
  60. isEmpty: true,
  61. key: col.toString(),
  62. });
  63. }
  64. return line;
  65. }
  66. /**
  67. * Gets a new empty grid
  68. *
  69. * @param width The grid width
  70. * @param height The grid height
  71. * @return {GridType} A new empty grid
  72. */
  73. getEmptyGrid(height: number, width: number): GridType {
  74. const grid = [];
  75. for (let row = 0; row < height; row += 1) {
  76. grid.push(this.getEmptyLine(width));
  77. }
  78. return grid;
  79. }
  80. /**
  81. * Removes the given lines from the grid,
  82. * shifts down every line on top and adds new empty lines on top.
  83. *
  84. * @param lines An array of line numbers to remove
  85. * @param scoreManager A reference to the score manager
  86. */
  87. clearLines(lines: Array<number>, scoreManager: ScoreManager) {
  88. lines.sort();
  89. for (let i = 0; i < lines.length; i += 1) {
  90. this.#currentGrid.splice(lines[i], 1);
  91. this.#currentGrid.unshift(this.getEmptyLine(this.#currentGrid[0].length));
  92. }
  93. scoreManager.addLinesRemovedPoints(lines.length);
  94. }
  95. /**
  96. * Gets the lines to clear around the given piece's coordinates.
  97. * The piece's coordinates are used for optimization and to prevent checking the whole grid.
  98. *
  99. * @param pos The piece's coordinates to check lines at
  100. * @return {Array<number>} An array containing the line numbers to clear
  101. */
  102. getLinesToClear(pos: Array<CoordinatesType>): Array<number> {
  103. const rows = [];
  104. for (let i = 0; i < pos.length; i += 1) {
  105. let isLineFull = true;
  106. for (let col = 0; col < this.#currentGrid[pos[i].y].length; col += 1) {
  107. if (this.#currentGrid[pos[i].y][col].isEmpty) {
  108. isLineFull = false;
  109. break;
  110. }
  111. }
  112. if (isLineFull && rows.indexOf(pos[i].y) === -1) {
  113. rows.push(pos[i].y);
  114. }
  115. }
  116. return rows;
  117. }
  118. /**
  119. * Freezes the given piece to the grid
  120. *
  121. * @param currentObject The piece to freeze
  122. * @param scoreManager A reference to the score manager
  123. */
  124. freezeTetromino(currentObject: Piece, scoreManager: ScoreManager) {
  125. this.clearLines(
  126. this.getLinesToClear(currentObject.getCoordinates()),
  127. scoreManager,
  128. );
  129. }
  130. }