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.

BaseShape.js 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // @flow
  2. export type coordinates = {
  3. x: number,
  4. y: number,
  5. }
  6. /**
  7. * Abstract class used to represent a BaseShape.
  8. * Abstract classes do not exist by default in Javascript: we force it by throwing errors in the constructor
  9. * and in methods to implement
  10. */
  11. export default class BaseShape {
  12. #currentShape: Array<Array<number>>;
  13. #rotation: number;
  14. position: coordinates;
  15. /**
  16. * Prevent instantiation if classname is BaseShape to force class to be abstract
  17. */
  18. constructor() {
  19. if (this.constructor === BaseShape)
  20. throw new Error("Abstract class can't be instantiated");
  21. this.#rotation = 0;
  22. this.position = {x: 0, y: 0};
  23. this.#currentShape = this.getShapes()[this.#rotation];
  24. }
  25. /**
  26. * Gets this shape's color.
  27. * Must be implemented by child class
  28. */
  29. getColor(): string {
  30. throw new Error("Method 'getColor()' must be implemented");
  31. }
  32. /**
  33. * Gets this object's all possible shapes as an array.
  34. * Must be implemented by child class.
  35. *
  36. * Used by tests to read private fields
  37. */
  38. getShapes(): Array<Array<Array<number>>> {
  39. throw new Error("Method 'getShapes()' must be implemented");
  40. }
  41. /**
  42. * Gets this object's current shape.
  43. *
  44. * Used by tests to read private fields
  45. */
  46. getCurrentShape(): Array<Array<number>> {
  47. return this.#currentShape;
  48. }
  49. /**
  50. * Gets this object's coordinates.
  51. * This will return an array of coordinates representing the positions of the cells used by this object.
  52. *
  53. * @param isAbsolute Should we take into account the current position of the object?
  54. * @return {Array<coordinates>} This object cells coordinates
  55. */
  56. getCellsCoordinates(isAbsolute: boolean): Array<coordinates> {
  57. let coordinates = [];
  58. for (let row = 0; row < this.#currentShape.length; row++) {
  59. for (let col = 0; col < this.#currentShape[row].length; col++) {
  60. if (this.#currentShape[row][col] === 1)
  61. if (isAbsolute)
  62. coordinates.push({x: this.position.x + col, y: this.position.y + row});
  63. else
  64. coordinates.push({x: col, y: row});
  65. }
  66. }
  67. return coordinates;
  68. }
  69. /**
  70. * Rotate this object
  71. *
  72. * @param isForward Should we rotate clockwise?
  73. */
  74. rotate(isForward: boolean) {
  75. if (isForward)
  76. this.#rotation++;
  77. else
  78. this.#rotation--;
  79. if (this.#rotation > 3)
  80. this.#rotation = 0;
  81. else if (this.#rotation < 0)
  82. this.#rotation = 3;
  83. this.#currentShape = this.getShapes()[this.#rotation];
  84. }
  85. /**
  86. * Move this object
  87. *
  88. * @param x Position X offset to add
  89. * @param y Position Y offset to add
  90. */
  91. move(x: number, y: number) {
  92. this.position.x += x;
  93. this.position.y += y;
  94. }
  95. }