package server; import server.cards.BuildingCard; import server.cards.CharacterCard; import server.cards.CharacterType; import server.cards.Trigger; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Tribe { // Attributes private List characters; private List buildings; // Constructor public Tribe() { this.characters = new ArrayList<>(); this.buildings = new ArrayList<>(); } public List getCharacters() { return characters; } public List getBuildingCard() { return buildings; } // METODI public int addCharacter(CharacterCard card) { this.characters.add(card); if (card.getCharacterType().equals(CharacterType.HUNTER)) { return hunterGetFood(card); } return 0; } // Metodo per aggiungere un nuovo building alla tribù public void addBuilding(BuildingCard card) { this.buildings.add(card); } // Metodo per ottenere lo sconto in cibo in base a quanti gatherer abbiamo nella tribù public int gathererDiscount() { long gatherers = characters.stream() .filter(c -> c.getCharacterType() == CharacterType.GATHERER) .count(); return (int) gatherers * 3; } // Metodo per ottenere lo sconto totale sugli edifici grazie ai builder nella tribù public int buildersDiscount() { return characters.stream() .filter(c -> c.getCharacterType() == CharacterType.BUILDER) .mapToInt(CharacterCard::getIconValue) .sum(); } // Metodo che conta quante stelle degli sciamani abbiamo in totale nella tribù public int shamansIcons() { return characters.stream() .filter(c -> c.getCharacterType() == CharacterType.SHAMAN) .mapToInt(CharacterCard::getIconValue) .sum(); } // Metodo che restituisce il numero di artisti nella tribù public int artistsNumber() { return countCharactersByType(CharacterType.ARTIST); } // Metodo che restituisce il numero di cacciatori nella tribù public int huntersNumber() { return countCharactersByType(CharacterType.HUNTER); } // Metodo universale per contare le carte di un certo tipo all'interno della tribù public int countCharactersByType(CharacterType typeToCount) { long count = characters.stream() .filter(c -> c.getCharacterType() == typeToCount) .count(); return (int) count; } // Metodo che ritorna il numero totale di cibi ottenuti dopo aver pescato il cacciatore col cosciotto public int hunterGetFood(CharacterCard hunter) { return huntersNumber() * hunter.getIconValue(); // getIconValue = 1 se il cacciatore ha il cosciotto } // Metodo che restituisce i punti finali degli inventori public int inventorsEndPoints() { long inventorCount = characters.stream() .filter(c -> c.getCharacterType() == CharacterType.INVENTOR) .count(); long uniqueInventions = characters.stream() .filter(c -> c.getCharacterType() == CharacterType.INVENTOR) .map(CharacterCard::getIconValue) .distinct() .count(); return (int) (inventorCount * uniqueInventions); } // Metodo che restituisce i punti finali degli artisti public int artistsEndPoints() { return (artistsNumber() / 2) * 10; // in java 1/2 fa 0 } // Metodo che restituisce i punti finali dei costruttore public int buildersEndPoints() { return characters.stream() .filter(c -> c.getCharacterType() == CharacterType.BUILDER) .mapToInt(CharacterCard::getPrestigePoints) .sum(); } // Metodo che restituisce i punti finali guadagnati grazie agli EFFETTI delle carte building private int buildingAbilitiesEndPoints() { int bonusPoints = 0; for (BuildingCard b : buildings) { Trigger trigger = b.getAbilityTrigger(); // leggiamo il trigger della carta edificio // Se la carta per qualche motivo non ha trigger, passiamo alla prossima if (trigger == null) continue; switch (trigger) { case ENDGAME_BUILDER_BONUS: // id carta: 107 bonusPoints += (buildersEndPoints() * 2); break; case ENDGAME_FOR_SIX: // id carta: 109 // Prepariamo i contatori per tutti e 6 i tipi di characters Map counts = characters.stream() .collect(Collectors.groupingBy(CharacterCard::getCharacterType, Collectors.counting())); long completeSets = Arrays.stream(new CharacterType[]{ CharacterType.INVENTOR, CharacterType.HUNTER, CharacterType.GATHERER, CharacterType.SHAMAN, CharacterType.ARTIST, CharacterType.BUILDER }) .mapToLong(t -> counts.getOrDefault(t, 0L)) .min() .orElse(0); // aggiungiamo 6 punti prestigio per ogni set completo bonusPoints += completeSets * 6; break; case ENDGAME_BONUS_CHARACTER: int id = b.getCardId(); // uso l'id della carta per capire che edificio è // il numero id corrisponde al numero di pagina nel pdf if (id == 110) { // edificio dei cacciatori bonusPoints += countCharactersByType(CharacterType.HUNTER) * 3; } else if (id == 111) { // edificio dei gatherer bonusPoints += countCharactersByType(CharacterType.GATHERER) * 4; } else if (id == 112) { // edificio degli sciamani bonusPoints += countCharactersByType(CharacterType.SHAMAN) * 4; } else if (id == 113) { // edificio dei costruttori bonusPoints += countCharactersByType(CharacterType.BUILDER) * 4; } else if (id == 114) { // edificio degli artisti bonusPoints += countCharactersByType(CharacterType.ARTIST) * 4; } else if (id == 115) { // edificio degli inventori bonusPoints += countCharactersByType(CharacterType.INVENTOR) * 2; } break; case ENDGAME_BONUS_POINTS: // id carta: 117 bonusPoints += 25; // dà 25 punti bonus break; default: break; } } return bonusPoints; } // Metodo che calcola i punti finali totali public int endPoints() { int total = 0; // sommiamo i punti calcolati dai vari personaggi total += inventorsEndPoints(); total += artistsEndPoints(); total += buildersEndPoints(); // sommiamo i punti prestigio BASE di tutti gli edifici (EndPP) for (BuildingCard b : buildings) { total += b.getEndPP(); } //TODO sommiamo gli effetti degli edifici sul punteggio finale, NON quelli durante la partita total += buildingAbilitiesEndPoints(); return total; } }