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.

228 lines
8.1 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. int[] getLastMove () { return lastMove; }
  81. void setLastMove (int[] lastMove) {
  82. this.lastMove = lastMove;
  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 tile The initial tile
  97. * @return The tile after the move
  98. * @note
  99. * We add this move() wrapper in order to provide polymorphism to
  100. * Player class hierarchy and to be sure that we are not braking the
  101. * Liskov substitution principle
  102. * @see https://en.wikipedia.org/wiki/Liskov_substitution_principle
  103. */
  104. int getNextMove (int tile) {
  105. return move (tile, dice(), true)[MOVE_TILE_IDX];
  106. }
  107. /**
  108. * @brief Move functionality
  109. *
  110. * @param tile The initial tile of the player
  111. * @param roll The dice roll to play
  112. * @param run Flag to indicate if we fake the move(dry run) or we do make the move.
  113. * @return
  114. * int[MOVE_TILE_IDX (0)] tile after move
  115. * int[MOVE_INITTILE_IDX (1)] tile before move
  116. * int[MOVE_STEPS_IDX (2)] number of total steps for the move
  117. * int[MOVE_ROLL_IDX (3)] the roll of the dice
  118. * int[MOVE_POINTS_IDX (4)] the points of the move
  119. * int[MOVE_SNAKES_IDX (5)] number of snake bites
  120. * int[MOVE_LADDERS_IDX (6)] number of ladders used
  121. * int[MOVE_RED_APPLES_IDX (7)] number of red apples eaten
  122. * int[MOVE_BLACK_APPLES_IDX (8)] number of black apples eaten
  123. * @note
  124. * Probably a mutable class like: <pre>
  125. * class MoveData {
  126. * int tile;
  127. * int initTile;
  128. * ...
  129. * }
  130. * </pre>
  131. * for returning value would be better, less error prone, cleaner, etc...
  132. * We could also had members like: <pre> MoveData previous; </pre> to help us further.
  133. * We kept this representation just because it was a requirement.
  134. */
  135. int [] move (int tile, int roll, boolean run) {
  136. int t;
  137. Arrays.fill(dryMove, 0);
  138. dryMove[MOVE_INITTILE_IDX] = tile;
  139. dryMove[MOVE_ROLL_IDX] = roll;
  140. tile += roll; // Initial move
  141. boolean keepGoing;
  142. do {
  143. keepGoing = false;
  144. // Check apples
  145. if ((t = board.checkApple(tile, run)) != 0) {
  146. dryMove[MOVE_POINTS_IDX] += t;
  147. if (t > 0)
  148. ++dryMove[MOVE_RED_APPLES_IDX];
  149. else
  150. ++dryMove[MOVE_BLACK_APPLES_IDX];
  151. }
  152. // Check ladder
  153. if ((t = board.checkLadder(tile, run)) != tile) {
  154. tile = t;
  155. ++dryMove[MOVE_LADDERS_IDX];
  156. keepGoing = true;
  157. }
  158. // Check snakes
  159. if ((t = board.checkSnake(tile)) != tile) {
  160. tile = t;
  161. ++dryMove[MOVE_SNAKES_IDX];
  162. keepGoing = true;
  163. }
  164. } while (keepGoing);
  165. dryMove[MOVE_TILE_IDX] = tile;
  166. dryMove[MOVE_STEPS_IDX]= tile - dryMove[MOVE_INITTILE_IDX];
  167. // Check if we do run the move
  168. if (run) {
  169. lastMove = dryMove.clone();
  170. this.tile = lastMove[MOVE_TILE_IDX];
  171. score += lastMove[MOVE_POINTS_IDX];
  172. }
  173. return dryMove;
  174. }
  175. /**
  176. * The base statistics version
  177. * @param verbose Flag to select the verbosity
  178. * @param sum Flag to select if we need to print a summarize (not used here)
  179. * @note
  180. * We added this function because:
  181. * 1) we need to keep the "Is a" relationship (Liskov substitution principle)
  182. * 2) It help us get rid of the move() console output code
  183. * 3) makes the code smaller
  184. */
  185. void statistics (boolean verbose, boolean sum) {
  186. int begin = lastMove[MOVE_INITTILE_IDX];
  187. int roll = lastMove[MOVE_ROLL_IDX];
  188. int last = lastMove[MOVE_TILE_IDX];
  189. if (verbose)
  190. System.out.println(name + " +" + roll + "->tile: " + (begin + roll));
  191. if (lastMove[MOVE_RED_APPLES_IDX] > 0)
  192. System.out.println(name + " Apple " + lastMove[MOVE_POINTS_IDX] + " points");
  193. if (lastMove[MOVE_BLACK_APPLES_IDX] > 0)
  194. System.out.println(name + " Apple " + lastMove[MOVE_POINTS_IDX] + " points");
  195. if (lastMove[MOVE_LADDERS_IDX] > 0)
  196. System.out.println(name + " Ladder @" + (begin + roll) + " new position " + last);
  197. if (lastMove[MOVE_SNAKES_IDX] > 0)
  198. System.out.println(name + " Ouch!! Snake @" + (begin + roll) + " new position " + last);
  199. // No use of sum here
  200. }
  201. /**@} */
  202. /** @name Data members package access only */
  203. /** @{ */
  204. int playerId; /**< Player's ID */
  205. String name; /**< Player's name */
  206. int score; /**< Player's score */
  207. Board board; /**< Reference to current board */
  208. int tile; /**< Player's tile location */
  209. int[] lastMove; /**< move() return data for statistics. These are only valid after a true move */
  210. private int [] dryMove; /**< Fake (dry run) move return buffer */
  211. /** @} */
  212. }