package net.hoo2.auth.dsproject.snake; /** * @mainpage * @title Snake game project. -- Part 2 -- * * This is the code documentation page of the Snake game project. * Listed are: * * All used classes * * All member functions * * All data members * * @author Christos Choutouridis AEM:8997 * @email cchoutou@ece.auth.gr */ import java.util.*; /** * @class Game * * @brief This is the main control class of the game. * * This class includes the main function.Using this class's api * the user can create a board, register players and roll the game. * * @author Christos Choutouridis AEM:8997 * @email cchoutou@ece.auth.gr */ public class Game { /** @name Constants */ /**@{ */ static final int MAX_PLAYERS = 6; /**< The maximum number of allowed players in the game */ static final int MAX_GAME_ROUNDS = 1000; /**< the maximum allowed round of the game */ /**@} */ /** @name Private data members */ /** @{ */ private int round; /**< The current round of the game */ private Board board; /**< A reference to board */ private ArrayList players; /**< A reference to players */ private Map playingOrder; /**< A Map with {PlayerID, Dice-roll} pairs @note This way of storing the playing order is unnecessary. The old style was far more better. We had a turn variable in each Player and we used to sort the players vector based on that value. This made the rest of the program simpler, faster, easer. We have adopt the above approach just because it is one of the homework requirements. */ /** @} */ /** @name private api */ /** @{ */ /** * Search the players already in the pairs vector and compare their turn to play * with the result of a dice. If there is another one with the same dice result return true. * * @param roll The dice result to check in order to find player's turn to play * @param pairs Reference to already register players and their dice result * @return True if there is another player with the same dice result */ private boolean _search (int roll, ArrayList pairs) { for (int i =0; i pairs) { Integer[] temp; for (int i=pairs.size()-1 ; i>0 ; --i) { for (int j =0 ; j pairs.get(i)[1]) { temp = pairs.get(i); pairs.set(i, pairs.get(j)); pairs.set(j, temp); } } } } /** * Helper function to get a player from players vector using it's ID * @param playerId The player's ID to seek * @return Reference to Player or null */ private Player _getPlayer(int playerId) { for (Player p : players) { if (p.getPlayerId() == playerId) return p; } return null; } /** @} */ /** @name Constructors */ /** @{ */ /** Default doing nothing constructor */ Game () { round = 0; board = new Board(); players = new ArrayList<>(); playingOrder = new HashMap(); } /** * @brief The main constructor * This constructor create a board and prepares the board for the game. * After this call the user can call @ref registerPlayer() * @param N The row for the board * @param M The columns of the board * @param numOfSnakes Number of snakes to place * @param numOfLadders Number of ladders to place * @param numOfApples Number of Apples to place */ Game (int N, int M, int numOfSnakes, int numOfLadders, int numOfApples) { round = 0; // delegate constructors board = new Board (N, M, numOfSnakes, numOfLadders, numOfApples); players = new ArrayList<>(); playingOrder = new HashMap(); } /** @} */ /** @name Get/Set interface */ /** @{ */ int getRound () { return round; } void setRound (int round) { this.round = round; } /** Get reference to board */ Board getBoard () { return board; } /** Set board * @param board Reference to board to use * @note This requires board must be allocated elsewhere. */ void setBoard (Board board) { this.board = board; } /** Get reference to players */ ArrayList getPlayers() { return players; } /** * Set players * @param players Reference to players to use * @note This requires players must be allocated elsewhere. */ void setPlayers(ArrayList players) { this.players = players; } /** Get reference to playingOrder Map */ Map getPlayingOrder () { return playingOrder; } /** Set the playingOrder Map */ void setPlayingOrder (Map playingOrder) { this.playingOrder = playingOrder; } /** @} */ /** @name Public functionality */ /** @{ */ /** * Register a player to the game * @param playerId The player ID to use * @param name The player name to use * @return The status of the operation */ boolean registerPlayer (int playerId, String name) { if (players.size() >= MAX_PLAYERS) return false; players.add(new Player(playerId, name, board)); return true; } /** * Register a heuristic player to the game * @param playerId The player ID to use * @param name The player name to use * @return The status of the operation */ boolean registerHeuristicPlayer (int playerId, String name) { if (players.size() >= MAX_PLAYERS) return false; players.add(new HeuristicPlayer(playerId, name, board)); return true; } /** * @brief Set the playing order of players * This function emulates the classic roll of dice to decide which player * plays first which second and so on. */ Map setTurns (ArrayList players) { int[] pairData = new int[2]; // We use plain int[] to create an Integer[] Integer[] PairData; // The Integer[] to push to ArrayList<> ArrayList pairList = new ArrayList<>(); // Use use ArrayList before Map in order to sort for (int d, i =0 ; i Integer.compare (p1.getScore(), p2.getScore()) ); } /** * A game round. In each round every player plays when is his turn * * @param verbose Flag to indicate how much we print to console * @return The winner if we have one, or null */ Player round (boolean verbose) { int tile; ++round; // keep track of round // traverse the players vector and move each player on the board // using a dice throw for (Integer pid : playingOrder.keySet()) { Player p = _getPlayer(pid); tile = p.getNextMove (p.getTile()); p.statistics(verbose, false); if (tile>= board.getN()*board.getM()) // The first one here is the winner return p; } return null; // No one finished yet } /** @} */ /** * @brief Main * As the requirements of the project suggested. * We: * * Create a game * * Manually create a board * * Register 2 players (John Doe for now) * * Place a predefined number of snakes, ladders and apples * * Deploy the game by calling @ref playOrder() and @ref round() * At the end we print the results and exit */ public static void main(String[] args) { // Current project requirements int lines = 20; int columns = 10; int numOfSnakes = 3; int numOfLadders = 3; int numOfApples = 6; int numOfPlayers = 2; boolean verbose = false; // Print caption System.out.println("================== Snake Game =================="); System.out.println("Board: " +lines +"x" +columns +" with " +numOfSnakes +" snakes, " +numOfLadders +" ladders and " +numOfApples +" apples."); System.out.println("Players: " + numOfPlayers); System.out.println(""); // Board creation Game game = new Game (lines, columns, numOfSnakes, numOfLadders, numOfApples); // game.getBoard().createElementBoard(); // Not explicitly required // Player registration, the one is cheater for (int i=0 ; i=0 ; --i) { // Loop all players Player p = game.getPlayers().get(i); if (p == winner) System.out.println(" * " +p.getName() + ": " + p.getScore() +" points"); else System.out.println(" " +p.getName() + ": " + p.getScore() +" points"); } // Print the extra statistics for the heuristic player only // We use a little reflection for that for (Player p : game.getPlayers()) { if (p.getClass().getSimpleName().equals("HeuristicPlayer")) p.statistics(verbose, true); } } }