summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/luxons/sevenwonders/game/Game.java29
-rw-r--r--src/main/java/org/luxons/sevenwonders/game/cards/Decks.java10
-rw-r--r--src/main/java/org/luxons/sevenwonders/game/cards/Hands.java50
-rw-r--r--src/test/java/org/luxons/sevenwonders/game/cards/DecksTest.java66
-rw-r--r--src/test/java/org/luxons/sevenwonders/game/cards/HandsTest.java77
-rw-r--r--src/test/java/org/luxons/sevenwonders/game/test/TestUtils.java13
6 files changed, 191 insertions, 54 deletions
diff --git a/src/main/java/org/luxons/sevenwonders/game/Game.java b/src/main/java/org/luxons/sevenwonders/game/Game.java
index 389ef844..9023a80f 100644
--- a/src/main/java/org/luxons/sevenwonders/game/Game.java
+++ b/src/main/java/org/luxons/sevenwonders/game/Game.java
@@ -5,13 +5,14 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
+import java.util.stream.IntStream;
-import org.luxons.sevenwonders.game.api.HandCard;
import org.luxons.sevenwonders.game.api.PlayerTurnInfo;
import org.luxons.sevenwonders.game.api.Table;
import org.luxons.sevenwonders.game.boards.Board;
import org.luxons.sevenwonders.game.cards.Card;
import org.luxons.sevenwonders.game.cards.Decks;
+import org.luxons.sevenwonders.game.cards.Hands;
public class Game {
@@ -29,7 +30,7 @@ public class Game {
private final Map<Integer, Move> preparedMoves;
- private Map<Integer, List<Card>> hands;
+ private Hands hands;
private int currentAge = 0;
@@ -40,7 +41,6 @@ public class Game {
this.table = new Table(boards);
this.decks = decks;
this.discardedCards = new ArrayList<>();
- this.hands = new HashMap<>();
this.preparedMoves = new HashMap<>();
startNewAge();
}
@@ -59,21 +59,16 @@ public class Game {
}
public List<PlayerTurnInfo> getTurnInfo() {
- return hands.entrySet().stream().map(e -> createPlayerTurnInfo(e.getKey(), e.getValue()))
- .collect(Collectors.toList());
+ return IntStream.range(0, players.size()).mapToObj(this::createPlayerTurnInfo).collect(Collectors.toList());
}
- private PlayerTurnInfo createPlayerTurnInfo(int playerIndex, List<Card> cards) {
+ private PlayerTurnInfo createPlayerTurnInfo(int playerIndex) {
PlayerTurnInfo pti = new PlayerTurnInfo(playerIndex, table);
- pti.setHand(createHand(playerIndex, cards));
+ pti.setHand(hands.createHand(table, playerIndex));
pti.setCurrentAge(currentAge);
return pti;
}
- private List<HandCard> createHand(int playerIndex, List<Card> cards) {
- return cards.stream().map(c -> new HandCard(c, table, playerIndex)).collect(Collectors.toList());
- }
-
public void prepareCard(Move move) throws InvalidMoveException {
validate(move);
preparedMoves.put(move.getPlayerIndex(), move);
@@ -110,7 +105,7 @@ public class Game {
if (endOfAgeReached()) {
startNewAge();
} else {
- rotateHands();
+ hands.rotate(getHandRotationOffset());
}
}
@@ -170,16 +165,6 @@ public class Game {
return hands.get(0).size() == 1;
}
- private void rotateHands() {
- int offset = getHandRotationOffset();
- Map<Integer, List<Card>> newHands = new HashMap<>(hands.size());
- for (int i = 0; i < players.size(); i++) {
- int newIndex = Math.floorMod(i + offset, players.size());
- newHands.put(newIndex, hands.get(i));
- }
- hands = newHands;
- }
-
private int getHandRotationOffset() {
// clockwise at age 1, and alternating
return currentAge % 2 == 0 ? -1 : 1;
diff --git a/src/main/java/org/luxons/sevenwonders/game/cards/Decks.java b/src/main/java/org/luxons/sevenwonders/game/cards/Decks.java
index b798b035..aa2b00bf 100644
--- a/src/main/java/org/luxons/sevenwonders/game/cards/Decks.java
+++ b/src/main/java/org/luxons/sevenwonders/game/cards/Decks.java
@@ -22,7 +22,7 @@ public class Decks {
.orElseThrow(() -> new CardNotFoundException(cardName));
}
- public Map<Integer, List<Card>> deal(int age, int nbPlayers) {
+ public Hands deal(int age, int nbPlayers) {
List<Card> deck = getDeck(age);
validateNbCards(deck, nbPlayers);
return deal(deck, nbPlayers);
@@ -46,13 +46,15 @@ public class Decks {
}
}
- private Map<Integer, List<Card>> deal(List<Card> deck, int nbPlayers) {
+ private Hands deal(List<Card> deck, int nbPlayers) {
Map<Integer, List<Card>> hands = new HashMap<>(nbPlayers);
+ for (int i = 0; i < nbPlayers; i++) {
+ hands.put(i, new ArrayList<>());
+ }
for (int i = 0; i < deck.size(); i++) {
- hands.putIfAbsent(i % nbPlayers, new ArrayList<>());
hands.get(i % nbPlayers).add(deck.get(i));
}
- return hands;
+ return new Hands(hands, nbPlayers);
}
class CardNotFoundException extends RuntimeException {
diff --git a/src/main/java/org/luxons/sevenwonders/game/cards/Hands.java b/src/main/java/org/luxons/sevenwonders/game/cards/Hands.java
new file mode 100644
index 00000000..4a5588c9
--- /dev/null
+++ b/src/main/java/org/luxons/sevenwonders/game/cards/Hands.java
@@ -0,0 +1,50 @@
+package org.luxons.sevenwonders.game.cards;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.luxons.sevenwonders.game.api.HandCard;
+import org.luxons.sevenwonders.game.api.Table;
+
+public class Hands {
+
+ private final int nbPlayers;
+
+ private Map<Integer, List<Card>> hands;
+
+ Hands(Map<Integer, List<Card>> hands, int nbPlayers) {
+ this.hands = hands;
+ this.nbPlayers = nbPlayers;
+ }
+
+ public List<Card> get(int playerIndex) {
+ if (!hands.containsKey(playerIndex)) {
+ throw new PlayerIndexOutOfBoundsException(playerIndex);
+ }
+ return hands.get(playerIndex);
+ }
+
+ public List<HandCard> createHand(Table table, int playerIndex) {
+ return hands.get(playerIndex)
+ .stream()
+ .map(c -> new HandCard(c, table, playerIndex))
+ .collect(Collectors.toList());
+ }
+
+ public Hands rotate(int offset) {
+ Map<Integer, List<Card>> newHands = new HashMap<>(hands.size());
+ for (int i = 0; i < nbPlayers; i++) {
+ int newIndex = Math.floorMod(i + offset, nbPlayers);
+ newHands.put(newIndex, hands.get(i));
+ }
+ return new Hands(newHands, nbPlayers);
+ }
+
+ class PlayerIndexOutOfBoundsException extends ArrayIndexOutOfBoundsException {
+ PlayerIndexOutOfBoundsException(int index) {
+ super(index);
+ }
+ }
+}
diff --git a/src/test/java/org/luxons/sevenwonders/game/cards/DecksTest.java b/src/test/java/org/luxons/sevenwonders/game/cards/DecksTest.java
index b7fad970..06060f16 100644
--- a/src/test/java/org/luxons/sevenwonders/game/cards/DecksTest.java
+++ b/src/test/java/org/luxons/sevenwonders/game/cards/DecksTest.java
@@ -1,34 +1,42 @@
package org.luxons.sevenwonders.game.cards;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
import org.luxons.sevenwonders.game.cards.Decks.CardNotFoundException;
+import org.luxons.sevenwonders.game.test.TestUtils;
import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+@RunWith(Theories.class)
public class DecksTest {
+ @DataPoints
+ public static int[] dataPoints() {
+ return new int[] {1, 2, 3, 5, 10};
+ }
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
private static Decks createDecks(int nbAges, int nbCardsPerAge) {
Map<Integer, List<Card>> cardsPerAge = new HashMap<>();
for (int age = 1; age <= nbAges; age++) {
int firstCardNumber = (age - 1) * nbCardsPerAge;
- cardsPerAge.put(age, createSampleCards(firstCardNumber, nbCardsPerAge));
+ cardsPerAge.put(age, TestUtils.createSampleCards(firstCardNumber, nbCardsPerAge));
}
return new Decks(cardsPerAge);
}
- private static List<Card> createSampleCards(int fromIndex, int nbCards) {
- List<Card> sampleCards = new ArrayList<>();
- for (int i = fromIndex; i < fromIndex + nbCards; i++) {
- sampleCards.add(new Card("Test Card " + i, Color.BLUE, null, null, null, null, null));
- }
- return sampleCards;
- }
-
@Test(expected = CardNotFoundException.class)
public void getCard_failsOnNullNameWhenDeckIsEmpty() {
Decks decks = createDecks(0, 0);
@@ -72,29 +80,31 @@ public class DecksTest {
decks.deal(4, 10);
}
- @Test(expected = IllegalArgumentException.class)
- public void deal_failsWhenTooFewPlayers() {
- Decks decks = createDecks(3, 28);
- decks.deal(1, 3);
+ @Theory
+ public void deal_failsWhenTooFewPlayers(int nbPlayers, int nbCards) {
+ assumeTrue(nbCards % nbPlayers != 0);
+ thrown.expect(IllegalArgumentException.class);
+ Decks decks = createDecks(1, nbCards);
+ decks.deal(1, nbPlayers);
}
- @Test
- public void deal_succeedsOnZeroCards() {
- Decks decks = createDecks(3, 0);
- Map<Integer, List<Card>> hands = decks.deal(1, 10);
- for (List<Card> hand : hands.values()) {
- assertTrue(hand.isEmpty());
+ @Theory
+ public void deal_succeedsOnZeroCards(int nbPlayers) {
+ Decks decks = createDecks(1, 0);
+ Hands hands = decks.deal(1, nbPlayers);
+ for (int i = 0; i < nbPlayers; i++) {
+ assertNotNull(hands.get(i));
+ assertTrue(hands.get(i).isEmpty());
}
}
- @Test
- public void deal_evenDistribution() {
- int nbCardsPerAge = 12;
- int nbPlayers = 4;
- Decks decks = createDecks(3, nbCardsPerAge);
- Map<Integer, List<Card>> hands = decks.deal(1, nbPlayers);
- for (List<Card> hand : hands.values()) {
- assertEquals(nbCardsPerAge / nbPlayers, hand.size());
+ @Theory
+ public void deal_evenDistribution(int nbPlayers, int nbCardsPerPlayer) {
+ int nbCardsPerAge = nbPlayers * nbCardsPerPlayer;
+ Decks decks = createDecks(1, nbCardsPerAge);
+ Hands hands = decks.deal(1, nbPlayers);
+ for (int i = 0; i < nbPlayers; i++) {
+ assertEquals(nbCardsPerPlayer, hands.get(i).size());
}
}
} \ No newline at end of file
diff --git a/src/test/java/org/luxons/sevenwonders/game/cards/HandsTest.java b/src/test/java/org/luxons/sevenwonders/game/cards/HandsTest.java
new file mode 100644
index 00000000..97cb4625
--- /dev/null
+++ b/src/test/java/org/luxons/sevenwonders/game/cards/HandsTest.java
@@ -0,0 +1,77 @@
+package org.luxons.sevenwonders.game.cards;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
+import org.luxons.sevenwonders.game.cards.Hands.PlayerIndexOutOfBoundsException;
+import org.luxons.sevenwonders.game.test.TestUtils;
+
+import static org.junit.Assert.*;
+
+public class HandsTest {
+
+ private static Hands createHands(int nbPlayers, int nbCardsPerPlayer) {
+ Map<Integer, List<Card>> hands = new HashMap<>();
+ for (int p = 0; p < nbPlayers; p++) {
+ int firstCardNumber = (p - 1) * nbCardsPerPlayer;
+ hands.put(p, TestUtils.createSampleCards(firstCardNumber, nbCardsPerPlayer));
+ }
+ return new Hands(hands, nbPlayers);
+ }
+
+ @Test(expected = PlayerIndexOutOfBoundsException.class)
+ public void get_failsOnMissingPlayer() {
+ Hands hands = createHands(4, 7);
+ hands.get(5);
+ }
+
+ @Test
+ public void get_retrievesCorrectCards() {
+ List<Card> hand0 = TestUtils.createSampleCards(0, 5);
+ List<Card> hand1 = TestUtils.createSampleCards(5, 10);
+ Map<Integer, List<Card>> handsMap = new HashMap<>();
+ handsMap.put(0, hand0);
+ handsMap.put(1, hand1);
+ Hands hands = new Hands(handsMap, 2);
+ assertEquals(hand0, hands.get(0));
+ assertEquals(hand1, hands.get(1));
+ }
+
+ @Test
+ public void rotate_doesNotMoveWhenOffsetIsZero() {
+ Hands hands = createHands(3, 7);
+ Hands rotated = hands.rotate(0);
+ assertEquals(rotated.get(0), hands.get(0));
+ assertEquals(rotated.get(1), hands.get(1));
+ assertEquals(rotated.get(2), hands.get(2));
+ }
+
+ @Test
+ public void rotate_movesOfCorrectOffset_positive() {
+ Hands hands = createHands(3, 7);
+ Hands rotated = hands.rotate(1);
+ assertEquals(rotated.get(1), hands.get(0));
+ assertEquals(rotated.get(2), hands.get(1));
+ assertEquals(rotated.get(0), hands.get(2));
+ }
+
+ @Test
+ public void rotate_movesOfCorrectOffset_negative() {
+ Hands hands = createHands(3, 7);
+ Hands rotated = hands.rotate(-1);
+ assertEquals(rotated.get(2), hands.get(0));
+ assertEquals(rotated.get(0), hands.get(1));
+ assertEquals(rotated.get(1), hands.get(2));
+ }
+
+ @Test
+ public void rotate_movesOfCorrectOffset_negative2() {
+ Hands hands = createHands(3, 7);
+ Hands rotated = hands.rotate(-2);
+ assertEquals(rotated.get(1), hands.get(0));
+ assertEquals(rotated.get(2), hands.get(1));
+ assertEquals(rotated.get(0), hands.get(2));
+ }
+} \ No newline at end of file
diff --git a/src/test/java/org/luxons/sevenwonders/game/test/TestUtils.java b/src/test/java/org/luxons/sevenwonders/game/test/TestUtils.java
index 2a0292cd..2a3bc379 100644
--- a/src/test/java/org/luxons/sevenwonders/game/test/TestUtils.java
+++ b/src/test/java/org/luxons/sevenwonders/game/test/TestUtils.java
@@ -1,7 +1,12 @@
package org.luxons.sevenwonders.game.test;
+import java.util.ArrayList;
+import java.util.List;
+
import org.luxons.sevenwonders.game.Settings;
import org.luxons.sevenwonders.game.boards.Board;
+import org.luxons.sevenwonders.game.cards.Card;
+import org.luxons.sevenwonders.game.cards.Color;
import org.luxons.sevenwonders.game.resources.Production;
import org.luxons.sevenwonders.game.resources.ResourceType;
import org.luxons.sevenwonders.game.resources.Resources;
@@ -49,4 +54,12 @@ public class TestUtils {
}
return resources;
}
+
+ public static List<Card> createSampleCards(int fromIndex, int nbCards) {
+ List<Card> sampleCards = new ArrayList<>();
+ for (int i = fromIndex; i < fromIndex + nbCards; i++) {
+ sampleCards.add(new Card("Test Card " + i, Color.BLUE, null, null, null, null, null));
+ }
+ return sampleCards;
+ }
}
bgstack15