Coverage Summary for Class: Game (it.polimi.ingsw.Server.Model)

Class Class, % Method, % Line, %
Game 100% (1/1) 100% (22/22) 96,4% (162/168)


 package it.polimi.ingsw.Server.Model;
 
 import it.polimi.ingsw.Common.CommonGoalCardInterface;
 import it.polimi.ingsw.Common.PersonalGoalCardInterface;
 import it.polimi.ingsw.Common.ShelfInterface;
 
 import java.rmi.RemoteException;
 import java.util.*;
 import java.util.stream.Collectors;
 
 /**
  * This class contains general information about the current game, such as CommonGoalCards and number of Players.
  */
 public class Game {
     /**
      * final attribute, which indicates the maximum number of players who can join a game
      */
     public final int MAX_PLAYERS = 4;
     /**
      * Identifier is the game id. It is chosen by the first player, who joins the game, and it can be used by other players to
      * join a pre-existing game
      */
     private final String identifier;
     /**
      * Map used to store Players, associated to an Integer key, which indicates their position in the game
      */
     private final Map<Integer, Player> players;
     /**
      * Number of players, chosen by the first player, when he/she creates a new game
      */
     private final int maxPlayers;
     /**
      * List of personalCards associated to each player
      */
     private final List<PersonalGoalCard> personalCards;
     /**
      * Game scoreboard
      */
     private Scoreboard scoreboard = null;
     /**
      * board used in the game
      */
     private Board board;
     /**
      * number of players who have already joined the game
      */
     private int playerCount;
     /**
      * It's the first CommonGoalCard drawn for the game
      */
     private CommonGoalCard cgCard1;
     /**
      * It's the second CommonGoalCard drawn for the game
      */
     private CommonGoalCard cgCard2;
     /**
      * Object Cards extracted in the related game
      */
     private List<ObjectCard> objectCards;
     /**
      * this attribute is true if a player has already filled his/her shelf, false otherwise
      */
     private boolean gameEnded = false;
     /**
      * this attribute is true if the game has started
      */
     private boolean prepared = false;
 
     /**
      * game constructor
      *
      * @param identifier ID of the game, chosen by the Player who creates the game
      * @param maxPlayers maximum number of players, who can join the game (chosen by the first player)
      * @throws Exception if the maximum number of players is higher than the MAX_PLAYERS number
      */
 
     public Game(String identifier, int maxPlayers) throws Exception {
         if (maxPlayers > MAX_PLAYERS)
             throw new Exception();
         this.identifier = identifier;
         this.maxPlayers = maxPlayers;
         this.players = new HashMap<>();
         this.objectCards = new ArrayList<>();
         this.board = new Board(maxPlayers, objectCards);
         this.personalCards = new ArrayList<>();
         this.gameEnded = false;
     }
 
     /**
      * Related to Game's refresh strategy
      */
     public Game(String identifier, Map<Integer, Player> players, int maxPlayers, List<PersonalGoalCard> personalCards, Scoreboard scoreboard, Board board, int playerCount, CommonGoalCard cgCard1, CommonGoalCard cgCard2, List<ObjectCard> objectCards, boolean gameEnded, boolean prepared) {
         this.identifier = identifier;
         this.players = players;
         this.maxPlayers = maxPlayers;
         this.personalCards = personalCards;
         this.scoreboard = scoreboard;
         this.board = board;
         this.playerCount = playerCount;
         this.cgCard1 = cgCard1;
         this.cgCard2 = cgCard2;
         this.objectCards = objectCards;
         this.gameEnded = gameEnded;
         this.prepared = prepared;
     }
 
     /**
      * Getter method for the board
      *
      * @return Board
      */
     public Board getBoard() {
         return board;
     }
 
     /**
      * Getter method for the attribute, which indicates the maximum number of players, who can join the game
      *
      * @return maxPlayers
      */
     public int getMaxPlayers() {
         return maxPlayers;
     }
 
     /**
      * Getter method for players. An integer is associated to each Player, who is playing the game
      *
      * @return a map of Players
      */
     public Map<Integer, Player> getPlayers() {
         return players;
     }
 
     /**
      * This method adds a new player to "players" Map.
      *
      * @param newNickname player's nickname
      * @return Player who's been added to players
      * @throws RemoteException if the new instance of class Player hasn't been created
      */
     public Player newPlayer(String newNickname) throws RemoteException {
         Player ret = new Player(newNickname);
         players.put(playerCount++, ret);
         return ret;
     }
 
     /**
      * getter method to recognize a player from nickname
      *
      * @param nickname player's nickname
      * @return players if nickname != null, null otherwise
      */
     public Player getPlayerFromNickname(String nickname) {
         if (nickname != null && players
                 .values()
                 .stream()
                 .anyMatch(p -> p.getNickname().equals(nickname))) {
             return players
                     .values()
                     .stream()
                     .filter(p -> p.getNickname().equals(nickname))
                     .findFirst()
                     .orElseThrow();
         } else return null;
     }
 
     /**
      * this method is a getter for the shelf interface obtained from nickname
      *
      * @param nickname player's nickname
      * @return player's shelf interface
      */
     public ShelfInterface getShelfInterfaceFromNickname(String nickname) {
         if (getPlayers()
                 .values()
                 .stream()
                 .map(Player::getNickname)
                 .toList()
                 .contains(nickname)) {
             return getPlayers()
                     .values()
                     .stream()
                     .filter(p -> p.getNickname().equals(nickname))
                     .map(Player::getShelf)
                     .findFirst()
                     .orElseThrow();
         } else return null;
     }
 
     /**
      * this method is a getter of PersonalGoalCard obtained from nickname
      *
      * @param nickname player's nickname
      * @return player's PersonalGoalCard
      */
     public PersonalGoalCardInterface getPersonalGoalCardInterfaceFromNickname(String nickname) {
         if (getPlayers()
                 .values()
                 .stream()
                 .map(Player::getNickname)
                 .toList()
                 .contains(nickname)) {
             return getPlayers()
                     .values()
                     .stream()
                     .filter(p -> p.getNickname().equals(nickname))
                     .map(Player::getPersonalGoalCard)
                     .findFirst()
                     .orElseThrow();
         } else return null;
     }
 
     /**
      * this method is a getter for CommonGoalCards
      *
      * @return a list of CommonGoalCards
      */
     public List<CommonGoalCardInterface> getCommonGoalCards() {
         return Arrays.asList(cgCard1, cgCard2);
     }
 
     /**
      * this method is a getter for player's shelf obtained from nickname
      *
      * @param nickname player's nickname
      * @return player's shelf
      */
     public Shelf getShelfFromNickname(String nickname) {
         if (getPlayers()
                 .values()
                 .stream()
                 .map(Player::getNickname)
                 .toList()
                 .contains(nickname)) {
             return getPlayers()
                     .values()
                     .stream()
                     .filter(p -> p.getNickname().equals(nickname))
                     .map(Player::getShelf)
                     .findFirst()
                     .orElseThrow();
         } else return null;
     }
 
     /**
      * this method is a getter for ScoreCards obtained from Nickname
      *
      * @param nickname player's nickname
      * @return a stack of player's ScoreCard
      */
     public Stack<ScoreCard> getScoreCardsFromNickname(String nickname) {
         if (getPlayers()
                 .values()
                 .stream()
                 .map(Player::getNickname)
                 .toList()
                 .contains(nickname)) {
             return getPlayers()
                     .values()
                     .stream()
                     .filter(p -> p.getNickname().equals(nickname))
                     .map(Player::getScoreCards)
                     .findFirst()
                     .orElseThrow();
         } else return null;
     }
 
     /**
      * This method returns a list of nicknames of the players, who are playing a game (if game isn't null), null otherwise
      *
      * @return a list of player's nicknames
      */
     public List<String> nicknames() {
         return getPlayers()
                 .values()
                 .stream()
                 .map(Player::getNickname)
                 .toList();
     }
 
     /**
      * This method includes setup procedures, such as drawing personal goal cards and common goal cards,
      * choosing randomly the first player and placing ObjectCards on the board.
      *
      * @throws Exception if the number of drawn personal goal cards has exceeded the limit
      */
     public void prepareGame() throws Exception {
         if (!prepared) {
             if (personalCards.size() > PersonalGoalCard.LIMIT)
                 throw new Exception();
 
             Random r = new Random();
 
             int cardType1 = -1;
             int cardType2 = -1;
             while (cardType1 == cardType2) {
                 cardType1 = r.nextInt(1, CommonGoalCard.LIMIT + 1);
                 cardType2 = r.nextInt(1, CommonGoalCard.LIMIT + 1);
             }
             cgCard1 = new CommonGoalCard(cardType1, maxPlayers);
             cgCard2 = new CommonGoalCard(cardType2, maxPlayers);
 
             for (Integer index : players.keySet()) {
                 int personalType;
                 do {
                     personalType = r.nextInt(1, PersonalGoalCard.LIMIT + 1);
                 }
                 while (personalCards.stream().map(PersonalGoalCard::getType).toList().contains(personalType));
                 PersonalGoalCard pgc = new PersonalGoalCard(personalType);
                 personalCards.add(pgc);
                 new ArrayList<>(players.values()).get(index).setGameParameters(pgc, cgCard1, cgCard2, board);
             }
 
             List<Player> support = new ArrayList<>(players.values());
             players.clear();
             Collections.shuffle(support);
             int counter = 0;
             for (Player p : support) {
                 p.setPosition(counter);
                 players.put(counter++, p);
             }
         }
         prepared = true;
     }
 
     /**
      * This method indicates if the game is prepared
      *
      * @return true if the game is prepared, false otherwise
      */
     public boolean isPrepared() {
         return prepared;
     }
 
     /**
      * This method checks if the active player has completely filled his/her shelf
      *
      * @param activePlayer represents the player who is playing in the current turn
      * @return true if the player has filled all the spaces, false otherwise
      * @throws Exception If the coordinates are invalid
      */
     public boolean checkEndGame(Player activePlayer) throws Exception {
         if (gameEnded) {
             return true;
         }
         if (activePlayer.getShelf().isFull()) {
             activePlayer.firstShelfFull();
             this.gameEnded = true;
             return true;
         }
         return false;
     }
 
     /**
      * This method is used for endgame procedures, such as final scoring.
      *
      * @return true if the game is completed, false otherwise
      * @throws Exception if updateScore() throws an Exception
      */
     public boolean gameComplete() throws Exception {
         if (gameEnded && players
                 .values()
                 .stream()
                 .filter(x -> !x.isInGame())
                 .count() == playerCount) {
             if (this.scoreboard == null) {
                 for (Player p : getPlayers().values()) {
                     p.updateScore();
                 }
                 Map<String, Integer> unsortedPointMap = players.entrySet()
                         .stream()
                         .collect(Collectors.toMap(
                                 e -> e.getValue().getNickname(),
                                 e -> e.getValue().getScore()
                         ));
                 this.scoreboard = new Scoreboard(unsortedPointMap);
             }
             return true;
         } else return false;
     }
 
     /**
      * this method is a getter for attribute scoreboard
      *
      * @return scoreboard
      */
     public Scoreboard getScoreboard() {
         return scoreboard;
     }
 
     /**
      * this method is a getter for attribute gameEnded
      *
      * @return true if game has ended, false otherwise
      */
     public boolean isGameEnded() {
         return gameEnded;
     }
 
     /**
      * Objects refresh following a game reloaded from a persistency file
      *
      * @return the refreshed game
      * @throws RemoteException Related to RMI
      */
     public Game refreshEntities() throws RemoteException {
         this.board = board.getCopy();
         this.objectCards = board.getObjectCards();
         this.cgCard1 = cgCard1.getCopy();
         this.cgCard2 = cgCard2.getCopy();
         for (Player p : players.values()) {
             p.refreshEntities(cgCard1, cgCard2);
         }
         return new Game(this.identifier, this.players, this.maxPlayers, this.personalCards, this.scoreboard, this.board, this.playerCount, this.cgCard1, this.cgCard2, this.objectCards, this.gameEnded, this.prepared);
     }
 }