A java snake game for A.U.TH. Data structures class
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

311 lignes
10 KiB

  1. package net.hoo2.auth.dsproject.snake;
  2. /**
  3. * @mainpage
  4. * @title Snake game project. -- Part 1 --
  5. *
  6. * This is the code documentation page of the Snake game project.
  7. * Listed are:
  8. * * All used classes
  9. * * All member functions
  10. * * All data members
  11. *
  12. * @author Christos Choutouridis AEM:8997
  13. * @email cchoutou@ece.auth.gr
  14. */
  15. import java.util.*;
  16. /**
  17. * @class Game
  18. *
  19. * @brief This is the main control class of the game.
  20. *
  21. * This class includes the main function.Using this class's api
  22. * the user can create a board, register players and roll the game.
  23. *
  24. * @author Christos Choutouridis AEM:8997
  25. * @email cchoutou@ece.auth.gr
  26. */
  27. public class Game {
  28. /** @name Constants */
  29. /**@{ */
  30. static final int MAX_PLAYERS = 6; /**< The maximum number of allowed players in the game */
  31. static final int MAX_GAME_ROUNDS = 1000; /**< the maximum allowed round of the game */
  32. /**@} */
  33. /** @name Private data members */
  34. /** @{ */
  35. private int round; /**< The current round of the game */
  36. private Board board; /**< A reference to board */
  37. private ArrayList<Player> players; /**< A reference to players */
  38. private Map<Integer, Integer> playingOrder;
  39. /** @} */
  40. /** @name private api */
  41. /** @{ */
  42. /**
  43. * Search the players already in the players vector and compare their turn to play
  44. * with the result of a dice. If there is another one with the same dice result return true.
  45. *
  46. * @param turn The dice result to check in order to find player's turn to play
  47. * @param players Reference to already register players
  48. * @return True if there is another player with the same dice result
  49. */
  50. private boolean _search (int die, ArrayList<Integer[]> pairs) {
  51. for (int i =0; i<pairs.size() ; ++i)
  52. if (pairs.get(i)[1] == die)
  53. return true;
  54. return false;
  55. }
  56. private void _sort (ArrayList<Integer[]> pairs) {
  57. Integer[] temp;
  58. for (int i=pairs.size()-1 ; i>0 ; --i) {
  59. for (int j =0 ; j<i ; ++j) {
  60. if (pairs.get(j)[1] > pairs.get(i)[1]) {
  61. temp = pairs.get(i);
  62. pairs.set(i, pairs.get(j));
  63. pairs.set(j, temp);
  64. }
  65. }
  66. }
  67. }
  68. private Player _getPlayer(int playerId) {
  69. for (Player p : players) {
  70. if (p.getPlayerId() == playerId)
  71. return p;
  72. }
  73. return null;
  74. }
  75. /** @} */
  76. /** @name Constructors */
  77. /** @{ */
  78. /** Default doing nothing constructor */
  79. Game () {
  80. round = 0;
  81. board = new Board();
  82. players = new ArrayList<>();
  83. playingOrder
  84. = new HashMap<Integer, Integer>();
  85. }
  86. /**
  87. * @brief The main constructor
  88. * This constructor create a board and prepares the board for the game.
  89. * After this call the user can call @ref registerPlayer()
  90. * @param N The row for the board
  91. * @param M The columns of the board
  92. * @param numOfSnakes Number of snakes to place
  93. * @param numOfLadders Number of ladders to place
  94. * @param numOfApples Number of Apples to place
  95. */
  96. Game (int N, int M, int numOfSnakes, int numOfLadders, int numOfApples) {
  97. round = 0;
  98. // delegate constructors
  99. board = new Board (N, M, numOfSnakes, numOfLadders, numOfApples);
  100. players = new ArrayList<>();
  101. playingOrder
  102. = new HashMap<Integer, Integer>();
  103. }
  104. /** @} */
  105. /** @name Get/Set interface */
  106. /** @{ */
  107. int getRound () { return round; }
  108. void setRound (int round) { this.round = round; }
  109. /** Get reference to board */
  110. Board getBoard () { return board; }
  111. /** Set board
  112. * @param board Reference to board to use
  113. * @note This requires board must be allocated elsewhere.
  114. */
  115. void setBoard (Board board) {
  116. this.board = board;
  117. }
  118. /** Get reference to players */
  119. ArrayList<Player> getPlayers() { return players; }
  120. /**
  121. * Set players
  122. * @param players Reference to players to use
  123. * @note This requires players must be allocated elsewhere.
  124. */
  125. void setPlayers(ArrayList<Player> players) {
  126. this.players = players;
  127. }
  128. Map<Integer, Integer> getPlayingOrder () { return playingOrder; }
  129. void setPlayingOrder (Map<Integer, Integer> playingOrder) {
  130. this.playingOrder = playingOrder;
  131. }
  132. /** @} */
  133. /** @name Public functionality */
  134. /** @{ */
  135. /**
  136. * Register a player to the game
  137. * @param playerId The player ID to use
  138. * @param name The player name to use
  139. * @return The status of the operation
  140. */
  141. boolean registerPlayer (int playerId, String name) {
  142. if (players.size() >= MAX_PLAYERS)
  143. return false;
  144. players.add(new Player(playerId, name, board));
  145. return true;
  146. }
  147. /**
  148. * Register a player to the game
  149. * @param playerId The player ID to use
  150. * @param name The player name to use
  151. * @return The status of the operation
  152. */
  153. boolean registerHeuristicPlayer (int playerId, String name) {
  154. if (players.size() >= MAX_PLAYERS)
  155. return false;
  156. players.add(new HeuristicPlayer(playerId, name, board));
  157. return true;
  158. }
  159. /**
  160. * @brief Set the playing order of players
  161. * This function emulates the classic roll of dice to decide which player
  162. * plays first which second and so on.
  163. */
  164. Map<Integer, Integer> setTurns (ArrayList<Player> players) {
  165. int[] pairData = new int[2];
  166. Integer[] PairData;
  167. ArrayList<Integer[]>
  168. pairList = new ArrayList<>();
  169. for (int d, i =0 ; i<players.size() ; ++i) {
  170. do
  171. d = players.get(i).dice ();
  172. while (_search (d, pairList));
  173. pairData[0] = players.get(i).getPlayerId();
  174. pairData[1] = d;
  175. PairData = Arrays.stream(pairData).boxed().toArray( Integer[]::new );
  176. pairList.add(PairData);
  177. }
  178. // Sort playeingOrger
  179. _sort (pairList);
  180. // Make and return the Map
  181. for (int i =0 ; i<pairList.size() ; ++i) {
  182. playingOrder.put(pairList.get(i)[0], pairList.get(i)[1]);
  183. }
  184. return playingOrder;
  185. }
  186. /**
  187. * Sort the players according to their score
  188. */
  189. void scoreSort () {
  190. players.sort((p1, p2) ->
  191. Integer.compare (p1.getScore(), p2.getScore())
  192. );
  193. }
  194. /**
  195. * A game round. In each round every player plays when is his turn
  196. *
  197. * @return The winner if we have one, or null
  198. */
  199. Player round (boolean verbose) {
  200. int tile;
  201. ++round; // keep track of round
  202. // traverse the players vector and move each player on the board
  203. // using a dice throw
  204. for (Integer pid : playingOrder.keySet()) {
  205. Player p = _getPlayer(pid);
  206. tile = p.getNextMove (p.getTile());
  207. p.statistics(verbose, false);
  208. if (tile>= board.getN()*board.getM())
  209. // The first one here is the winner
  210. return p;
  211. }
  212. return null; // No one finished yet
  213. }
  214. /** @} */
  215. /**
  216. * @brief Main
  217. * As the requirements of the project suggested.
  218. * We:
  219. * * Create a game
  220. * * Manually create a board
  221. * * Register 2 players (John Doe for now)
  222. * * Place a predefined number of snakes, ladders and apples
  223. * * Deploy the game by calling @ref playOrder() and @ref round()
  224. * At the end we print the results and exit
  225. */
  226. public static void main(String[] args) {
  227. // Current project requirements
  228. int lines = 20;
  229. int columns = 10;
  230. int numOfSnakes = 3;
  231. int numOfLadders = 3;
  232. int numOfApples = 6;
  233. int numOfPlayers = 2;
  234. boolean verbose = false;
  235. // Print caption
  236. System.out.println("================== Snake Game ==================");
  237. System.out.println("Board: " +lines +"x" +columns +" with " +numOfSnakes +" snakes, "
  238. +numOfLadders +" ladders and " +numOfApples +" apples.");
  239. System.out.println("Players: " + numOfPlayers);
  240. System.out.println("");
  241. // Board creation
  242. Game game = new Game (lines, columns, numOfSnakes, numOfLadders, numOfApples);
  243. // game.getBoard().createElementBoard(); // Not explicitly required
  244. // Player registration, the one is cheater
  245. for (int i=0 ; i<numOfPlayers && i<MAX_PLAYERS; ++i) {
  246. if (i == 0)
  247. game.registerHeuristicPlayer(i+1, String.format("Player %d", i+1));
  248. else
  249. game.registerPlayer(i+1, String.format("Player %d", i+1));
  250. }
  251. game.setTurns(game.getPlayers()); // Choose play order
  252. Player winner;
  253. do // Keep going until someone finishes
  254. winner = game.round (verbose);
  255. while (winner == null
  256. && game.getRound() < MAX_GAME_ROUNDS);
  257. if (game.getRound() == MAX_GAME_ROUNDS) {
  258. // Check if we finished
  259. System.out.println("Game did not finished in " + MAX_GAME_ROUNDS + " rounds. Abort.");
  260. return;
  261. }
  262. // Print the results
  263. System.out.println("*** Game finished ***");
  264. System.out.println("");
  265. System.out.println("");
  266. System.out.println("*** Game Results ***");
  267. System.out.println("Rounds: " + game.getRound());
  268. System.out.println("Winner: " + winner.getName() + " [" + winner.getScore() +" points]");
  269. System.out.println("Score: ");
  270. game.scoreSort (); // sort players based on their score
  271. for (int i=game.getPlayers().size()-1 ; i>=0 ; --i) {
  272. // Loop all players
  273. Player p = game.getPlayers().get(i);
  274. if (p == winner)
  275. System.out.println(" * " +p.getName() + ": " + p.getScore() +" points");
  276. else
  277. System.out.println(" " +p.getName() + ": " + p.getScore() +" points");
  278. }
  279. for (Player p : game.getPlayers()) {
  280. if (p.getClass().getSimpleName().equals("HeuristicPlayer"))
  281. p.statistics(verbose, true);
  282. }
  283. }
  284. }