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 Player getPlayerByIndex(int playerIndex) throws IndexOutOfBoundsException { if(playerIndex >= playersList.size()) throw new IndexOutOfBoundsException("Player index out of bounds"); return playersList.get(playerIndex); } /* public TribeCard getUpperTribeCardByIndex(int playerIndex) throws IndexOutOfBoundsException { } public TribeCard getLowerTribeCardByIndex() { } public BuildingCard getUpperBuildingCardByIndex(int playerIndex) throws IndexOutOfBoundsException { } public BuildingCard getLowerBuildingCardByIndex(int playerIndex) throws IndexOutOfBoundsException { } */ 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; playersList.add(player); if(playersList.size()>=nPlayers) { init(); return true; } return false; } 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 SlotChoice(Player player, Slot slot) { if(currentState.getGameStage()!= GameStages.SLOT_CHOICE) { return false; } if(!player.equals(currentState.getCurrentPlayer())) { return false; } if(slotMap.get(slot)!=null) { return false; } if(!board.getSlotList().contains(slot)) { return false; } slotMap.put(slot,player); nextPlayerSetup(); return true; } //region Drawing Methods public boolean DrawUpperTribeCard(Player player,TribeCard tribeCard) { if(currentState.getGameStage()!= GameStages.RESOLVING_ACTIONS) { return false; } if(!player.equals(currentState.getCurrentPlayer())) { return false; } if(!board.containsUpperTribeCard(tribeCard)) return false; if(currentState.getNUpper() <1) return false; 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 DrawLowerTribeCard(Player player,TribeCard tribeCard) { if(currentState.getGameStage()!= GameStages.RESOLVING_ACTIONS) { return false; } if(!player.equals(currentState.getCurrentPlayer())) { return false; } if(!board.containsLowerTribeCard(tribeCard)) return false; if(currentState.getNLower() <1) return false; 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 DrawUpperBuildingCard(Player player,BuildingCard buildingCard) { if(currentState.getGameStage()!= GameStages.RESOLVING_ACTIONS) { return false; } if(!player.equals(currentState.getCurrentPlayer())) { return false; } if(!board.containsUpperBuildingCard(buildingCard)) { return false; } 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 DrawLowerBuildingCard(Player player,BuildingCard buildingCard) { if(currentState.getGameStage()!= GameStages.RESOLVING_ACTIONS) { return false; } if(!player.equals(currentState.getCurrentPlayer())) { return false; } if(!board.containsLowerBuildingCard(buildingCard)) { return false; } 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 // TODO fare mappa per contare più volte lo stesso player 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.containsUpperTribeCard(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.containsUpperBuildingCard(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; } return true; } //endregion //endregion private void nextPlayerSetup() { if(GameStages.SLOT_CHOICE==currentState.getGameStage()) { currentState.PlayerUpdate(orderLogicCard.pull(), null); if(currentState.getCurrentPlayer()==null) { currentState.GameStageUpdate(GameStages.RESOLVING_ACTIONS); } } 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); OptionalCardQueue=(playersList.stream().filter(x->x.buildingCards.stream().anyMatch(y->y.getEffectId()==12)).collect(Collectors.toCollection(LinkedList::new))); 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(); } // TODO pulire game ? private void endGame() { playersList.forEach( p -> p.buildingCards.stream().filter(x -> x.getEffectType() == EffectType.FINAL). forEach(x -> x.applyEffect(p)) ); currentState.GameStageUpdate(GameStages.ENDED); } }