Merge branch 'main' into Fix-tests-and-javadoc-idIMG

This commit is contained in:
rubenpirreram
2026-05-07 15:02:12 +02:00
committed by GitHub
14 changed files with 183 additions and 251 deletions
@@ -334,50 +334,16 @@ public class Game implements Serializable {
return true;
}
/**
* Skips the upper card draw 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, at least one upper draw is still available,
* and there are no drawable upper tribe cards (i.e. all remaining upper tribe cards are event cards)
* and no upper building cards that the player can afford.
* If successful, the upper draw counter is decremented.
* If both upper and lower draws become zero (or no cards remain drawable), the next player setup is triggered.
*
* @param player the player skipping the upper draw.
* @return {@code true} if the skip succeeds, {@code false} otherwise.
*/
public boolean SkipUpperDrawing(Player player) {
if(currentState.getGameStage()!= GameStages.RES_ACTIONS)
{
return false;
}
if(!player.equals(currentState.getCurrentPlayer()))
{
return false;
}
if(currentState.getNUpper() <1)
return false;
if(hasDrawableUp())
return false;
currentState.UpperDrawn();
if((currentState.getNLower() ==0 ||( !hasDrawableDown() && getLowerListBuilding().isEmpty())) && ((currentState.getNUpper() ==0)||(getUpperListBuilding().isEmpty())))
nextPlayerSetup();
return true;
}
/**
* Skips the lower card draw for the specified player when no drawable cards are available.
* 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, at least one lower draw is still available,
* and there are no drawable lower tribe cards (i.e. all remaining lower tribe cards are event cards)
* and no lower building cards that the player can afford.
* If successful, the lower draw counter is decremented.
* If both upper and lower draws become zero (or no cards remain drawable), the next player setup is triggered.
*
* @param player the player skipping the lower draw.
* 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 SkipLowerDrawing(Player player) {
public boolean SkipNoDrawable(Player player) {
if(currentState.getGameStage()!= GameStages.RES_ACTIONS)
{
return false;
@@ -386,13 +352,15 @@ public class Game implements Serializable {
{
return false;
}
if(currentState.getNLower() <1)
if(hasDrawableDown() && currentState.getNLower()>0 )
return false;
if(hasDrawableDown())
if(hasDrawableUp() && currentState.getNUpper()>0)
return false;
currentState.LowerDrawn();
if((currentState.getNLower() ==0 ||( getLowerListBuilding().isEmpty())) && ((currentState.getNUpper() ==0)||(!hasDrawableUp()&&getUpperListBuilding().isEmpty())))
nextPlayerSetup();
while(currentState.getNLower()>0)
currentState.LowerDrawn();
while(currentState.getNUpper()>0)
currentState.UpperDrawn();
nextPlayerSetup();
return true;
}
@@ -636,83 +604,75 @@ public class Game implements Serializable {
* If no player is available, the game stage is updated to {@code RESOLVING_EVENT}.
*/
private void nextPlayerSetup() {
if(GameStages.SLOT_CHOICE==currentState.getGameStage()) {
if (GameStages.SLOT_CHOICE == currentState.getGameStage()) {
Player tempPlayer = orderLogicCard.pull();
if(tempPlayer!=null) {
if (tempPlayer != null) {
currentState.PlayerUpdate(tempPlayer, null);
return;
}
// All players have chosen a slot → switch to RES_ACTIONS
currentState.GameStageUpdate(GameStages.RES_ACTIONS);
boolean anyAssigned = false;
for (Slot s : slotMap.keySet()) {
if (slotMap.get(s) != null) {
currentState.PlayerUpdate(slotMap.get(s), s);
if(!((currentState.getNLower() ==0 ||(!hasDrawableDown() && getLowerListBuilding().size()==0)) && ((currentState.getNUpper() ==0)||(!hasDrawableUp() && getUpperListBuilding().size()==0))))
break;
else
{
boolean hasDrawableLower = currentState.getNLower() > 0
&& (hasDrawableDown() || !getLowerListBuilding().isEmpty());
boolean hasDrawableUpper = currentState.getNUpper() > 0
&& (hasDrawableUp() || !getUpperListBuilding().isEmpty());
if (!hasDrawableLower && !hasDrawableUpper) {
// This player has nothing drawable, skip them immediately
orderLogicCard.push(currentState.getCurrentPlayer());
slotMap.put(currentState.getSlot(), null);
} else {
anyAssigned = true;
break;
}
}
}
return;
// If every player was skipped, jump straight to optional phase
if (!anyAssigned) {
transitionToOptionalOrNextRound();
}
return;
}
if(GameStages.RES_ACTIONS ==currentState.getGameStage()) {
if (GameStages.RES_ACTIONS == currentState.getGameStage()) {
orderLogicCard.push(currentState.getCurrentPlayer());
slotMap.put(currentState.getSlot(), null);
for (Slot s : slotMap.keySet()) {
if (slotMap.get(s) != null) {
currentState.PlayerUpdate(slotMap.get(s), s);
if((currentState.getNLower() ==0 ||(!hasDrawableDown() && getLowerListBuilding().size()==0)) && ((currentState.getNUpper() ==0)||( !hasDrawableUp() && getUpperListBuilding().size()==0))) {
boolean hasDrawableLower = currentState.getNLower() > 0
&& (hasDrawableDown() || !getLowerListBuilding().isEmpty());
boolean hasDrawableUpper = currentState.getNUpper() > 0
&& (hasDrawableUp() || !getUpperListBuilding().isEmpty());
if (!hasDrawableLower && !hasDrawableUpper) {
// This player also has nothing, skip and continue the loop
orderLogicCard.push(currentState.getCurrentPlayer());
slotMap.put(currentState.getSlot(), null);
}
else
{
break;
} else {
// Found a player with something to do, stop here
return;
}
}
}
if(slotMap.values().stream().allMatch(v -> v == null))
{
currentState.GameStageUpdate(GameStages.OPT_CARD_E);
HashMap<Player,Integer> optional=new LinkedHashMap<>();
for (Player p : orderLogicCard.players) {
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());
}
Player optionalPlayer = OptionalCardQueue.poll();
if (optionalPlayer != null) {
currentState.PlayerUpdate(optionalPlayer, null);
return;
}
currentState.GameStageUpdate(GameStages.RES_EVENT);
if (currentState.getRound() < 10) {
nextRound();
currentState.PlayerUpdate(orderLogicCard.pull(), null);
currentState.GameStageUpdate(GameStages.SLOT_CHOICE);
} else {
currentState.GameStageUpdate(GameStages.ENDING);
endGame();
}
return;
}
}
// All slots are now null → every player is done for this round
transitionToOptionalOrNextRound();
return;
}
if (GameStages.OPT_CARD_E == currentState.getGameStage()) {
Player optionalPlayer = OptionalCardQueue.poll();
@@ -734,7 +694,37 @@ public class Game implements Serializable {
}
}
}
//TODO
private void transitionToOptionalOrNextRound() {
currentState.GameStageUpdate(GameStages.OPT_CARD_E);
OptionalCardQueue = new LinkedList<>();
for (Player p : orderLogicCard.players) {
long count = p.buildingCards.stream().filter(x -> x.getEffectId() == 12).count();
if (count > 0) {
OptionalCardQueue.add(p);
}
}
Player optionalPlayer = OptionalCardQueue.poll();
if (optionalPlayer != null) {
currentState.PlayerUpdate(optionalPlayer, null);
return;
}
// Nobody has optional cards → go straight to event resolution
currentState.GameStageUpdate(GameStages.RES_EVENT);
if (currentState.getRound() < 10) {
nextRound();
currentState.PlayerUpdate(orderLogicCard.pull(), null);
currentState.GameStageUpdate(GameStages.SLOT_CHOICE);
} else {
currentState.GameStageUpdate(GameStages.ENDING);
endGame();
}
}
/**
* Checks whether there are any drawable upper tribe cards on the board,
* i.e. upper tribe cards that are not event cards.
@@ -743,7 +733,7 @@ public class Game implements Serializable {
*/
private boolean hasDrawableUp()
{
return getUpperListTribeCards().stream().filter(x-> !x.IsEventCard()).count()!=0;
return getUpperListTribeCards().stream().anyMatch(x -> !x.IsEventCard());
}
/**
@@ -754,7 +744,7 @@ public class Game implements Serializable {
*/
private boolean hasDrawableDown()
{
return getLowerListTribeCards().stream().filter(x-> !x.IsEventCard()).count()!=0;
return getLowerListTribeCards().stream().anyMatch(x -> !x.IsEventCard());
}
/**
* Resolves all pending event cards if the current game stage is {@code RESOLVING_EVENT}.