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);
}
/**
* TODO rifare javadoc
* 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
*/
public int getPosition(String username)
{
int pos = 0;
for (OrderPlayer p : playerList) {
if (p.player.getUserName().equals(username))
return pos;
pos++;
}
return -1;
}
}