Coverage Summary for Class: Board (it.polimi.ingsw.gc14.Model.GamePackage)

Class Class, % Method, % Branch, % Line, %
Board 100% (1/1) 100% (16/16) 96.7% (29/30) 100% (82/82)


 package it.polimi.ingsw.gc14.Model.GamePackage;
 
 import it.polimi.ingsw.gc14.Model.Cards.BuildingCard;
 import it.polimi.ingsw.gc14.Model.Cards.TribeCard;
 import it.polimi.ingsw.gc14.Model.Cards.TribeCards.EventCard;
 import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Events.ShamanicRitual;
 import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Events.Sustenance;
 import it.polimi.ingsw.gc14.Model.DecksCreator;
 import it.polimi.ingsw.gc14.Model.Slot;
 
 import java.io.Serializable;
 import java.util.*;
 import java.util.stream.Collectors;
 
 /**
  * Board manages all the elements during the game such as decks, upper and lower rows, totems, tiles...
  */
 public class Board implements Serializable {
     /**
      * slotList contains the ordered list of slots (tiles). The slots changes based on the number of players.
      * Each slot (tile) has special action as drawing from the upper/lower row or taking food.
      */
     private final List<Slot> slotList;
 
     /** tribeDeck is the deck from where you draw tribe cards as characters and events. */
     private final Queue<TribeCard> tribeDeck;
 
     /**
      * The upper row of tribe cards. It contains a total of
      * {@code nTotem + 4} tribe cards, which may include both character and event cards.
      */
     private final List<TribeCard> upperListTribe;
 
     /**
      * The lower row of the tribe card. During the first round, there will be (num. of players + 1) character cards.
      * During the following rounds, lower row will be emptied and populated with upper row's cards.
      * When an Event card gets in the lower row, the event effect will be activated at the end of the round.
      */
     private final List<TribeCard> lowerListTribe;
 
     /** Contains all the building cards of the upper list. When a new era starts, all its building cards are placed here. */
     private final List<BuildingCard> upperListBuilding;
 
     /** Contains all the building cards of the lower list. When a new era starts, the old era's buildings are moved from the upper to the lower list. */
     private final List<BuildingCard> lowerListBuilding;
 
     /**
      * Returns the upper row of tribe cards.
      *
      * @return the live upper tribe card list.
      */
     public List<TribeCard> getUpperListTribe() { return upperListTribe; }
 
     /**
      * Returns the lower row of tribe cards.
      *
      * @return the live lower tribe card list.
      */
     public List<TribeCard> getLowerListTribe() { return lowerListTribe; }
 
     /**
      * Returns the upper row of building cards.
      *
      * @return the live upper building card list.
      */
     public List<BuildingCard> getUpperListBuilding() { return upperListBuilding; }
 
     /**
      * Returns the lower row of building cards.
      *
      * @return the live lower building card list.
      */
     public List<BuildingCard> getLowerListBuilding() { return lowerListBuilding; }
 
     /** All building card lists grouped by era; index 0 = era 1, index 1 = era 2, etc. */
     private final ArrayList<List<BuildingCard>> buildingCardsAllEras;
     /** Number of players */
     private final int nTotem;
 
     /** Current era of the game */
     private int era;
 
     /**
      * Creates and returns a new list containing the slots (tiles) of the game.
      *
      * @return a copy of the slot list.
      */
     public List<Slot> getSlotList(){
         return slotList.stream().map(x->new Slot(x.getSlotId())).collect(Collectors.toList());
     }
 
     /**
      * @return the size of the TribeDeck
      */
     public int getTribeDeckSize() {
         return this.tribeDeck.size();
     }
 
     /**
      * @return the game era
      */
     public int getEra() {return this.era;}
 
 
     /**
      *  Creates and initializes a new board:
      *      - Generate the slotList using a method of DecksCreator.
      *      - Generate the tribeDeck.
      *      - Populate the lower list (if there is an event card, it's added to the upper list).
      *      - Populate the upper list.
      *      - Generate the buildingDeck using a method of DecksCreator.
      *
      * @param nTotem        the number of players.
      */
     public Board(int nTotem) {
         this.nTotem = nTotem;
         this.slotList = DecksCreator.loadSlotDeck().stream().filter(x->x.getNMinPlayer()<=nTotem).sorted(Comparator.comparingInt(Slot::getSlotId)).toList();
         upperListTribe=new ArrayList<>();
         lowerListTribe=new ArrayList<>();
         lowerListBuilding=new ArrayList<>();
         tribeDeck=generateTribeDeck(nTotem);
         era=1;
 
 
         for(int i=0;i<nTotem+1;i++)
         {
             TribeCard tempCard = tribeDeck.remove();
             if(tempCard.isEventCard())
             {
                 upperListTribe.add(tempCard);
                 i--;
             }
             else
             {
                 lowerListTribe.add(tempCard);
             }
         }
 
         for(int i=upperListTribe.size();i<nTotem+4;i++)
         {
             TribeCard tempCard = tribeDeck.remove();
             upperListTribe.add(tempCard);
         }
 
         ArrayList<BuildingCard> buildingDeck = new ArrayList<>(DecksCreator.loadBuildingDeckByEra(1));
         Collections.shuffle(buildingDeck);
         buildingCardsAllEras= new ArrayList<>();
         buildingCardsAllEras.add(new ArrayList<>());
         buildingCardsAllEras.add(new ArrayList<>());
         buildingCardsAllEras.add(new ArrayList<>());
         if(nTotem==2)
         {
             buildingCardsAllEras.set(0, new ArrayList<>(buildingDeck.subList(0, 1)));
             upperListBuilding = new ArrayList<>(buildingDeck.subList(0,1));
         }
         else
         {
             buildingCardsAllEras.set(0, new ArrayList<>(buildingDeck.subList(0, 2)));
             upperListBuilding = new ArrayList<>(buildingDeck.subList(0,2));
         }
 
         buildingDeck=new ArrayList<>(DecksCreator.loadBuildingDeckByEra(2));
         Collections.shuffle(buildingDeck);
         if(nTotem<=3)
         {
             buildingCardsAllEras.set(1, new ArrayList<BuildingCard>(buildingDeck.subList(0, 2)));
         }
         else
         {
             buildingCardsAllEras.set(1, new ArrayList<BuildingCard>(buildingDeck.subList(0, 3)));
         }
         buildingDeck=new ArrayList<>(DecksCreator.loadBuildingDeckByEra(3));
         Collections.shuffle(buildingDeck);
         if(nTotem==2)
         {
             buildingCardsAllEras.set(2, new ArrayList<BuildingCard>(buildingDeck.subList(0, 3)));
         }else if(nTotem==5)
         {
             buildingCardsAllEras.set(2, new ArrayList<BuildingCard>(buildingDeck.subList(0, 5)));
         }
         else {
             buildingCardsAllEras.set(2, new ArrayList<BuildingCard>(buildingDeck.subList(0, 4)));
         }
 
     }
 
     /**
      * Creates the tribeDeck. Loads the cards from each era, shuffle them, and then combine them in the final deck.
      * In the end, two special events (Sustenance and ShamanicRitual) are added.
      *
      * @param nPlayers      the number of players.
      * @return a queue containing the cards in this order:
      *      - Era 1.
      *      - Era 2.
      *      - Era 3.
      *      - Special events.
      */
     private Queue<TribeCard>  generateTribeDeck(int nPlayers) {
         ArrayList<TribeCard> era1= DecksCreator.loadTribeDeckByEra(1).stream().filter(x->x.getNMin()<=nPlayers).collect(Collectors.toCollection(ArrayList::new));
         ArrayList<TribeCard> era2= DecksCreator.loadTribeDeckByEra(2).stream().filter(x->x.getNMin()<=nPlayers).collect(Collectors.toCollection(ArrayList::new));
         ArrayList<TribeCard> era3= DecksCreator.loadTribeDeckByEra(3).stream().filter(x->x.getNMin()<=nPlayers).collect(Collectors.toCollection(ArrayList::new));
         Collections.shuffle(era1);
         Collections.shuffle(era2);
         Collections.shuffle(era3);
 
         Queue<TribeCard> tribeDeck_temp=new LinkedList<>();
         tribeDeck_temp.addAll(era1);
         tribeDeck_temp.addAll(era2);
         tribeDeck_temp.addAll(era3);
         tribeDeck_temp.add(new Sustenance("095",3,3));
         tribeDeck_temp.add(new ShamanicRitual("096",3,15,7));
         return tribeDeck_temp;
     }
 
     /** @return the queue of events cards from the lower list that need to be activated */
     public Queue<EventCard> getPendingEvents(){
         return lowerListTribe.stream().filter(TribeCard::isEventCard).map(x->(EventCard)x).collect(Collectors.toCollection(LinkedList::new));
     }
 
     /**
      * Take the selected card from the upper tribe list of the board.
      *
      * @param tribeCard is the card to remove.
      * @return true if the card is successfully removed.
      */
     public boolean removeUpperTribeCard(TribeCard tribeCard) {
         return upperListTribe.remove(tribeCard);
     }
 
     /**
      * Take the selected card from the lower tribe list of the board.
      *
      * @param tribeCard is the card to remove.
      * @return true if succeed in removing the card.
      */
     public boolean removeLowerTribeCard(TribeCard tribeCard) {
         return lowerListTribe.remove(tribeCard);
     }
 
     /**
      * Take the selected card from the upper building list of the board.
      *
      * @param buildingCard is the card to remove.
      * @return true if succeed in removing the card.
      */
     public boolean removeUpperBuildingCard(BuildingCard buildingCard) {
         return upperListBuilding.remove(buildingCard);
     }
 
     /**
      * Take the selected card from the lower building list of the board.
      *
      * @param buildingCard is the card to remove.
      * @return true if succeed in removing the card.
      */
     public boolean removeLowerBuildingCard(BuildingCard buildingCard) {
         return lowerListBuilding.remove(buildingCard);
     }
 
     /**
      * Goes to the next round.
      *      - Clear the lower tribe row.
      *      - Moves the upper tribe row to the lower one.
      *      - Populate the upper tribe row.
      *
      * @return the current era after moving to the next round.
      */
     public int nextRound() {
         lowerListTribe.clear();
         lowerListTribe.addAll(upperListTribe);
         upperListTribe.clear();
 
         for(int i=0;i<nTotem+4;i++)
         {
             if (tribeDeck.isEmpty()) break;
             TribeCard tempCard = tribeDeck.remove();
             if(tempCard.getEra()!=era)
             {
                 nextEra();
             }
             upperListTribe.add(tempCard);
         }
 
         return era;
     }
 
     /**
      * Changes the era of the game:
      *      - Increase the era attribute.
      *      - Clear the lower building list and replace it with the upper building list.
      *      - Repopulate the upper building list.
      */
     private void nextEra() {
         era=era+1;
         lowerListBuilding.clear();
         lowerListBuilding.addAll(upperListBuilding);
         upperListBuilding.clear();
 
         if(era==2)
         {
             upperListBuilding.addAll(buildingCardsAllEras.get(1));
         }
         else
         {
             upperListBuilding.addAll(buildingCardsAllEras.get(2));
         }
     }
 }