summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/luxons/sevenwonders/game/Game.java44
-rw-r--r--src/main/java/org/luxons/sevenwonders/game/cards/Hands.java14
-rw-r--r--src/test/java/org/luxons/sevenwonders/game/cards/HandsTest.java63
3 files changed, 112 insertions, 9 deletions
diff --git a/src/main/java/org/luxons/sevenwonders/game/Game.java b/src/main/java/org/luxons/sevenwonders/game/Game.java
index dd98f421..1fab129c 100644
--- a/src/main/java/org/luxons/sevenwonders/game/Game.java
+++ b/src/main/java/org/luxons/sevenwonders/game/Game.java
@@ -96,18 +96,31 @@ public class Game {
}
public void playTurn() {
+ makeMoves();
+ if (endOfAgeReached()) {
+ executeEndOfAgeEvents();
+ startNewAge();
+ } else {
+ hands.rotate(getHandRotationOffset());
+ }
+ }
+
+ private void makeMoves() {
List<Move> playedMoves = mapToList(preparedMoves);
- // cards need to be all placed first as some effects depend on just-played cards
+ // all cards from this turn need to be placed before executing any effect
+ // because effects depending on played cards need to take the ones from the current turn into account too
placePreparedCards(playedMoves);
+
+ // same goes for the discarded cards during the last turn, which should be available for special actions
+ if (lastTurnOfAge()) {
+ discardedCards.addAll(hands.gatherAndClear());
+ }
+
activatePlayedCards(playedMoves);
+
table.setLastPlayedMoves(playedMoves);
preparedMoves.clear();
- if (endOfAgeReached()) {
- startNewAge();
- } else {
- hands.rotate(getHandRotationOffset());
- }
}
private static List<Move> mapToList(Map<Integer, Move> movesPerPlayer) {
@@ -125,11 +138,14 @@ public class Game {
private void placePreparedCards(List<Move> playedMoves) {
playedMoves.forEach(move -> {
placeCard(move);
- Card card = decks.getCard(move.getCardName());
- hands.get(move.getPlayerIndex()).remove(card);
+ removeFromHand(move.getPlayerIndex(), move.getCardName());
});
}
+ private boolean lastTurnOfAge() {
+ return hands.maxOneCardRemains();
+ }
+
private void placeCard(Move move) {
switch (move.getType()) {
case PLAY:
@@ -144,6 +160,12 @@ public class Game {
}
}
+ private void removeFromHand(int playerIndex, String cardName) {
+ Card card = decks.getCard(cardName);
+ List<Card> hand = hands.get(playerIndex);
+ hand.remove(card);
+ }
+
private void activatePlayedCards(List<Move> playedMoves) {
playedMoves.forEach(this::activateCard);
}
@@ -163,7 +185,11 @@ public class Game {
}
private boolean endOfAgeReached() {
- return hands.get(0).size() == 1;
+ return hands.isEmpty();
+ }
+
+ private void executeEndOfAgeEvents() {
+ // TODO resolve military conflicts
}
private int getHandRotationOffset() {
diff --git a/src/main/java/org/luxons/sevenwonders/game/cards/Hands.java b/src/main/java/org/luxons/sevenwonders/game/cards/Hands.java
index 4a5588c9..4d09c53b 100644
--- a/src/main/java/org/luxons/sevenwonders/game/cards/Hands.java
+++ b/src/main/java/org/luxons/sevenwonders/game/cards/Hands.java
@@ -42,6 +42,20 @@ public class Hands {
return new Hands(newHands, nbPlayers);
}
+ public boolean isEmpty() {
+ return hands.values().stream().allMatch(List::isEmpty);
+ }
+
+ public boolean maxOneCardRemains() {
+ return hands.values().stream().mapToInt(List::size).max().orElse(0) <= 1;
+ }
+
+ public List<Card> gatherAndClear() {
+ List<Card> remainingCards = hands.values().stream().flatMap(List::stream).collect(Collectors.toList());
+ hands.clear();
+ return remainingCards;
+ }
+
class PlayerIndexOutOfBoundsException extends ArrayIndexOutOfBoundsException {
PlayerIndexOutOfBoundsException(int index) {
super(index);
diff --git a/src/test/java/org/luxons/sevenwonders/game/cards/HandsTest.java b/src/test/java/org/luxons/sevenwonders/game/cards/HandsTest.java
index 97cb4625..86763450 100644
--- a/src/test/java/org/luxons/sevenwonders/game/cards/HandsTest.java
+++ b/src/test/java/org/luxons/sevenwonders/game/cards/HandsTest.java
@@ -5,13 +5,30 @@ import java.util.List;
import java.util.Map;
import org.junit.Test;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.FromDataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
import org.luxons.sevenwonders.game.cards.Hands.PlayerIndexOutOfBoundsException;
import org.luxons.sevenwonders.game.test.TestUtils;
import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+@RunWith(Theories.class)
public class HandsTest {
+ @DataPoints("nbCardsPerPlayer")
+ public static int[] nbCardsPerPlayer() {
+ return new int[] {0, 1, 2, 3, 4, 5, 6, 7};
+ }
+
+ @DataPoints("nbPlayers")
+ public static int[] nbPlayers() {
+ return new int[] {3, 4, 5, 6, 7};
+ }
+
private static Hands createHands(int nbPlayers, int nbCardsPerPlayer) {
Map<Integer, List<Card>> hands = new HashMap<>();
for (int p = 0; p < nbPlayers; p++) {
@@ -39,6 +56,52 @@ public class HandsTest {
assertEquals(hand1, hands.get(1));
}
+ @Theory
+ public void isEmpty_falseWhenAtLeast1_allSame(@FromDataPoints("nbPlayers") int nbPlayers,
+ @FromDataPoints("nbCardsPerPlayer") int nbCardsPerPlayer) {
+ assumeTrue(nbCardsPerPlayer >= 1);
+ Hands hands = createHands(nbPlayers, nbCardsPerPlayer);
+ assertFalse(hands.isEmpty());
+ }
+
+ @Theory
+ public void isEmpty_trueWhenAllEmpty(@FromDataPoints("nbPlayers") int nbPlayers) {
+ Hands hands = createHands(nbPlayers, 0);
+ assertTrue(hands.isEmpty());
+ }
+
+ @Theory
+ public void maxOneCardRemains_falseWhenAtLeast2_allSame(@FromDataPoints("nbPlayers") int nbPlayers,
+ @FromDataPoints("nbCardsPerPlayer") int nbCardsPerPlayer) {
+ assumeTrue(nbCardsPerPlayer >= 2);
+ Hands hands = createHands(nbPlayers, nbCardsPerPlayer);
+ assertFalse(hands.maxOneCardRemains());
+ }
+
+ @Theory
+ public void maxOneCardRemains_trueWhenAtMost1_allSame(@FromDataPoints("nbPlayers") int nbPlayers,
+ @FromDataPoints("nbCardsPerPlayer") int nbCardsPerPlayer) {
+ assumeTrue(nbCardsPerPlayer <= 1);
+ Hands hands = createHands(nbPlayers, nbCardsPerPlayer);
+ assertTrue(hands.maxOneCardRemains());
+ }
+
+ @Theory
+ public void maxOneCardRemains_trueWhenAtMost1_someZero(@FromDataPoints("nbPlayers") int nbPlayers) {
+ Hands hands = createHands(nbPlayers, 1);
+ hands.get(0).remove(0);
+ assertTrue(hands.maxOneCardRemains());
+ }
+
+ @Theory
+ public void gatherAndClear(@FromDataPoints("nbPlayers") int nbPlayers,
+ @FromDataPoints("nbCardsPerPlayer") int nbCardsPerPlayer) {
+ Hands hands = createHands(nbPlayers, nbCardsPerPlayer);
+ List<Card> remainingCards = hands.gatherAndClear();
+ assertEquals(nbPlayers * nbCardsPerPlayer, remainingCards.size());
+ assertTrue(hands.isEmpty());
+ }
+
@Test
public void rotate_doesNotMoveWhenOffsetIsZero() {
Hands hands = createHands(3, 7);
bgstack15