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.

225 lines
7.9 KiB

  1. /**
  2. * @file Tile.java
  3. *
  4. * @author Christos Choutouridis AEM:8997
  5. * @email cchoutou@ece.auth.gr
  6. */
  7. package net.hoo2.auth.labyrinth;
  8. /**
  9. * @brief
  10. * This class is the representation of the board's tile
  11. *
  12. * Tiles are arranged on the board in square shape and they're identified by
  13. * an ID. This ID is the linear combination of x and y coordinate of the tile.
  14. */
  15. class Tile {
  16. /** @name Constructors */
  17. /** @{ */
  18. /**
  19. * The main constructor of the Tile constructed from (x,y)
  20. *
  21. * @param x The x coordinate to place the Tile
  22. * @param y The y coordinate to place the Tile
  23. * @param up The existence of wall north of the tile
  24. * @param down The existence of wall south of the tile
  25. * @param left The existence of wall left of the tile
  26. * @param right The existence of wall right of the tile
  27. */
  28. protected Tile(int x, int y, boolean up, boolean down, boolean left, boolean right) {
  29. // Boundary checks
  30. assert (x >= 0 && x< Defaults.boardSize) : "X coordinate must be in the range [0, Defaults.boardSize)";
  31. assert (x >= 0 && x< Defaults.boardSize) : "Y coordinate must be in the range [0, Defaults.boardSize)";
  32. // Initialization
  33. this.tileId = Position.toID(x, y);
  34. this.x =x;
  35. this.y =y;
  36. this.up = up;
  37. this.down = down;
  38. this.left = left;
  39. this.right = right;
  40. }
  41. /**
  42. * The main constructor of the Tile constructed from tileId
  43. *
  44. * @param id The tileId to place the Tile
  45. * @param up The existence of wall north of the tile
  46. * @param down The existence of wall south of the tile
  47. * @param left The existence of wall left of the tile
  48. * @param right The existence of wall right of the tile
  49. */
  50. protected Tile(int id, boolean up, boolean down, boolean left, boolean right) {
  51. // Boundary check
  52. assert (id >= 0 && id <= Position.toID(Defaults.boardSize-1, Defaults.boardSize-1))
  53. : "TileId must be in the range of [0, Defaults.boardSize^2)";
  54. // Initialization
  55. this.tileId = id;
  56. this.x =Position.toX(id);
  57. this.y =Position.toY(id);
  58. this.up = up;
  59. this.down = down;
  60. this.left = left;
  61. this.right = right;
  62. }
  63. /**
  64. * A deep copy constructor.
  65. */
  66. protected Tile (Tile t) {
  67. this.tileId = t.tileId;
  68. this.x = t.x;
  69. this.y = t.y;
  70. this.up = t.up;
  71. this.down = t.down;
  72. this.left = t.left;
  73. this.right = t.right;
  74. // We achieve deep copy as the members are all primitives.
  75. }
  76. /** @} */
  77. /** @name Supply's main application interface */
  78. /** @{ */
  79. /**
  80. * @return the position of the tile as a Position object
  81. * @see Position
  82. */
  83. protected Position position () { return new Position (x, y); }
  84. /**
  85. * Set the position of the tile from a (x, y) pair
  86. * @param x The x coordinate of the tile
  87. * @param y The y coordinate of the tile
  88. * @return the position of the supply as a Position object
  89. * @note This function also returns the supplyId to help in chained expressions.
  90. * @see Position
  91. */
  92. protected Position position (int x, int y) {
  93. // Boundary checks
  94. assert (x >= 0 && x< Defaults.boardSize) : "X coordinate must be in the range [0, Defaults.boardSize)";
  95. assert (x >= 0 && x< Defaults.boardSize) : "Y coordinate must be in the range [0, Defaults.boardSize)";
  96. Position p = new Position (x, y);
  97. this.x = x;
  98. this.y = y;
  99. this.tileId = p.getID();
  100. return p;
  101. }
  102. /**
  103. * Set the position of the tile from a tileId
  104. * @param tileId The tileId position
  105. * @return The position of the supply as Position object
  106. * @note This function also returns the supplyId to help in chained expressions.
  107. * @see Position
  108. */
  109. protected int position (int tileId) {
  110. // Boundary check
  111. assert (tileId >= 0 && tileId <= Position.toID(Defaults.boardSize-1, Defaults.boardSize-1))
  112. : "TileId must be in the range of [0, Defaults.boardSize^2)";
  113. this.x = Position.toX(tileId);
  114. this.y = Position.toY(tileId);
  115. this.tileId = tileId;
  116. return tileId;
  117. }
  118. /** @return The tileId */
  119. protected int positionId () { return tileId; }
  120. /**
  121. * Set the tile's walls
  122. * @param up Request for north wall (winter is coming)
  123. * @param down Request for south wall
  124. * @param left Request for west wall
  125. * @param right Request for east wall
  126. */
  127. protected void setWalls (boolean up, boolean down, boolean left, boolean right) {
  128. assert (
  129. ((up?1:0) + (down?1:0) + (left?1:0) + (right?1:0)) <=2
  130. ) : "A tile can have at most 2 walls";
  131. this.up = up;
  132. this.down = down;
  133. this.left = left;
  134. this.right = right;
  135. }
  136. /**
  137. * Checks if the tile has wall in the requested direction
  138. * @param direction The direction to check
  139. * @return True if there is a wall
  140. */
  141. protected boolean hasWall (int direction) {
  142. switch (direction) {
  143. case Direction.UP: return up;
  144. case Direction.RIGHT: return right;
  145. case Direction.DOWN: return down;
  146. case Direction.LEFT: return left;
  147. }
  148. return false;
  149. }
  150. /** @} */
  151. /**
  152. * @name Accessor/Mutator interface
  153. * @note
  154. * Please consider not to use mutator interface. Its the abstraction killer :(
  155. * We have added a bit of logic however, in order to make it a bit more safe.
  156. */
  157. /** @{ */
  158. protected int getTileId () { return tileId; }
  159. protected int getX () { return x; }
  160. protected int getY () { return y; }
  161. protected boolean getUp () { return up; }
  162. protected boolean getDown () { return down; }
  163. protected boolean getLeft () { return left; }
  164. protected boolean getRight () { return right; }
  165. protected void setTileId(int tileId) {
  166. assert (tileId >= 0 && tileId <= Position.toID(Defaults.boardSize-1, Defaults.boardSize-1))
  167. : "TileId must be in the range of [0, Defaults.boardSize^2)";
  168. this.tileId = tileId;
  169. this.x = Position.toX(tileId);
  170. this.y = Position.toY(tileId);
  171. }
  172. protected void setX(int x) {
  173. assert (x >= 0 && x< Defaults.boardSize) : "X coordinate must be in the range [0, Defaults.boardSize)";
  174. this.x = x;
  175. this.tileId = Position.toID(this.x, this.y);
  176. }
  177. protected void setY(int y) {
  178. assert (y >= 0 && y< Defaults.boardSize) : "X coordinate must be in the range [0, Defaults.boardSize)";
  179. this.y = y;
  180. this.tileId = Position.toID(this.x, this.y);
  181. }
  182. protected void setUp(boolean up) { this.up = up; }
  183. protected void setDown(boolean down) { this.down = down; }
  184. protected void setRight(boolean right) { this.right = right; }
  185. protected void setLeft(boolean left) { this.left = left; }
  186. /** @} */
  187. /** @name Class data */
  188. /** @{ */
  189. private int tileId; /**<
  190. * The unique identifier of the tile. This is the linear combination of
  191. * x and y coordinates of the tile
  192. */
  193. private int x; /**< The x coordinate of the tile as if the board lies in the 1st quadrant */
  194. private int y; /**< The y coordinate of the tile as if the board lies in the 1st quadrant */
  195. private boolean up; /**< Indicator of a wall in the north side of the tile */
  196. private boolean down; /**< Indicator of a wall in the south side of the tile */
  197. private boolean left; /**< Indicator of a wall in the left side of the tile */
  198. private boolean right; /**< Indicator of a wall in the right side of the tile */
  199. /**
  200. * @warning
  201. * We can calculate tileId from (x,y) so having both (x,y) and tile ID is error
  202. * prone and not a good practice. Its easy to get them out of sync(code smell).
  203. * We implement it just because its in the requirements of the assignment.
  204. * @see Supply.supplyTileId
  205. */
  206. }