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.

267 lines
9.1 KiB

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