1137 lines
54 KiB
HTML
1137 lines
54 KiB
HTML
|
||
|
||
|
||
<!DOCTYPE html>
|
||
<html id="htmlId">
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
|
||
<title>Coverage Report > Game</title>
|
||
<style type="text/css">
|
||
@import "../../css/coverage.css";
|
||
@import "../../css/idea.min.css";
|
||
</style>
|
||
<script type="text/javascript" src="../../js/highlight.min.js"></script>
|
||
<script type="text/javascript" src="../../js/highlightjs-line-numbers.min.js"></script>
|
||
</head>
|
||
|
||
<body>
|
||
<div class="content">
|
||
<div class="breadCrumbs">
|
||
Current scope: <a href="../../index.html">all classes</a>
|
||
<span class="separator">|</span>
|
||
<a href="../index.html">it.polimi.ingsw.gc14.Model</a>
|
||
</div>
|
||
|
||
<h1>Coverage Summary for Class: Game (it.polimi.ingsw.gc14.Model)</h1>
|
||
|
||
<table class="coverageStats">
|
||
<tr>
|
||
<th class="name">Class</th>
|
||
<th class="coverageStat
|
||
">
|
||
Class, %
|
||
</th>
|
||
<th class="coverageStat
|
||
">
|
||
Method, %
|
||
</th>
|
||
<th class="coverageStat
|
||
">
|
||
Branch, %
|
||
</th>
|
||
<th class="coverageStat
|
||
">
|
||
Line, %
|
||
</th>
|
||
</tr>
|
||
<tr>
|
||
<td class="name">Game</td>
|
||
<td class="coverageStat">
|
||
<span class="percent">
|
||
100%
|
||
</span>
|
||
<span class="absValue">
|
||
(1/1)
|
||
</span>
|
||
</td>
|
||
<td class="coverageStat">
|
||
<span class="percent">
|
||
90.9%
|
||
</span>
|
||
<span class="absValue">
|
||
(40/44)
|
||
</span>
|
||
</td>
|
||
<td class="coverageStat">
|
||
<span class="percent">
|
||
68.4%
|
||
</span>
|
||
<span class="absValue">
|
||
(210/307)
|
||
</span>
|
||
</td>
|
||
<td class="coverageStat">
|
||
<span class="percent">
|
||
83.1%
|
||
</span>
|
||
<span class="absValue">
|
||
(285/343)
|
||
</span>
|
||
</td>
|
||
</tr>
|
||
|
||
</table>
|
||
|
||
<br/>
|
||
<br/>
|
||
|
||
|
||
<pre>
|
||
<code class="sourceCode" id="sourceCode"> 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.CharacterType;
|
||
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters.Builder;
|
||
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters.Inventor;
|
||
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.io.Serializable;
|
||
import java.util.*;
|
||
import java.util.stream.Collectors;
|
||
import java.util.stream.Stream;
|
||
|
||
/**
|
||
* Represents the main game model.
|
||
* A Game object stores the players, the current state of the match,
|
||
* the slot assignments, the board, and the logic required to manage the game flow.
|
||
*/
|
||
public class Game implements Serializable {
|
||
|
||
/**
|
||
* The final ranking of players at the end of the game.
|
||
*/
|
||
private ArrayList<Player> playerStanding;
|
||
|
||
/**
|
||
* Returns the final ranking of players.
|
||
*
|
||
* @return the list of players ordered according to their final standing.
|
||
*/
|
||
public ArrayList<Player> getPlayerStanding() {
|
||
<b class="nc"> return playerStanding;</b>
|
||
}
|
||
|
||
/**
|
||
* Returns the list of players participating in the game.
|
||
*
|
||
* @return a copy of the list of players currently participating in the game.
|
||
*/
|
||
public List<Player> getPlayers() {
|
||
<b class="fc"> return playersList;</b>
|
||
}
|
||
|
||
/**
|
||
* Returns the list of totems that have not yet been assigned to any player.
|
||
*
|
||
* @return the list of currently available totems.
|
||
*/
|
||
public List<Totems>getAvailableTotems() {
|
||
<b class="fc"> List<Totems> totems=new ArrayList<>(List.of(Totems.values()));</b>
|
||
<b class="fc"> playersList.forEach(player -> {if(player.getTotem()!=null)totems.remove(player.getTotem());});</b>
|
||
<b class="fc"> return totems;</b>
|
||
}
|
||
|
||
/**
|
||
* Queue containing the players who still have to choose their totem.
|
||
*/
|
||
<b class="fc"> private final Queue<Player> totemChoiceQueue = new LinkedList<>();</b>
|
||
|
||
/**
|
||
* Assigns the selected totem to the specified player during the totem choice phase.
|
||
*
|
||
* <p>The choice is accepted only if the game is currently in the
|
||
* {@link GameStages#TOTEM_CHOICE} stage, the player is the current one,
|
||
* and the selected totem is still available.
|
||
*
|
||
* <p>After a valid choice, the method advances to the next player in the queue.
|
||
* If all players have completed the selection, the game moves to the slot choice phase.
|
||
* Disconnected players are automatically assigned a random available totem.
|
||
*
|
||
* @param player the player making the totem choice.
|
||
* @param totem the selected totem.
|
||
* @return {@code true} if the choice is applied successfully, {@code false} otherwise.
|
||
*/
|
||
public synchronized boolean totemChoice(Player player,Totems totem) {
|
||
<b class="pc"> if(currentState.getGameStage() != GameStages.TOTEM_CHOICE)</b>
|
||
<b class="nc"> return false;</b>
|
||
<b class="fc"> if(!getCurrentState().getCurrentPlayer().equals(player))</b>
|
||
<b class="fc"> return false;</b>
|
||
<b class="fc"> if(!getAvailableTotems().contains(totem))</b>
|
||
{
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
<b class="fc"> player.setTotem(totem);</b>
|
||
<b class="fc"> Player nextPlayer= totemChoiceQueue.poll();</b>
|
||
|
||
<b class="fc"> if(nextPlayer==null)</b>
|
||
{
|
||
<b class="fc"> currentState.gameStageUpdate(GameStages.SLOT_CHOICE);</b>
|
||
<b class="fc"> currentState.playerUpdate(orderLogicCard.pull(),null);</b>
|
||
}
|
||
else
|
||
{
|
||
<b class="pc"> while(disconnectedPlayers.containsKey(nextPlayer)&& disconnectedPlayers.get(nextPlayer))</b>
|
||
{
|
||
<b class="nc"> nextPlayer.setTotem(getAvailableTotems().get(new Random().nextInt(0,getAvailableTotems().size())));</b>
|
||
<b class="nc"> nextPlayer=totemChoiceQueue.poll();</b>
|
||
<b class="nc"> if(nextPlayer==null)</b>
|
||
{
|
||
<b class="nc"> currentState.gameStageUpdate(GameStages.SLOT_CHOICE);</b>
|
||
<b class="nc"> nextPlayerSetup();</b>
|
||
<b class="nc"> return true;</b>
|
||
}
|
||
}
|
||
<b class="fc"> currentState.playerUpdate(nextPlayer,null);</b>
|
||
}
|
||
<b class="fc"> return true;</b>
|
||
}
|
||
|
||
/**
|
||
* Map tracking the players who are currently disconnected.
|
||
* Key: player; value: {@code true} if currently disconnected, {@code false} if reconnected.
|
||
*/
|
||
<b class="fc"> private final Map<Player,Boolean> disconnectedPlayers = new HashMap<>();</b>
|
||
|
||
/**
|
||
* Returns an unmodifiable view of the disconnected-players map.
|
||
*
|
||
* @return map from player to disconnection status.
|
||
*/
|
||
public Map<Player,Boolean> getDisconnectedPlayers() {
|
||
<b class="fc"> return Collections.unmodifiableMap(disconnectedPlayers);</b>
|
||
}
|
||
|
||
/**
|
||
* Marks the specified player as disconnected and updates the game flow accordingly.
|
||
*
|
||
* <p>If the player disconnects during the waiting phase, they are removed from
|
||
* the player list and from the totem choice queue. If the disconnected player is
|
||
* the current one, the game advances to the next suitable player or, during the
|
||
* totem choice phase, handles the remaining selection flow automatically.
|
||
*
|
||
* @param player the player who disconnected.
|
||
* @return {@code true} if the disconnection is handled successfully,
|
||
* {@code false} if the player was already marked as disconnected.
|
||
*/
|
||
public synchronized boolean disconnectedPlayer(Player player)
|
||
{
|
||
<b class="pc"> if(disconnectedPlayers.containsKey(player) && disconnectedPlayers.get(player))</b>
|
||
{
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
<b class="fc"> disconnectedPlayers.put(player,true);</b>
|
||
<b class="pc"> if (currentState.getGameStage() == GameStages.WAITING) {</b>
|
||
<b class="nc"> playersList.remove(player);</b>
|
||
<b class="nc"> totemChoiceQueue.remove(player);</b>
|
||
<b class="nc"> return true;</b>
|
||
}
|
||
<b class="pc"> if(currentState.getCurrentPlayer().equals(player)) {</b>
|
||
<b class="pc"> if (currentState.getGameStage() != GameStages.TOTEM_CHOICE) {</b>
|
||
<b class="fc"> nextPlayerSetup();</b>
|
||
}
|
||
else {
|
||
<b class="nc"> totemChoiceQueue.removeIf(x->x.getUserName().equals(player.getUserName()));</b>
|
||
<b class="nc"> player.setTotem(getAvailableTotems().get(new Random().nextInt(getAvailableTotems().size())));</b>
|
||
<b class="nc"> if (totemChoiceQueue.isEmpty()) {</b>
|
||
<b class="nc"> player.setTotem(getAvailableTotems().get(new Random().nextInt(getAvailableTotems().size())));</b>
|
||
<b class="nc"> currentState.gameStageUpdate(GameStages.SLOT_CHOICE);</b>
|
||
<b class="nc"> nextPlayerSetup();</b>
|
||
<b class="nc"> return true;</b>
|
||
}
|
||
<b class="nc"> currentState.playerUpdate(totemChoiceQueue.poll(), null);</b>
|
||
}
|
||
<b class="fc"> return true;</b>
|
||
}
|
||
|
||
<b class="nc"> return true;</b>
|
||
}
|
||
|
||
/**
|
||
* Marks the specified player as reconnected.
|
||
*
|
||
* <p>If the player reconnects during the slot choice phase, they are removed
|
||
* from the disconnected players map and reinserted into the order logic card
|
||
* when necessary.
|
||
*
|
||
* @param player the player who reconnected.
|
||
* @return {@code true} if the reconnection is handled successfully,
|
||
* {@code false} if the player was not previously marked as disconnected.
|
||
*/
|
||
public synchronized boolean reconnectPlayer(Player player)
|
||
{
|
||
<b class="pc"> if(!disconnectedPlayers.containsKey(player))</b>
|
||
{
|
||
<b class="nc"> return false;</b>
|
||
}
|
||
<b class="fc"> disconnectedPlayers.put(player,false);</b>
|
||
<b class="pc"> if(currentState.getGameStage() == GameStages.SLOT_CHOICE)</b>
|
||
{
|
||
<b class="fc"> disconnectedPlayers.remove(player);</b>
|
||
<b class="pc"> if(!orderLogicCard.containsInQueue(player))</b>
|
||
{
|
||
<b class="fc"> orderLogicCard.pushNoEffect(player);</b>
|
||
}
|
||
}
|
||
<b class="nc"> else if(currentState.getGameStage() == GameStages.RES_ACTIONS) {</b>
|
||
<b class="nc"> if(slotMap.containsValue(player))</b>
|
||
{
|
||
<b class="nc"> disconnectedPlayers.remove(player);</b>
|
||
}
|
||
}
|
||
<b class="fc"> return true;</b>
|
||
}
|
||
|
||
/**
|
||
* Clears the collection of disconnected players.
|
||
*/
|
||
public synchronized void clearDisconnected()
|
||
{
|
||
<b class="fc"> disconnectedPlayers.clear();</b>
|
||
}
|
||
|
||
/**
|
||
* Returns the current number of players participating in the game.
|
||
* @return the current number of players.
|
||
*/
|
||
public int getCurrentPlayerNumber() {
|
||
<b class="fc"> return playersList.size();</b>
|
||
}
|
||
|
||
/**
|
||
* The list of players participating in the game.
|
||
*/
|
||
private ArrayList<Player> playersList;
|
||
|
||
/**
|
||
* The current state of the game.
|
||
*/
|
||
private CurrentState currentState;
|
||
|
||
/**
|
||
* The mapping between slots and the players assigned to them.
|
||
*/
|
||
private HashMap<Slot,Player> slotMap;
|
||
|
||
/**
|
||
* Returns the map of slots assigned to players.
|
||
*
|
||
* @return the map that associates each slot with the corresponding player.
|
||
*/
|
||
<b class="fc"> public HashMap<Slot,Player> getSlotMap() {return slotMap;}</b>
|
||
|
||
/**
|
||
* The configured number of players for this game.
|
||
*/
|
||
private int nPlayers;
|
||
|
||
/**
|
||
* The queue of players involved in optional card resolution.
|
||
*/
|
||
private Queue<Player> optionalCardQueue;
|
||
|
||
/**
|
||
* The order logic card associated with this game.
|
||
*/
|
||
private OrderLogicCard orderLogicCard;
|
||
|
||
/**
|
||
* Returns the order logic card associated with this game.
|
||
*
|
||
* @return the order logic card.
|
||
*/
|
||
<b class="nc"> public OrderLogicCard getOrderLogicCard() { return orderLogicCard; }</b>
|
||
|
||
/**
|
||
* The board associated with this game.
|
||
*/
|
||
private Board board;
|
||
|
||
/**
|
||
* Returns the game board.
|
||
*
|
||
* @return the board associated with the game.
|
||
*/
|
||
<b class="fc"> public Board getBoard() {return board;}</b>
|
||
|
||
/**
|
||
* Returns a copy of the upper tribe cards currently available on the board.
|
||
*
|
||
* @return a new list containing the upper tribe cards currently on the board.
|
||
*/
|
||
public ArrayList<TribeCard> getUpperListTribeCards() {
|
||
<b class="fc"> return new ArrayList<>(board.getUpperListTribe());</b>
|
||
}
|
||
|
||
/**
|
||
* Returns a copy of the lower tribe cards currently available on the board.
|
||
*
|
||
* @return a new list containing the lower tribe cards currently on the board.
|
||
*/
|
||
public ArrayList<TribeCard> getLowerListTribeCards() {
|
||
<b class="fc"> return new ArrayList<>(board.getLowerListTribe());</b>
|
||
}
|
||
|
||
/**
|
||
* Returns a copy of the upper building cards currently available on the board.
|
||
*
|
||
* @return a new list containing the upper building cards currently on the board.
|
||
*/
|
||
public ArrayList<BuildingCard> getUpperListBuilding() {
|
||
<b class="fc"> return new ArrayList<>(board.getUpperListBuilding());</b>
|
||
}
|
||
|
||
/**
|
||
* Returns a copy of the lower building cards currently available on the board.
|
||
*
|
||
* @return a new list containing the lower building cards currently on the board.
|
||
*/
|
||
public ArrayList<BuildingCard> getLowerListBuilding() {
|
||
<b class="fc"> return new ArrayList<>(board.getLowerListBuilding());</b>
|
||
}
|
||
|
||
/**
|
||
* Returns the current state of the game.
|
||
*
|
||
* @return the current state of the game.
|
||
*/
|
||
public CurrentState getCurrentState() {
|
||
<b class="fc"> return currentState;</b>
|
||
}
|
||
|
||
/**
|
||
* Returns the player with the specified username, if present.
|
||
*
|
||
* @param username the username of the player to search for.
|
||
* @return the player with the specified username, or {@code null} if no such player exists.
|
||
* @throws IndexOutOfBoundsException if an index access error occurs.
|
||
*/
|
||
public Player getPlayerByUsername(String username) throws IndexOutOfBoundsException {
|
||
<b class="fc"> return playersList.stream().filter(x->x.getUserName().equals(username)).findFirst().orElse(null);</b>
|
||
}
|
||
|
||
/**
|
||
* Returns the configured number of players for this game.
|
||
*
|
||
* @return the configured number of players for this game.
|
||
*/
|
||
public int getNPlayers() {
|
||
<b class="fc"> return nPlayers;</b>
|
||
}
|
||
|
||
/**
|
||
* Creates a game with the specified number of players.
|
||
*
|
||
* @param nPlayers the configured number of players for the game.
|
||
* @throws IllegalArgumentException if {@code nPlayers < 0} or {@code nPlayers > 5}.
|
||
*/
|
||
<b class="fc"> public Game(int nPlayers) throws IllegalArgumentException{</b>
|
||
<b class="fc"> if(nPlayers !=0 && (nPlayers < 2 || nPlayers > 5)) {</b>
|
||
<b class="fc"> throw new IllegalArgumentException();</b>
|
||
}
|
||
<b class="fc"> this.nPlayers = nPlayers;</b>
|
||
<b class="fc"> board=new Board(nPlayers);</b>
|
||
<b class="fc"> slotMap = new LinkedHashMap<>();</b>
|
||
<b class="fc"> for(Slot s :board.getSlotList())</b>
|
||
{
|
||
<b class="fc"> slotMap.put(s,null);</b>
|
||
}
|
||
<b class="fc"> currentState= new CurrentState();</b>
|
||
<b class="fc"> playersList = new ArrayList<>();</b>
|
||
<b class="fc"> optionalCardQueue = new LinkedList<>();</b>
|
||
}
|
||
|
||
/**
|
||
* Creates a game with 0 configured players.
|
||
*/
|
||
public Game()
|
||
{
|
||
<b class="fc"> this(0);</b>
|
||
}
|
||
|
||
/**
|
||
* Attempts to add the specified player to the game.
|
||
* The operation succeeds only if the configured number of players is not 0,
|
||
* the current game stage is {@code WAITING}, and the player is not already present.
|
||
* If the number of players reaches the configured maximum, the game is initialized.
|
||
*
|
||
* @param player the player to add to the game.
|
||
* @return {@code true} if the player is successfully added, {@code false} otherwise.
|
||
*/
|
||
public boolean addPlayer(Player player) {
|
||
<b class="fc"> if(this.nPlayers==0)</b>
|
||
{
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
<b class="fc"> if(currentState.getGameStage()!= GameStages.WAITING)</b>
|
||
<b class="fc"> return false;</b>
|
||
<b class="fc"> if(getPlayerByUsername(player.getUserName())!=null)</b>
|
||
<b class="fc"> return false;</b>
|
||
<b class="fc"> playersList.add(player);</b>
|
||
<b class="fc"> totemChoiceQueue.add(player);</b>
|
||
<b class="fc"> if(playersList.size()>=nPlayers)</b>
|
||
{
|
||
<b class="fc"> init();</b>
|
||
}
|
||
<b class="fc"> return true;</b>
|
||
}
|
||
|
||
/**
|
||
* Initializes the game after all required players have been added.
|
||
* The method creates the appropriate order logic card according to the number of players,
|
||
* selects the first current player, and updates the game stage to {@code SLOT_CHOICE}.
|
||
*/
|
||
public void init() {
|
||
|
||
<b class="pc"> switch (nPlayers) {</b>
|
||
case 2:
|
||
<b class="fc"> orderLogicCard=new Order2(playersList);</b>
|
||
break;
|
||
case 3:
|
||
<b class="fc"> orderLogicCard=new Order3(playersList);</b>
|
||
break;
|
||
case 4:
|
||
<b class="fc"> orderLogicCard=new Order4(playersList);</b>
|
||
break;
|
||
case 5:
|
||
<b class="fc"> orderLogicCard=new Order5(playersList);</b>
|
||
break;
|
||
default:
|
||
<b class="nc"> throw new IllegalStateException("nPlayers must be 2–5, got: " + nPlayers);</b>
|
||
}
|
||
<b class="fc"> for(Player player : playersList)</b>
|
||
{
|
||
<b class="pc"> switch(orderLogicCard.getPosition(player.getUserName()))</b>
|
||
{
|
||
<b class="fc"> case 0: player.addFood(2); break;</b>
|
||
<b class="fc"> case 1,2: player.addFood(3); break;</b>
|
||
<b class="fc"> case 3,4: player.addFood(4); break;</b>
|
||
}
|
||
|
||
}
|
||
<b class="fc"> currentState.playerUpdate(totemChoiceQueue.poll(),null);</b>
|
||
<b class="fc"> currentState.gameStageUpdate(GameStages.TOTEM_CHOICE);</b>
|
||
}
|
||
|
||
|
||
/**
|
||
* Attempts to assign the slot at the specified index to the specified player.
|
||
* The operation succeeds only if the index is valid, the current game stage is {@code SLOT_CHOICE},
|
||
* the specified player is the current player, and the selected slot is not already assigned.
|
||
* If the slot is successfully assigned, the next player setup is triggered.
|
||
*
|
||
* @param player the player performing the slot choice.
|
||
* @param slotIndex the index of the selected slot.
|
||
* @return {@code true} if the slot choice succeeds, {@code false} otherwise.
|
||
*/
|
||
public boolean slotChoiceByIndex(Player player, int slotIndex) {
|
||
<b class="fc"> if(slotIndex<0 || slotIndex>=slotMap.size())</b>
|
||
<b class="fc"> return false;</b>
|
||
<b class="fc"> if(currentState.getGameStage()!= GameStages.SLOT_CHOICE)</b>
|
||
{
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
<b class="fc"> if(!player.equals(currentState.getCurrentPlayer()))</b>
|
||
{
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
<b class="fc"> Map.Entry<Slot, Player> slotPlayerEntry = new ArrayList<>(slotMap.entrySet()).get(slotIndex);</b>
|
||
<b class="fc"> if(slotPlayerEntry.getValue()!=null)</b>
|
||
{
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
<b class="fc"> slotMap.put(slotPlayerEntry.getKey(),player);</b>
|
||
<b class="fc"> nextPlayerSetup();</b>
|
||
<b class="fc"> return true;</b>
|
||
|
||
}
|
||
|
||
//region Drawing Methods
|
||
|
||
/**
|
||
* Attempts to draw the upper tribe card at the specified index for the specified player.
|
||
* The operation succeeds only if the index is valid, the game stage is {@code RESOLVING_ACTIONS},
|
||
* the specified player is the current player, at least one upper card draw is still available,
|
||
* and the selected tribe card is not an event card.
|
||
* If successful, the card is inserted into the player's collection, removed from the board,
|
||
* and the number of remaining upper draws is decremented.
|
||
* If both upper and lower draws become zero, the next player setup is triggered.
|
||
*
|
||
* @param player the player performing the draw.
|
||
* @param cardIndex the index of the upper tribe card to draw.
|
||
* @return {@code true} if the draw succeeds, {@code false} otherwise.
|
||
*/
|
||
public boolean drawUpperTribeCardByIndex(Player player,int cardIndex) {
|
||
<b class="fc"> if( cardIndex<0 || cardIndex >=board.getUpperListTribe().size())</b>
|
||
<b class="fc"> return false;</b>
|
||
<b class="fc"> if(currentState.getGameStage()!= GameStages.RES_ACTIONS && currentState.getGameStage()!=GameStages.OPT_CARD_E)</b>
|
||
{
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
<b class="fc"> if(!player.equals(currentState.getCurrentPlayer()))</b>
|
||
{
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
<b class="fc"> if(currentState.getNUpper() <1 && currentState.getGameStage()==GameStages.RES_ACTIONS)</b>
|
||
<b class="fc"> return false;</b>
|
||
<b class="fc"> TribeCard tribeCard = board.getUpperListTribe().get(cardIndex);</b>
|
||
<b class="fc"> if(tribeCard.isEventCard())</b>
|
||
<b class="fc"> return false;</b>
|
||
|
||
<b class="fc"> Character tempCard = (Character) tribeCard;</b>
|
||
<b class="fc"> tempCard.insert(player);</b>
|
||
<b class="fc"> board.removeUpperTribeCard(tempCard);</b>
|
||
<b class="fc"> if(currentState.getGameStage()==GameStages.RES_ACTIONS)</b>
|
||
{
|
||
<b class="fc"> currentState.upperDrawn();</b>
|
||
<b class="pc"> if((currentState.getNLower() ==0 ||( !hasDrawableDown() && getLowerListBuilding().isEmpty())) && ((currentState.getNUpper() ==0)||(!hasDrawableUp() && getUpperListBuilding().isEmpty())))</b>
|
||
<b class="fc"> nextPlayerSetup();</b>
|
||
}
|
||
else
|
||
{
|
||
<b class="fc"> nextPlayerSetup();</b>
|
||
}
|
||
|
||
<b class="fc"> return true;</b>
|
||
}
|
||
|
||
|
||
/**
|
||
* Skips the turn for the specified player when no drawable cards are available.
|
||
* The operation succeeds only if the current game stage is {@code RESOLVING_ACTIONS},
|
||
* the specified player is the current player,
|
||
* and the player can't draw tribe card (i.e. all remaining lower tribe cards are event cards).
|
||
* @param player the player skipping the turn .
|
||
* @return {@code true} if the skip succeeds, {@code false} otherwise.
|
||
*/
|
||
public boolean skipTurn(Player player) {
|
||
<b class="fc"> if(currentState.getGameStage() != GameStages.RES_ACTIONS && currentState.getGameStage() != GameStages.OPT_CARD_E)</b>
|
||
{
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
<b class="fc"> if(!player.equals(currentState.getCurrentPlayer()))</b>
|
||
{
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
<b class="fc"> if(currentState.getGameStage()==GameStages.RES_ACTIONS)</b>
|
||
{
|
||
<b class="pc"> if(hasDrawableDown() && currentState.getNLower()>0 )</b>
|
||
<b class="fc"> return false;</b>
|
||
<b class="pc"> if(hasDrawableUp() && currentState.getNUpper()>0)</b>
|
||
<b class="fc"> return false;</b>
|
||
<b class="nc"> while(currentState.getNLower()>0)</b>
|
||
<b class="nc"> currentState.lowerDrawn();</b>
|
||
<b class="nc"> while(currentState.getNUpper()>0)</b>
|
||
<b class="nc"> currentState.upperDrawn();</b>
|
||
<b class="nc"> nextPlayerSetup();</b>
|
||
}
|
||
else {
|
||
<b class="fc"> nextPlayerSetup();</b>
|
||
}
|
||
<b class="fc"> return true;</b>
|
||
}
|
||
|
||
/**
|
||
* Attempts to draw the lower tribe card at the specified index for the specified player.
|
||
* The operation succeeds only if the index is valid, the game stage is {@code RESOLVING_ACTIONS},
|
||
* the specified player is the current player, at least one lower card draw is still available,
|
||
* and the selected tribe card is not an event card.
|
||
* If successful, the card is inserted into the player's collection, removed from the board,
|
||
* and the number of remaining lower draws is decremented.
|
||
* If both lower and upper draws become zero, the next player setup is triggered.
|
||
*
|
||
* @param player the player performing the draw.
|
||
* @param cardIndex the index of the lower tribe card to draw.
|
||
* @return {@code true} if the draw succeeds, {@code false} otherwise.
|
||
*/
|
||
public boolean drawLowerTribeCardByIndex(Player player, int cardIndex) {
|
||
<b class="fc"> if( cardIndex<0 || cardIndex >=board.getLowerListTribe().size())</b>
|
||
<b class="fc"> return false;</b>
|
||
<b class="fc"> if(currentState.getGameStage()!= GameStages.RES_ACTIONS)</b>
|
||
{
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
<b class="fc"> if(!player.equals(currentState.getCurrentPlayer()))</b>
|
||
{
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
|
||
|
||
<b class="pc"> if(currentState.getNLower() <1)</b>
|
||
<b class="nc"> return false;</b>
|
||
<b class="fc"> TribeCard tribeCard = board.getLowerListTribe().get(cardIndex);</b>
|
||
<b class="pc"> if(tribeCard.isEventCard())</b>
|
||
<b class="nc"> return false;</b>
|
||
|
||
<b class="fc"> Character tempCard = (Character) tribeCard;</b>
|
||
<b class="fc"> tempCard.insert(player);</b>
|
||
<b class="fc"> board.removeLowerTribeCard(tempCard);</b>
|
||
<b class="fc"> currentState.lowerDrawn();</b>
|
||
<b class="pc"> if((currentState.getNLower() ==0 ||( !hasDrawableDown() && getLowerListBuilding().isEmpty())) && ((currentState.getNUpper() ==0)||(!hasDrawableUp() && getUpperListBuilding().isEmpty())))</b>
|
||
<b class="fc"> nextPlayerSetup();</b>
|
||
<b class="fc"> return true;</b>
|
||
|
||
}
|
||
|
||
/**
|
||
* Attempts to draw the upper building card at the specified index for the specified player.
|
||
* The operation succeeds only if the index is valid, the game stage is {@code RESOLVING_ACTIONS},
|
||
* the specified player is the current player, at least one upper card draw is still available,
|
||
* and the selected building card can be bought by the player.
|
||
* If successful, the building card is removed from the board and the number of remaining upper draws is decremented.
|
||
* If both upper and lower draws become zero, the next player setup is triggered.
|
||
*
|
||
* @param player the player performing the draw.
|
||
* @param cardIndex the index of the upper building card to draw.
|
||
* @return {@code true} if the draw succeeds, {@code false} otherwise.
|
||
*/
|
||
public boolean drawUpperBuildingCardByIndex(Player player,int cardIndex) {
|
||
<b class="fc"> if( cardIndex<0 || cardIndex >=board.getUpperListBuilding().size())</b>
|
||
<b class="fc"> return false;</b>
|
||
<b class="fc"> if(currentState.getGameStage()!= GameStages.RES_ACTIONS && currentState.getGameStage()!=GameStages.OPT_CARD_E)</b>
|
||
{
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
<b class="fc"> if(!player.equals(currentState.getCurrentPlayer()))</b>
|
||
{
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
<b class="fc"> BuildingCard buildingCard = board.getUpperListBuilding().get(cardIndex);</b>
|
||
<b class="fc"> if(currentState.getNUpper() <1 && currentState.getGameStage()==GameStages.RES_ACTIONS)</b>
|
||
<b class="fc"> return false;</b>
|
||
<b class="fc"> if(!buildingCard.buy(player))</b>
|
||
{
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
<b class="fc"> board.removeUpperBuildingCard(buildingCard);</b>
|
||
<b class="fc"> if(currentState.getGameStage() == GameStages.RES_ACTIONS)</b>
|
||
{
|
||
<b class="fc"> currentState.upperDrawn();</b>
|
||
<b class="pc"> if((currentState.getNLower() ==0 ||( !hasDrawableDown() && getLowerListBuilding().isEmpty())) && ((currentState.getNUpper() ==0)||(!hasDrawableUp() && getUpperListBuilding().isEmpty())))</b>
|
||
<b class="fc"> nextPlayerSetup();</b>
|
||
}
|
||
else
|
||
{
|
||
<b class="fc"> nextPlayerSetup();</b>
|
||
}
|
||
<b class="fc"> return true;</b>
|
||
}
|
||
|
||
/**
|
||
* Attempts to draw the lower building card at the specified index for the specified player.
|
||
* The operation succeeds only if the index is valid, the game stage is {@code RESOLVING_ACTIONS},
|
||
* the specified player is the current player, at least one lower card draw is still available,
|
||
* and the selected building card can be bought by the player.
|
||
* If successful, the building card is removed from the board and the number of remaining lower draws is decremented.
|
||
* If both lower and upper draws become zero, the next player setup is triggered.
|
||
*
|
||
* @param player the player performing the draw.
|
||
* @param cardIndex the index of the lower building card to draw.
|
||
* @return {@code true} if the draw succeeds, {@code false} otherwise.
|
||
*/
|
||
public boolean drawLowerBuildingCardByIndex(Player player,int cardIndex) {
|
||
<b class="fc"> if( cardIndex<0 || cardIndex >=board.getLowerListBuilding().size())</b>
|
||
<b class="fc"> return false;</b>
|
||
<b class="pc"> if(currentState.getGameStage()!= GameStages.RES_ACTIONS)</b>
|
||
{
|
||
<b class="nc"> return false;</b>
|
||
}
|
||
|
||
<b class="fc"> if(!player.equals(currentState.getCurrentPlayer()))</b>
|
||
{
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
<b class="fc"> BuildingCard buildingCard = board.getLowerListBuilding().get(cardIndex);</b>
|
||
<b class="pc"> if(currentState.getNLower() <1)</b>
|
||
<b class="nc"> return false;</b>
|
||
<b class="fc"> if(buildingCard.buy(player))</b>
|
||
{
|
||
<b class="fc"> currentState.lowerDrawn();</b>
|
||
<b class="fc"> board.removeLowerBuildingCard(buildingCard);</b>
|
||
}
|
||
else
|
||
<b class="fc"> return false;</b>
|
||
<b class="pc"> if((currentState.getNLower() ==0 ||( !hasDrawableDown() && getLowerListBuilding().isEmpty())) && ((currentState.getNUpper() ==0)||(!hasDrawableUp() && getUpperListBuilding().isEmpty())))</b>
|
||
<b class="fc"> nextPlayerSetup();</b>
|
||
|
||
<b class="fc"> return true;</b>
|
||
|
||
}
|
||
|
||
|
||
//region Optional Card Methods
|
||
|
||
/**
|
||
* Prepares the next player and updates the game state according to the current game stage.
|
||
* If the current stage is {@code SLOT_CHOICE}, the next player is taken from the order logic card.
|
||
* If no player is available, the game stage is updated to {@code RESOLVING_ACTIONS}
|
||
* and the first assigned slot is selected.
|
||
* If the current stage is {@code RESOLVING_ACTIONS}, the current player is pushed back
|
||
* into the order logic card, the current slot is freed, and the next assigned slot is selected.
|
||
* If no assigned slots remain, the game stage is updated to {@code OPTIONAL_CARD_EFFECT},
|
||
* the optional card queue is built from players owning building cards with effect id equal to 12,
|
||
* and the first player in that queue is selected.
|
||
* If no player is available for optional card resolution, the game stage is updated to
|
||
* {@code RESOLVING_EVENT}; then, if the round number is less than 10, the next round is prepared,
|
||
* otherwise event resolution is performed, the game stage is updated to {@code ENDING},
|
||
* and the game is ended.
|
||
* If the current stage is {@code OPTIONAL_CARD_EFFECT}, the next player is taken from the optional card queue.
|
||
* If no player is available, the game stage is updated to {@code RESOLVING_EVENT}.
|
||
*/
|
||
private synchronized void nextPlayerSetup() {
|
||
|
||
<b class="fc"> if (GameStages.SLOT_CHOICE == currentState.getGameStage()) {</b>
|
||
Player tempPlayer;
|
||
while (true) {
|
||
<b class="fc"> tempPlayer = orderLogicCard.pull();</b>
|
||
<b class="fc"> if (tempPlayer == null) break;</b>
|
||
<b class="pc"> if (!disconnectedPlayers.containsKey(tempPlayer) || !disconnectedPlayers.get(tempPlayer)) break;</b>
|
||
}
|
||
<b class="fc"> if (tempPlayer != null) {</b>
|
||
<b class="fc"> currentState.playerUpdate(tempPlayer, null);</b>
|
||
return;
|
||
}
|
||
|
||
// All players have chosen a slot → switch to RES_ACTIONS
|
||
<b class="fc"> currentState.gameStageUpdate(GameStages.RES_ACTIONS);</b>
|
||
|
||
<b class="fc"> boolean anyAssigned = false;</b>
|
||
<b class="pc"> for (Map.Entry<Slot,Player> entry : slotMap.entrySet()) {</b>
|
||
<b class="fc"> if (entry.getValue() != null) {</b>
|
||
<b class="fc"> if(entry.getKey().getSlotId()=='A')</b>
|
||
{
|
||
<b class="fc"> entry.getValue().addFood(3);</b>
|
||
<b class="fc"> orderLogicCard.push(entry.getValue());</b>
|
||
<b class="fc"> entry.setValue(null);</b>
|
||
continue;
|
||
}
|
||
<b class="fc"> currentState.playerUpdate(entry.getValue(), entry.getKey());</b>
|
||
<b class="fc"> boolean hasDrawableLower = currentState.getNLower() > 0</b>
|
||
<b class="pc"> && (hasDrawableDown() || !getLowerListBuilding().isEmpty());</b>
|
||
<b class="fc"> boolean hasDrawableUpper = currentState.getNUpper() > 0</b>
|
||
<b class="pc"> && (hasDrawableUp() || !getUpperListBuilding().isEmpty());</b>
|
||
<b class="pc"> if (!hasDrawableLower && !hasDrawableUpper) {</b>
|
||
// This player has nothing drawable, skip them immediately
|
||
<b class="nc"> orderLogicCard.push(currentState.getCurrentPlayer());</b>
|
||
<b class="nc"> slotMap.put(currentState.getSlot(), null);</b>
|
||
} else {
|
||
<b class="fc"> anyAssigned = true;</b>
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// If every player was skipped, jump straight to optional phase
|
||
<b class="pc"> if (!anyAssigned) {</b>
|
||
<b class="nc"> transitionToOptionalOrNextRound();</b>
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
<b class="fc"> if (GameStages.RES_ACTIONS == currentState.getGameStage()) {</b>
|
||
<b class="fc"> orderLogicCard.push(currentState.getCurrentPlayer());</b>
|
||
<b class="fc"> slotMap.put(currentState.getSlot(), null);</b>
|
||
|
||
<b class="fc"> for (Map.Entry<Slot,Player> entry : slotMap.entrySet()) {</b>
|
||
<b class="fc"> if (entry.getValue() != null) {</b>
|
||
<b class="pc"> if(disconnectedPlayers.containsKey(entry.getValue())&& disconnectedPlayers.get(entry.getValue()))</b>
|
||
{
|
||
<b class="nc"> orderLogicCard.push(entry.getValue());</b>
|
||
<b class="nc"> entry.setValue(null);</b>
|
||
continue;
|
||
}
|
||
<b class="fc"> currentState.playerUpdate(entry.getValue(), entry.getKey());</b>
|
||
<b class="fc"> boolean hasDrawableLower = currentState.getNLower() > 0</b>
|
||
<b class="pc"> && (hasDrawableDown() || !getLowerListBuilding().isEmpty());</b>
|
||
<b class="fc"> boolean hasDrawableUpper = currentState.getNUpper() > 0</b>
|
||
<b class="pc"> && (hasDrawableUp() || !getUpperListBuilding().isEmpty());</b>
|
||
<b class="pc"> if (!hasDrawableLower && !hasDrawableUpper) {</b>
|
||
// This player also has nothing, skip and continue the loop
|
||
<b class="nc"> orderLogicCard.push(entry.getValue());</b>
|
||
<b class="nc"> entry.setValue(null);</b>
|
||
} else {
|
||
// Found a player with something to do, stop here
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
// All slots are now null → every player is done for this round
|
||
<b class="fc"> transitionToOptionalOrNextRound();</b>
|
||
return;
|
||
}
|
||
|
||
<b class="pc"> if (GameStages.OPT_CARD_E == currentState.getGameStage()) {</b>
|
||
<b class="fc"> Player optionalPlayer = optionalCardQueue.poll();</b>
|
||
|
||
<b class="fc"> if (optionalPlayer != null) {</b>
|
||
<b class="fc"> currentState.playerUpdate(optionalPlayer, null);</b>
|
||
<b class="pc"> if(disconnectedPlayers.containsKey(currentState.getCurrentPlayer())&& disconnectedPlayers.get(currentState.getCurrentPlayer())) {</b>
|
||
<b class="nc"> nextPlayerSetup();</b>
|
||
}
|
||
return;
|
||
}
|
||
|
||
<b class="fc"> currentState.gameStageUpdate(GameStages.RES_EVENT);</b>
|
||
|
||
<b class="fc"> if (currentState.getRound() < 10) {</b>
|
||
<b class="fc"> nextRound();</b>
|
||
<b class="fc"> currentState.playerUpdate(orderLogicCard.pull(), null);</b>
|
||
<b class="fc"> currentState.gameStageUpdate(GameStages.SLOT_CHOICE);</b>
|
||
} else {
|
||
<b class="fc"> currentState.gameStageUpdate(GameStages.ENDING);</b>
|
||
<b class="fc"> endGame();</b>
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* Transitions the game to the optional card phase or directly to the next round.
|
||
*
|
||
* <p>Builds a queue of non-disconnected players who own Building 12 (optional card effect).
|
||
* If such players exist, the first one is set as the current player for their optional action.
|
||
* Otherwise, if the round counter is below 10, the next round begins and the game stage
|
||
* is set to {@link GameStages#SLOT_CHOICE}; if round 10 has been completed, the game ends.
|
||
*/
|
||
private synchronized void transitionToOptionalOrNextRound() {
|
||
<b class="fc"> currentState.gameStageUpdate(GameStages.OPT_CARD_E);</b>
|
||
|
||
<b class="fc"> optionalCardQueue = new LinkedList<>();</b>
|
||
<b class="fc"> for (Player p :playersList) {</b>
|
||
<b class="fc"> long count = p.getBuildingCards().stream().filter(x -> x.getEffectId() == 12).count();</b>
|
||
<b class="fc"> if (count > 0) {</b>
|
||
<b class="pc"> if(disconnectedPlayers.containsKey(p)&& disconnectedPlayers.get(p))</b>
|
||
{
|
||
continue;
|
||
}
|
||
<b class="fc"> optionalCardQueue.add(p);</b>
|
||
}
|
||
}
|
||
|
||
<b class="fc"> Player optionalPlayer = optionalCardQueue.poll();</b>
|
||
|
||
<b class="fc"> if (optionalPlayer != null) {</b>
|
||
<b class="fc"> currentState.playerUpdate(optionalPlayer, null);</b>
|
||
return;
|
||
}
|
||
|
||
<b class="fc"> if (currentState.getRound() < 10) {</b>
|
||
<b class="fc"> nextRound();</b>
|
||
<b class="pc"> for (Map.Entry<Player, Boolean> entry : new ArrayList<>(disconnectedPlayers.entrySet())) {</b>
|
||
<b class="nc"> if (!entry.getValue()) {</b>
|
||
<b class="nc"> orderLogicCard.pushNoEffect(entry.getKey());</b>
|
||
<b class="nc"> disconnectedPlayers.remove(entry.getKey());</b>
|
||
} else {
|
||
<b class="nc"> orderLogicCard.removeFromQueue(entry.getKey());</b>
|
||
}
|
||
}
|
||
<b class="fc"> currentState.playerUpdate(orderLogicCard.pull(), null);</b>
|
||
<b class="fc"> currentState.gameStageUpdate(GameStages.SLOT_CHOICE);</b>
|
||
} else {
|
||
<b class="fc"> currentState.gameStageUpdate(GameStages.ENDING);</b>
|
||
<b class="fc"> endGame();</b>
|
||
}
|
||
}
|
||
/**
|
||
* Checks whether there are any drawable upper tribe cards on the board,
|
||
* i.e. upper tribe cards that are not event cards.
|
||
*
|
||
* @return {@code true} if at least one non-event upper tribe card is available, {@code false} otherwise.
|
||
*/
|
||
private boolean hasDrawableUp()
|
||
{
|
||
<b class="fc"> return getUpperListTribeCards().stream().anyMatch(x -> !x.isEventCard());</b>
|
||
}
|
||
|
||
/**
|
||
* Checks whether there are any drawable lower tribe cards on the board,
|
||
* i.e. lower tribe cards that are not event cards.
|
||
*
|
||
* @return {@code true} if at least one non-event lower tribe card is available, {@code false} otherwise.
|
||
*/
|
||
private boolean hasDrawableDown()
|
||
{
|
||
<b class="fc"> return getLowerListTribeCards().stream().anyMatch(x -> !x.isEventCard());</b>
|
||
}
|
||
/**
|
||
* Resolves all pending event cards if the current game stage is {@code RESOLVING_EVENT}.
|
||
* All pending events are activated on the player list.
|
||
* Event cards of type {@code SUSTENANCE} are resolved after all other pending events.
|
||
*/
|
||
private void eventResolution() {
|
||
|
||
<b class="fc"> currentState.gameStageUpdate(GameStages.RES_EVENT);</b>
|
||
Queue<EventCard> events;
|
||
<b class="fc"> events=board.getPendingEvents();</b>
|
||
<b class="fc"> ArrayList<EventCard>sustenance=events.stream().filter(x->x.getType().equals(EventType.SUSTENANCE)).collect(Collectors.toCollection(ArrayList::new));</b>
|
||
<b class="fc"> events.removeAll(sustenance);</b>
|
||
<b class="fc"> for(EventCard event:events)</b>
|
||
{
|
||
<b class="fc"> event.activateEvent(playersList);</b>
|
||
}
|
||
|
||
<b class="fc"> for(EventCard e : sustenance)</b>
|
||
{
|
||
<b class="fc"> e.activateEvent(playersList);</b>
|
||
}
|
||
|
||
}
|
||
|
||
|
||
/**
|
||
* Advances the game to the next round.
|
||
* The method first resolves pending events.
|
||
* If the current round is 10, the game stage is updated to {@code ENDING} and the game is ended.
|
||
* Otherwise, the era is updated if the board changes era, and the round number is incremented.
|
||
*/
|
||
private void nextRound() {
|
||
|
||
<b class="fc"> eventResolution();</b>
|
||
<b class="fc"> if(currentState.getEra()!= board.nextRound()) {</b>
|
||
<b class="fc"> currentState.eraUpdate();</b>
|
||
}
|
||
|
||
<b class="fc"> currentState.roundUpdate();</b>
|
||
|
||
}
|
||
|
||
/**
|
||
* Ends the game by applying all final building effects owned by each player
|
||
* and updating the game stage to {@code ENDED}.
|
||
*/
|
||
private void endGame() {
|
||
Queue<EventCard> events;
|
||
<b class="fc"> events=Stream.concat(board.getLowerListTribe().stream().filter(TribeCard::isEventCard),board.getUpperListTribe().stream().filter(TribeCard::isEventCard)).map(x->((EventCard)x)).collect(Collectors.toCollection(LinkedList::new));</b>
|
||
<b class="fc"> ArrayList<EventCard>sustenance=events.stream().filter(x->x.getType().equals(EventType.SUSTENANCE)).collect(Collectors.toCollection(ArrayList::new));</b>
|
||
<b class="fc"> events.removeAll(sustenance);</b>
|
||
<b class="fc"> events.forEach(event->event.activateEvent(playersList));</b>
|
||
<b class="fc"> sustenance.forEach(event->event.activateEvent(playersList));</b>
|
||
|
||
<b class="fc"> playersList.forEach(p->{</b>
|
||
<b class="fc"> int temp= p.getBuilders().stream().mapToInt(Builder::getPrestigeValue).sum();</b>
|
||
<b class="fc"> p.addPrestige(temp);</b>
|
||
});
|
||
<b class="fc"> playersList.forEach(p->{</b>
|
||
<b class="fc"> int temp=(int) p.getInventors().stream().mapToInt(Inventor::getIcon).distinct().count();</b>
|
||
<b class="fc"> p.addPrestige(temp*p.getNType(CharacterType.INVENTOR));</b>
|
||
});
|
||
<b class="fc"> playersList.forEach(p->{</b>
|
||
<b class="fc"> p.addPrestige(10 * (p.getNType(CharacterType.ARTIST)/2));</b>
|
||
});
|
||
<b class="fc"> playersList.forEach(p->{</b>
|
||
<b class="fc"> int temp= p.getBuildingCards().stream().mapToInt(BuildingCard::getPrestigeValue).sum();</b>
|
||
<b class="fc"> p.addPrestige(temp);</b>
|
||
});
|
||
<b class="fc"> playersList.forEach(</b>
|
||
<b class="pc"> p -> p.getBuildingCards().stream().filter(x -> x.getEffectType() == EffectType.FINAL).</b>
|
||
<b class="fc"> forEach(x -> x.applyEffect(p))</b>
|
||
);
|
||
<b class="fc"> currentState.gameStageUpdate(GameStages.ENDED);</b>
|
||
<b class="fc"> playerStanding=new ArrayList<>(playersList);</b>
|
||
<b class="fc"> playerStanding.sort((y,x)->x.getPrestigeValue()==y.getPrestigeValue()?Integer.compare(x.getFoodValue(),y.getFoodValue()):Integer.compare(x.getPrestigeValue(),y.getPrestigeValue()));</b>
|
||
|
||
}
|
||
|
||
/**
|
||
* Sets the configured number of players for this game.
|
||
* The operation succeeds only if the current configured number of players is 0.
|
||
*
|
||
* @param nPlayers the new configured number of players.
|
||
* @return {@code true} if the number of players is updated, {@code false} otherwise.
|
||
*/
|
||
public boolean setNPlayer(int nPlayers) {
|
||
<b class="fc"> if (this.nPlayers != 0) {</b>
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
|
||
<b class="fc"> if (nPlayers < 2 || nPlayers > 5) {</b>
|
||
<b class="fc"> return false;</b>
|
||
}
|
||
|
||
<b class="fc"> this.nPlayers = nPlayers;</b>
|
||
|
||
<b class="fc"> board = new Board(nPlayers);</b>
|
||
|
||
<b class="fc"> slotMap = new LinkedHashMap<>();</b>
|
||
<b class="fc"> for (Slot s : board.getSlotList()) {</b>
|
||
<b class="fc"> slotMap.put(s, null);</b>
|
||
}
|
||
|
||
<b class="fc"> currentState = new CurrentState();</b>
|
||
<b class="fc"> playersList = new ArrayList<>();</b>
|
||
<b class="fc"> optionalCardQueue = new LinkedList<>();</b>
|
||
|
||
<b class="fc"> return true;</b>
|
||
}
|
||
|
||
/**
|
||
* Ends the game by forfeit and determines the final player standing.
|
||
*
|
||
* <p>The player who is still connected is declared the winner and placed
|
||
* in the first position of the final ranking. The remaining players are
|
||
* ordered by prestige value and, in case of a tie, by food value.
|
||
*/
|
||
public synchronized void endGameForfeit() {
|
||
<b class="nc"> Player winner = playersList.stream()</b>
|
||
<b class="nc"> .filter(x -> !disconnectedPlayers.containsKey(x) || !disconnectedPlayers.get(x))</b>
|
||
<b class="nc"> .findFirst().orElse(null);</b>
|
||
<b class="nc"> if (winner == null) return;</b>
|
||
<b class="nc"> currentState.gameStageUpdate(GameStages.ENDED);</b>
|
||
<b class="nc"> playerStanding = new ArrayList<>(playersList);</b>
|
||
<b class="nc"> playerStanding.remove(winner);</b>
|
||
<b class="nc"> playerStanding.sort((y, x) -> x.getPrestigeValue() == y.getPrestigeValue()</b>
|
||
<b class="nc"> ? Integer.compare(x.getFoodValue(), y.getFoodValue())</b>
|
||
<b class="nc"> : Integer.compare(x.getPrestigeValue(), y.getPrestigeValue()));</b>
|
||
<b class="nc"> playerStanding.add(0, winner);</b>
|
||
}
|
||
|
||
|
||
}
|
||
</code>
|
||
</pre>
|
||
</div>
|
||
|
||
<script type="text/javascript">
|
||
(function() {
|
||
var msie = false, msie9 = false;
|
||
/*@cc_on
|
||
msie = true;
|
||
@if (@_jscript_version >= 9)
|
||
msie9 = true;
|
||
@end
|
||
@*/
|
||
|
||
if (!msie || msie && msie9) {
|
||
hljs.highlightAll()
|
||
hljs.initLineNumbersOnLoad();
|
||
}
|
||
})();
|
||
</script>
|
||
|
||
<div class="footer">
|
||
|
||
<div style="float:right;">generated on 2026-06-19 22:53</div>
|
||
</div>
|
||
</body>
|
||
</html>
|