|
- 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<Player> players; /**< A reference to players */
- private Map<Integer, Integer> 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<Integer[]> pairs) {
- for (int i =0; i<pairs.size() ; ++i)
- if (pairs.get(i)[1] == roll)
- return true;
- return false;
- }
-
- /**
- * Sort the pairs vector using second parameter witch represent the
- * dice roll. We use bubblesort for the implementation.
- * @param pairs A vector with {PlayerId, dice-roll} pairs to sort
- */
- private void _sort (ArrayList<Integer[]> pairs) {
- Integer[] temp;
- for (int i=pairs.size()-1 ; i>0 ; --i) {
- for (int j =0 ; j<i ; ++j) {
- if (pairs.get(j)[1] > 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<Integer, Integer>();
- }
-
- /**
- * @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<Integer, Integer>();
- }
- /** @} */
-
- /** @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<Player> getPlayers() { return players; }
- /**
- * Set players
- * @param players Reference to players to use
- * @note This requires players must be allocated elsewhere.
- */
- void setPlayers(ArrayList<Player> players) {
- this.players = players;
- }
- /** Get reference to playingOrder Map */
- Map<Integer, Integer> getPlayingOrder () { return playingOrder; }
- /** Set the playingOrder Map */
- void setPlayingOrder (Map<Integer, Integer> 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<Integer, Integer> setTurns (ArrayList<Player> players) {
- int[] pairData = new int[2]; // We use plain int[] to create an Integer[]
- Integer[] PairData; // The Integer[] to push to ArrayList<>
- ArrayList<Integer[]>
- pairList = new ArrayList<>(); // Use use ArrayList before Map in order to sort
-
- for (int d, i =0 ; i<players.size() ; ++i) {
- do
- // Keep rolling the dice until we get a unique value
- d = players.get(i).dice ();
- while (_search (d, pairList));
- // Make Integer[] pair
- pairData[0] = players.get(i).getPlayerId();
- pairData[1] = d;
- PairData = Arrays.stream(pairData)
- .boxed()
- .toArray(Integer[]::new);
- pairList.add(PairData); // Add to vector
- }
- // Sort playeingOrger
- _sort (pairList);
- // Make and return the Map
- for (int i =0 ; i<pairList.size() ; ++i) {
- playingOrder.put(pairList.get(i)[0], pairList.get(i)[1]);
- }
- return playingOrder;
-
- }
- /**
- * Sort the players according to their score
- */
- void scoreSort () {
- players.sort((p1, p2) ->
- 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<numOfPlayers && i<MAX_PLAYERS; ++i) {
- if (i == 0)
- game.registerHeuristicPlayer(i+1, String.format("Player %d", i+1));
- else
- game.registerPlayer(i+1, String.format("Player %d", i+1));
- }
- game.setTurns(game.getPlayers()); // Choose play order
-
- Player winner;
- do // Keep going until someone finishes
- winner = game.round (verbose);
- while (winner == null
- && game.getRound() < MAX_GAME_ROUNDS);
- if (game.getRound() == MAX_GAME_ROUNDS) {
- // Check if we finished
- System.out.println("Game did not finished in " + MAX_GAME_ROUNDS + " rounds. Abort.");
- return;
- }
-
- // Print the results
- System.out.println("*** Game finished ***");
- System.out.println("");
- System.out.println("");
- System.out.println("*** Game Results ***");
- System.out.println("Rounds: " + game.getRound());
- System.out.println("Winner: " + winner.getName() + " [" + winner.getScore() +" points]");
- System.out.println("Score: ");
- game.scoreSort (); // sort players based on their score
- for (int i=game.getPlayers().size()-1 ; 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);
- }
-
- }
- }
|