diff options
Diffstat (limited to 'src')
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); |