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.

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