410 lines
13 KiB
Java
410 lines
13 KiB
Java
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<Player> playersList;
|
|
private CurrentState currentState;
|
|
private HashMap<Slot,Player> slotMap;
|
|
private int nPlayers;
|
|
private Queue<Player> OptionalCardQueue;
|
|
private OrderLogicCard orderLogicCard;
|
|
private Board board;
|
|
|
|
|
|
public List<TribeCard>getUpperListTribeCards() {
|
|
List<TribeCard> 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<Slot, Player> 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<Slot,Player> 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<Player,Integer> 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<Player,Integer> 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<EventCard> events;
|
|
events=board.getPendingEvents();
|
|
ArrayList<EventCard>sustenance=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);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|