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.

270 lines
9.2 KiB

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