package it.polimi.ingsw.gc14.Model; import it.polimi.ingsw.gc14.Model.Cards.BuildingCard; import it.polimi.ingsw.gc14.Model.Orders.OrderPlayer; import it.polimi.ingsw.gc14.View.TUI.AsciiTable; import it.polimi.ingsw.gc14.View.TUI.BorderStyle; import java.io.Serializable; import java.util.*; import java.util.stream.Collectors; /** * Abstract base class for all order logic cards. * *

An order logic card manages the turn order of the players and defines * the behavior used to update the order during the game. */ public abstract class OrderLogicCard implements Serializable { /** * The queue of {@link Player Players} associated with this order logic card. */ protected Queue players; /** * The list of {@link Player Players} associated with this order logic card. */ protected List playerList; /** * Creates an order logic card with the specified list of players. * The input list is shuffled before being inserted into the queue. * * @param players the list of players associated with this order logic card. */ public OrderLogicCard(ArrayList players) { Collections.shuffle(players); this.players = new LinkedList<>(players); this.playerList=new ArrayList<>(players.stream().map(x->new OrderPlayer(x,false)).toList()); } /** * Applies the effect associated with the current queue position of the player * and then adds the player to the end of the queue. * * @param player the player to be pushed into the queue. */ public void push(Player player){ effect(player,players.size()); if(players.size()==0) { playerList=new ArrayList<>(); } playerList.add(new OrderPlayer(player,false)); players.add(player); } /** * Adds the player to the end of the queue, without effects. * * @param player the player to be pushed into the queue. */ public void pushNoEffect(Player player){ if(players.size()==0) { playerList=new ArrayList<>(); } playerList.add(new OrderPlayer(player,false)); players.add(player); } /** * Removes and returns the first player in the queue. * * @return the first player in the queue, or {@code null} if the queue is empty. */ public Player pull(){ for(OrderPlayer p:playerList){ if(p.played==false) { p.played=true; break; } } return players.poll(); } /** * Returns the first player in the queue without removing it. * * @return the first player in the queue, or {@code null} if the queue is empty. */ public Player getFirst() { return players.peek(); } /** * Applies the effect associated with the specified player and queue position. * * @param player the player to whom the effect is applied. * @param index the queue position index associated with the effect. * @throws IndexOutOfBoundsException if the specified index is not valid. */ protected abstract void effect(Player player, int index) throws IndexOutOfBoundsException; /** * Applies the building-related effect to the specified player. * For each building card owned by the player with effect id equal to 3, * the player gains 1 Food. * * @param player the player to whom the building effect is applied. */ protected void buildingEffect(Player player) { for(BuildingCard b : player.buildingCards.stream().filter(x->x.getEffectId()==3).toList()) player.addFood(1); } /** * Returns the {@code Player}'s position based on it's {@code Username}. * @param username The desired {@code Player}'s username. * @return {@code int} - the {@code Player}'s position. * @see Player */ protected int getPosition(String username) { int pos = 0; for (Player p : players) { if (p.getUserName().equals(username)) return pos; pos++; } return -1; } }