package it.polimi.ingsw.gc14.Model; import it.polimi.ingsw.gc14.Model.Cards.Building.EffectType; import it.polimi.ingsw.gc14.Model.Cards.BuildingCard; import it.polimi.ingsw.gc14.Model.Cards.TribeCard; import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Character; import it.polimi.ingsw.gc14.Model.Cards.TribeCards.EventCard; import it.polimi.ingsw.gc14.Model.Cards.TribeCards.EventType; import it.polimi.ingsw.gc14.Model.GamePackage.Board; import it.polimi.ingsw.gc14.Model.GamePackage.CurrentState; import it.polimi.ingsw.gc14.Model.Orders.Order2; import it.polimi.ingsw.gc14.Model.Orders.Order3; import it.polimi.ingsw.gc14.Model.Orders.Order4; import it.polimi.ingsw.gc14.Model.Orders.Order5; import it.polimi.ingsw.gc14.Model.GamePackage.GameStages; import java.util.*; import java.util.stream.Collectors; public class Game { private ArrayList playersList; private CurrentState currentState; private HashMap slotMap; private int nPlayers; private Queue OptionalCardQueue; private OrderLogicCard orderLogicCard; private Board board; public ListgetUpperListTribeCards() { List cards = new ArrayList<>(); board.upperListTribe.forEach(x->cards.add(x.clone())); return cards; } public CurrentState getCurrentState() { return currentState; }; public Player getPlayerByIndex(int playerIndex) throws IndexOutOfBoundsException { if(playerIndex >= playersList.size()) throw new IndexOutOfBoundsException("Player index out of bounds"); return playersList.get(playerIndex); } public int getNPlayers() { return nPlayers; } public Game(int nPlayers) { this.nPlayers = nPlayers; board=new Board(nPlayers); slotMap = new LinkedHashMap<>(); for(Slot s :board.getSlotList()) { slotMap.put(s,null); } currentState= new CurrentState(); playersList = new ArrayList<>(); OptionalCardQueue = new LinkedList<>(); } public boolean addPlayer(Player player) { if(currentState.getGameStage()!= GameStages.WAITING) return false; if(playersList.contains(player)) return false; playersList.add(player); if(playersList.size()>=nPlayers) { init(); } return true; } public void init() { switch (nPlayers) { case 2: orderLogicCard=new Order2(playersList); break; case 3: orderLogicCard=new Order3(playersList); break; case 4: orderLogicCard=new Order4(playersList); break; case 5: orderLogicCard=new Order5(playersList); break; } currentState.PlayerUpdate(orderLogicCard.pull(),null); currentState.GameStageUpdate(GameStages.SLOT_CHOICE); } //region Cotroller Methods public boolean SlotChoiceByIndex(Player player, int slotIndex) { if(slotIndex<0 || slotIndex>=slotMap.size()) return false; if(currentState.getGameStage()!= GameStages.SLOT_CHOICE) { return false; } if(!player.equals(currentState.getCurrentPlayer())) { return false; } Map.Entry slotPlayerEntry = new ArrayList<>(slotMap.entrySet()).get(slotIndex); if(slotPlayerEntry.getValue()!=null) { return false; } slotMap.put(slotPlayerEntry.getKey(),player); nextPlayerSetup(); return true; } //region Drawing Methods public boolean DrawUpperTribeCardByIndex(Player player,int cardIndex) { if( cardIndex<0 || cardIndex >=board.upperListTribe.size()) return false; if(currentState.getGameStage()!= GameStages.RESOLVING_ACTIONS) { return false; } if(!player.equals(currentState.getCurrentPlayer())) { return false; } if(currentState.getNUpper() <1) return false; TribeCard tribeCard = board.upperListTribe.get(cardIndex); if(tribeCard.IsEventCard()) return false; Character tempCard = (Character) tribeCard; tempCard.insert(player); board.removeUpperTribeCard(tempCard); currentState.UpperDrawn(); if(currentState.getNUpper() ==0 && currentState.getNLower() ==0) nextPlayerSetup(); return true; } public boolean DrawLowerTribeCardByIndex(Player player, int cardIndex) { if( cardIndex<0 || cardIndex >=board.lowerListTribe.size()) return false; if(currentState.getGameStage()!= GameStages.RESOLVING_ACTIONS) { return false; } if(!player.equals(currentState.getCurrentPlayer())) { return false; } if(currentState.getNLower() <1) return false; TribeCard tribeCard = board.lowerListTribe.get(cardIndex); if(!tribeCard.IsEventCard()) return false; Character tempCard = (Character) tribeCard; tempCard.insert(player); board.removeLowerTribeCard(tempCard); currentState.LowerDrawn(); if(currentState.getNLower() ==0 && currentState.getNUpper() ==0) nextPlayerSetup(); return true; } public boolean DrawUpperBuildingCardByIndex(Player player,int cardIndex) { if( cardIndex<0 || cardIndex >=board.upperListBuilding.size()) return false; if(currentState.getGameStage()!= GameStages.RESOLVING_ACTIONS) { return false; } if(!player.equals(currentState.getCurrentPlayer())) { return false; } BuildingCard buildingCard = board.upperListBuilding.get(cardIndex); if(currentState.getNUpper() <1) return false; if(buildingCard.buy(player)) { currentState.UpperDrawn(); board.removeUpperBuildingCard(buildingCard); } else return false; if(currentState.getNLower() ==0 && currentState.getNUpper() ==0) nextPlayerSetup(); return true; } public boolean DrawLowerBuildingCardByIndex(Player player,int cardIndex) { if( cardIndex<0 || cardIndex >=board.lowerListBuilding.size()) return false; if(currentState.getGameStage()!= GameStages.RESOLVING_ACTIONS) { return false; } if(!player.equals(currentState.getCurrentPlayer())) { return false; } BuildingCard buildingCard = board.lowerListBuilding.get(cardIndex); if(currentState.getNLower() <1) return false; if(buildingCard.buy(player)) { currentState.LowerDrawn(); board.removeLowerBuildingCard(buildingCard); } else return false; if(currentState.getNLower() ==0 && currentState.getNUpper() ==0) nextPlayerSetup(); return true; } //endregion //region Optional Card Methods public boolean PickOptionalTribeCard(Player player,TribeCard tribeCard) { if(currentState.getGameStage() != GameStages.OPTIONAL_CARD_EFFECT){ return false; } if(!player.equals(currentState.getCurrentPlayer())){ return false; } if(!board.upperListTribe.contains(tribeCard)){ return false; } if(tribeCard.IsEventCard()){ return false; } Character tempCard = (Character) tribeCard; tempCard.insert(player); board.removeUpperTribeCard(tempCard); nextPlayerSetup(); return true; } public boolean PickOptionalBuildingCard(Player player, BuildingCard buildingCard) { if(currentState.getGameStage() != GameStages.OPTIONAL_CARD_EFFECT){ return false; } if(!player.equals(currentState.getCurrentPlayer())){ return false; } if(!board.upperListBuilding.contains(buildingCard)){ return false; } if(buildingCard.buy(player)) { board.removeUpperBuildingCard(buildingCard); } else { return false; } nextPlayerSetup(); return true; } public boolean NoOptionalCard(Player player) { if(currentState.getGameStage() != GameStages.OPTIONAL_CARD_EFFECT){ return false; } if(!player.equals(currentState.getCurrentPlayer())){ return false; } OptionalCardQueue.removeIf(x->x.equals(player)); nextPlayerSetup(); return true; } //endregion //endregion private void nextPlayerSetup() { if(GameStages.SLOT_CHOICE==currentState.getGameStage()) { Player tempPlayer = orderLogicCard.pull(); if(tempPlayer!=null) { currentState.PlayerUpdate(tempPlayer, null); return; } currentState.GameStageUpdate(GameStages.RESOLVING_ACTIONS); for (Map.Entry s : slotMap.entrySet()) { if (s.getValue()!=null) { currentState.PlayerUpdate(s.getValue(), s.getKey()); return; } } return; } if(GameStages.RESOLVING_ACTIONS==currentState.getGameStage()) { orderLogicCard.push(currentState.getCurrentPlayer()); slotMap.put(currentState.getSlot(), null); for (Slot s : board.getSlotList()) { if (slotMap.get(s) != null) { currentState.PlayerUpdate(slotMap.get(s), s); } } if(slotMap.values().stream().allMatch(v -> v == null)) { currentState.GameStageUpdate(GameStages.OPTIONAL_CARD_EFFECT); HashMap optional=new LinkedHashMap<>(); for (Player p : playersList) { int tempCount=(int)p.buildingCards.stream().filter(x->x.getEffectId()==12).count(); if(tempCount>0) { optional.put(p,tempCount); } } OptionalCardQueue=new LinkedList<>(); for(Map.Entry e : optional.entrySet()) { OptionalCardQueue.add(e.getKey()); } currentState.PlayerUpdate(OptionalCardQueue.remove(), null); if(currentState.getCurrentPlayer()==null) { currentState.GameStageUpdate(GameStages.RESOLVING_EVENT); if(currentState.getRound()<10) { nextRound(); } else { EventResolution(); currentState.GameStageUpdate(GameStages.ENDING); endGame(); } return; } } } if(GameStages.OPTIONAL_CARD_EFFECT==currentState.getGameStage()) { currentState.PlayerUpdate(OptionalCardQueue.remove(), null); if(currentState.getCurrentPlayer()==null) { currentState.GameStageUpdate(GameStages.RESOLVING_EVENT); } } } private void EventResolution() { if(currentState.getGameStage()!= GameStages.RESOLVING_EVENT) { return; } Queue events; events=board.getPendingEvents(); ArrayListsustenance=events.stream().filter(x->x.getType().equals(EventType.SUSTENANCE)).collect(Collectors.toCollection(ArrayList::new)); events.removeAll(sustenance); for(EventCard event:events) { event.activateEvent(playersList); } for(EventCard e : sustenance) { e.activateEvent(playersList); } } private void nextRound() { EventResolution(); if(currentState.getRound()==10) { currentState.GameStageUpdate(GameStages.ENDING); endGame(); } if(currentState.getEra()!= board.nextRound()) currentState.EraUpdate(); currentState.RoundUpdate(); } private void endGame() { playersList.forEach( p -> p.buildingCards.stream().filter(x -> x.getEffectType() == EffectType.FINAL). forEach(x -> x.applyEffect(p)) ); currentState.GameStageUpdate(GameStages.ENDED); } }