A java snake game for A.U.TH. Data structures class
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.

236 lines
8.3 KiB

  1. package net.hoo2.auth.dsproject.snake;
  2. import java.util.Arrays;
  3. import java.lang.Math;
  4. /**
  5. * @class Player
  6. * @brief Represent a Player in the Game
  7. *
  8. * The players are playing in a round-robin sequence and we keep track
  9. * for each one of them their playing order, score and place on the board.
  10. *
  11. * @author Christos Choutouridis AEM:8997
  12. * @email cchoutou@ece.auth.gr
  13. */
  14. public class Player {
  15. /** Helper variables to keep track of the move() return values @see move() */
  16. static final int MOVE_DATA_SIZE = 9; /**< The move return data array size */
  17. static final int MOVE_TILE_IDX = 0; /**< The index of tile */
  18. static final int MOVE_INITTILE_IDX = 1; /**< The index of init tile */
  19. static final int MOVE_STEPS_IDX = 2; /**< The index of steps */
  20. static final int MOVE_ROLL_IDX = 3; /**< The index of roll */
  21. static final int MOVE_POINTS_IDX = 4; /**< The index of points */
  22. static final int MOVE_SNAKES_IDX = 5; /**< The index for number of snakes (Always <= 1) */
  23. static final int MOVE_LADDERS_IDX = 6; /**< The index for number of ladders (Always <= 1) */
  24. static final int MOVE_RED_APPLES_IDX = 7; /**< The index for number of red apples (Always <= 1) */
  25. static final int MOVE_BLACK_APPLES_IDX = 8; /**< The index for number of black apples (Always <= 1) */
  26. /** @name Constructors */
  27. /** @{ */
  28. /** Default doing nothing constructor */
  29. Player () {
  30. playerId = score = tile = 0;
  31. name = "";
  32. board = null;
  33. lastMove = new int[MOVE_DATA_SIZE];
  34. dryMove = new int[MOVE_DATA_SIZE];
  35. }
  36. /**
  37. * @brief The main constructor
  38. *
  39. * This creates a player for the game
  40. * @param playerId The player's to create
  41. * @param name The name of the player
  42. * @param board Reference to the board the player will play on.
  43. */
  44. Player (int playerId, String name, Board board) {
  45. this.playerId = playerId;
  46. this.name = name;
  47. this.board = board;
  48. score = 0;
  49. tile = 0;
  50. lastMove = new int[MOVE_DATA_SIZE];
  51. dryMove = new int[MOVE_DATA_SIZE];
  52. }
  53. /** @} */
  54. /** @name Get/Set interface */
  55. /** @{ */
  56. int getPlayerId () { return playerId; }
  57. void setPlayerId (int playerId) {
  58. this.playerId = playerId;
  59. }
  60. String getName () { return name; }
  61. void setName (String name) {
  62. this.name = name;
  63. }
  64. int getScore () { return score; }
  65. void setScore (int score) {
  66. this.score = score;
  67. }
  68. /** Get reference to Board */
  69. Board getBoard () { return board; }
  70. /** Set Board reference */
  71. void setBoard (Board board) {
  72. this.board = board;
  73. }
  74. /** Get tile */
  75. int getTile () { return tile; }
  76. /** Set tile */
  77. void setTile (int tile) {
  78. this.tile = tile;
  79. }
  80. /** Get lastMove */
  81. int[] getLastMove () { return lastMove; }
  82. /** Set lastMove */
  83. void setLastMove (int[] lastMove) {
  84. this.lastMove = lastMove;
  85. }
  86. /** Get dryMove */
  87. int[] getDryMove () { return dryMove; }
  88. /** Set dryMove */
  89. void setDryMove (int[] dryMove) {
  90. this.dryMove = dryMove;
  91. }
  92. /** @} */
  93. /** @name Exposed API members */
  94. /** @{ */
  95. /**
  96. * Dice functionality for the players
  97. * @return An integer in the range [1 .. 6]
  98. */
  99. int dice () {
  100. return (int)(1 + Math.random()*5);
  101. }
  102. /**
  103. * Get the next tile after the user's move
  104. * @param tile The initial tile
  105. * @return The tile after the move
  106. * @note
  107. * We add this move() wrapper in order to provide polymorphism to
  108. * Player class hierarchy and to be sure that we are not braking the
  109. * Liskov substitution principle
  110. * @see https://en.wikipedia.org/wiki/Liskov_substitution_principle
  111. */
  112. int getNextMove (int tile) {
  113. return move (tile, dice(), true)[MOVE_TILE_IDX];
  114. }
  115. /**
  116. * @brief Move functionality
  117. *
  118. * @param tile The initial tile of the player
  119. * @param roll The dice roll to play
  120. * @param run Flag to indicate if we fake the move(dry run) or we do make the move.
  121. * @return
  122. * int[MOVE_TILE_IDX (0)] tile after move
  123. * int[MOVE_INITTILE_IDX (1)] tile before move
  124. * int[MOVE_STEPS_IDX (2)] number of total steps for the move
  125. * int[MOVE_ROLL_IDX (3)] the roll of the dice
  126. * int[MOVE_POINTS_IDX (4)] the points of the move
  127. * int[MOVE_SNAKES_IDX (5)] number of snake bites
  128. * int[MOVE_LADDERS_IDX (6)] number of ladders used
  129. * int[MOVE_RED_APPLES_IDX (7)] number of red apples eaten
  130. * int[MOVE_BLACK_APPLES_IDX (8)] number of black apples eaten
  131. * @note
  132. * Probably a mutable class like: <pre>
  133. * class MoveData {
  134. * int tile;
  135. * int initTile;
  136. * ...
  137. * }
  138. * </pre>
  139. * for returning value would be better, less error prone, cleaner, etc...
  140. * We could also had members like: <pre> MoveData previous; </pre> to help us further.
  141. * We kept this representation just because it was a requirement.
  142. */
  143. int [] move (int tile, int roll, boolean run) {
  144. int t;
  145. Arrays.fill(dryMove, 0);
  146. dryMove[MOVE_INITTILE_IDX] = tile;
  147. dryMove[MOVE_ROLL_IDX] = roll;
  148. tile += roll; // Initial move
  149. boolean keepGoing;
  150. do {
  151. keepGoing = false;
  152. // Check apples
  153. if ((t = board.checkApple(tile, run)) != 0) {
  154. dryMove[MOVE_POINTS_IDX] += t;
  155. if (t > 0)
  156. ++dryMove[MOVE_RED_APPLES_IDX];
  157. else
  158. ++dryMove[MOVE_BLACK_APPLES_IDX];
  159. }
  160. // Check ladder
  161. if ((t = board.checkLadder(tile, run)) != tile) {
  162. tile = t;
  163. ++dryMove[MOVE_LADDERS_IDX];
  164. keepGoing = true;
  165. }
  166. // Check snakes
  167. if ((t = board.checkSnake(tile)) != tile) {
  168. tile = t;
  169. ++dryMove[MOVE_SNAKES_IDX];
  170. keepGoing = true;
  171. }
  172. } while (keepGoing);
  173. dryMove[MOVE_TILE_IDX] = tile;
  174. dryMove[MOVE_STEPS_IDX]= tile - dryMove[MOVE_INITTILE_IDX];
  175. // Check if we do run the move
  176. if (run) {
  177. lastMove = dryMove.clone();
  178. this.tile = lastMove[MOVE_TILE_IDX];
  179. score += lastMove[MOVE_POINTS_IDX];
  180. }
  181. return dryMove;
  182. }
  183. /**
  184. * The base statistics version
  185. * @param verbose Flag to select the verbosity
  186. * @param sum Flag to select if we need to print a summarize (not used here)
  187. * @note
  188. * We added this function because:
  189. * 1) we need to keep the "Is a" relationship (Liskov substitution principle)
  190. * 2) It help us get rid of the move() console output code
  191. * 3) makes the code smaller
  192. */
  193. void statistics (boolean verbose, boolean sum) {
  194. int begin = lastMove[MOVE_INITTILE_IDX];
  195. int roll = lastMove[MOVE_ROLL_IDX];
  196. int last = lastMove[MOVE_TILE_IDX];
  197. if (verbose)
  198. System.out.println(name + " +" + roll + "->tile: " + (begin + roll));
  199. if (lastMove[MOVE_RED_APPLES_IDX] > 0)
  200. System.out.println(name + " Apple " + lastMove[MOVE_POINTS_IDX] + " points");
  201. if (lastMove[MOVE_BLACK_APPLES_IDX] > 0)
  202. System.out.println(name + " Apple " + lastMove[MOVE_POINTS_IDX] + " points");
  203. if (lastMove[MOVE_LADDERS_IDX] > 0)
  204. System.out.println(name + " Ladder @" + (begin + roll) + " new position " + last);
  205. if (lastMove[MOVE_SNAKES_IDX] > 0)
  206. System.out.println(name + " Ouch!! Snake @" + (begin + roll) + " new position " + last);
  207. // No use of sum here
  208. }
  209. /**@} */
  210. /** @name Data members package access only */
  211. /** @{ */
  212. int playerId; /**< Player's ID */
  213. String name; /**< Player's name */
  214. int score; /**< Player's score */
  215. Board board; /**< Reference to current board */
  216. int tile; /**< Player's tile location */
  217. int[] lastMove; /**< move() return data for statistics. These are only valid after a true move */
  218. private int [] dryMove; /**< Fake (dry run) move return buffer */
  219. /** @} */
  220. }