summaryrefslogtreecommitdiff
path: root/domain
diff options
context:
space:
mode:
Diffstat (limited to 'domain')
-rw-r--r--domain/build.gradle4
-rw-r--r--domain/src/main/java/mancala/domain/Bowl.java38
-rw-r--r--domain/src/main/java/mancala/domain/DomainSmallBowlException.java7
-rw-r--r--domain/src/main/java/mancala/domain/Kalaha.java53
-rw-r--r--domain/src/main/java/mancala/domain/Mancala.java55
-rw-r--r--domain/src/main/java/mancala/domain/MancalaException.java7
-rw-r--r--domain/src/main/java/mancala/domain/MancalaImpl.java117
-rw-r--r--domain/src/main/java/mancala/domain/SmallBowl.java113
-rw-r--r--domain/src/test/java/mancala/domain/BowlTest.java508
-rw-r--r--domain/src/test/java/mancala/domain/MancalaImplTest.java291
10 files changed, 877 insertions, 316 deletions
diff --git a/domain/build.gradle b/domain/build.gradle
index 001d2dd..fe53df0 100644
--- a/domain/build.gradle
+++ b/domain/build.gradle
@@ -11,8 +11,8 @@ repositories {
dependencies {
// Download JUnit so that we can use it in our tests.
- testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
- testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2'
+ testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.2'
+ testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.2'
testRuntimeOnly "org.junit.platform:junit-platform-commons:1.7.0"
}
diff --git a/domain/src/main/java/mancala/domain/Bowl.java b/domain/src/main/java/mancala/domain/Bowl.java
index ade728d..07859f7 100644
--- a/domain/src/main/java/mancala/domain/Bowl.java
+++ b/domain/src/main/java/mancala/domain/Bowl.java
@@ -1,12 +1,12 @@
package mancala.domain;
abstract class Bowl {
- protected int myRocks;
+ protected int myStones;
protected Player myOwner;
protected Bowl nextBowl;
- public int getMyRocks() {
- return myRocks;
+ public int getMyStones() {
+ return myStones;
}
public Bowl getNextBowl() {
@@ -25,37 +25,43 @@ abstract class Bowl {
abstract Kalaha getKalaha();
- abstract SmallBowl getSmallBowl();
+ abstract SmallBowl getNextSmallBowl();
+ abstract SmallBowl goToFirstBowlOfPlayerWithTurn();
+
+ abstract boolean isEmpty();
// abstract SmallBowl getNextSmallBowl();
void endTheGame() {
- getNextBowl().endTheGame(this, 0, 0);
+ goToFirstBowlOfPlayerWithTurn().getNextBowl().endTheGame(goToFirstBowlOfPlayerWithTurn(), 0, 0);
}
- abstract boolean isEmpty();
-
- private void endTheGame(Bowl startOfLoop, int scorePlayer, int scoreOpponent) {
- if (isEmpty() == false && myOwner.hasTheTurn()) return;
-
- if (getMyOwner().equals(startOfLoop.getMyOwner())) {
- scorePlayer = scorePlayer + getMyRocks();
- } else scoreOpponent = scoreOpponent + getMyRocks();
+ protected void endTheGame(Bowl startOfLoop, int scorePlayer, int scoreOpponent) {
+ if (isEmpty() == false && getMyOwner().equals(startOfLoop.getMyOwner())) return;
if (this.equals(startOfLoop)) {
- int playerKalaha = getKalaha().getMyRocks();
+ int playerKalaha = getKalaha().getMyStones();
if (scorePlayer == playerKalaha) {
if (scorePlayer == scoreOpponent) getMyOwner().gotADraw();
else if (scorePlayer > scoreOpponent) getMyOwner().isTheWinner();
else getMyOwner().getOpponent().isTheWinner();
-
}
- } else getNextBowl().endTheGame(startOfLoop, scorePlayer, scoreOpponent);
+ } else {
+ if (getMyOwner().equals(startOfLoop.getMyOwner())) {
+ scorePlayer = scorePlayer + getMyStones();
+ } else scoreOpponent = scoreOpponent + getMyStones();
+
+ getNextBowl().endTheGame(startOfLoop, scorePlayer, scoreOpponent);
+ }
}
+
+ protected abstract String makeString(String playerBowls, String opponentBowls, String kalahas);
+
+ protected abstract int[] toStateArray(int[] stateArray, int index);
}
diff --git a/domain/src/main/java/mancala/domain/DomainSmallBowlException.java b/domain/src/main/java/mancala/domain/DomainSmallBowlException.java
new file mode 100644
index 0000000..56e5de1
--- /dev/null
+++ b/domain/src/main/java/mancala/domain/DomainSmallBowlException.java
@@ -0,0 +1,7 @@
+package mancala.domain;
+
+public class DomainSmallBowlException extends Exception {
+ public DomainSmallBowlException(String message) {
+ super(message);
+ }
+}
diff --git a/domain/src/main/java/mancala/domain/Kalaha.java b/domain/src/main/java/mancala/domain/Kalaha.java
index 9e70e6c..411a86d 100644
--- a/domain/src/main/java/mancala/domain/Kalaha.java
+++ b/domain/src/main/java/mancala/domain/Kalaha.java
@@ -1,23 +1,34 @@
package mancala.domain;
+import java.util.List;
+
class Kalaha extends Bowl {
- Kalaha(int boardSize, int bowlsToAdd, Bowl startBowl, Player playerOwningThisSide) {
+ Kalaha(int boardSize, int bowlsToAdd, List<Integer> stonesList, Bowl startBowl, Player playerOwningThisSide) {
bowlsToAdd = bowlsToAdd - 1;
- this.myRocks = 0;
+ this.myStones = stonesList.remove(0);
this.myOwner = playerOwningThisSide;
if (bowlsToAdd == 0) this.nextBowl = startBowl;
- else this.nextBowl = new SmallBowl(boardSize, bowlsToAdd, startBowl, playerOwningThisSide.getOpponent());
+ else this.nextBowl = new SmallBowl(boardSize, bowlsToAdd, stonesList, startBowl, playerOwningThisSide.getOpponent());
}
Kalaha getKalaha() {
return this;
}
- SmallBowl getSmallBowl() {
- return getNextBowl().getSmallBowl();
+ SmallBowl getNextSmallBowl() {
+ return getNextBowl().getNextSmallBowl();
+ }
+
+ @Override
+ SmallBowl goToFirstBowlOfPlayerWithTurn() {
+ if (getMyOwner().hasTheTurn()) {
+ return getNextBowl().getKalaha().getNextSmallBowl();
+ } else {
+ return getNextSmallBowl();
+ }
}
SmallBowl getOpposite(int countTillThis) {
@@ -29,10 +40,10 @@ class Kalaha extends Bowl {
}
void distribute(int remainingRocks) {
- myRocks++;
+ myStones++;
// Skip?
if (getMyOwner().hasTheTurn() == false) {
- myRocks--;
+ myStones--;
getNextBowl().distribute(remainingRocks);
} else if (remainingRocks == 1) {
endTheGame();
@@ -44,8 +55,34 @@ class Kalaha extends Bowl {
return true;
}
+ @Override
+ protected String makeString(String playerBowls, String opponentBowls, String kalahas) {
+ if (getMyOwner().equals(SmallBowl.referencePoint.getMyOwner().getOpponent())) {
+ return " " + opponentBowls + "\n" +
+ getMyStones() + "\t\t\t\t " + kalahas + "\n" +
+ " " + playerBowls;
+ }
+ else {
+ return getNextBowl().makeString(
+ playerBowls,
+ opponentBowls,
+ kalahas + getMyStones());
+ }
+ }
void claimStolenBooty(int booty) {
- myRocks = myRocks + booty;
+ myStones = myStones + booty;
}
+
+ @Override
+ protected int[] toStateArray(int[] stateArray, int index) {
+ stateArray[index] = getMyStones();
+ if (index == stateArray.length - 2) {
+ stateArray[stateArray.length - 1] = (getMyOwner().hasTheTurn() ? Mancala.PLAYER_TWO : Mancala.PLAYER_ONE);
+ return stateArray;
+ } else {
+ return getNextBowl().toStateArray(stateArray, ++index);
+ }
+ }
+
}
diff --git a/domain/src/main/java/mancala/domain/Mancala.java b/domain/src/main/java/mancala/domain/Mancala.java
new file mode 100644
index 0000000..d80e9e5
--- /dev/null
+++ b/domain/src/main/java/mancala/domain/Mancala.java
@@ -0,0 +1,55 @@
+package mancala.domain;
+
+public interface Mancala {
+ public static final int NO_PLAYERS = 0;
+ public static final int PLAYER_ONE = 1;
+ public static final int PLAYER_TWO = 2;
+ public static final int BOTH_PLAYERS = 3;
+
+ /**
+ * Method indicating if the first player has the next turn or not.
+ * If player 1 is not in turn, then player 2 is in turn.
+ * @param The player which you want to know the turn for.
+ * @return True if the first player has the next turn, false if it's the turn of the other player.
+ */
+ boolean isPlayersTurn(int player);
+
+ /**
+ * Method for playing the specified recess. Index is as specified below:
+ *
+ * 12 11 10 9 8 7
+ * 13 6
+ * 0 1 2 3 4 5
+ *
+ * @param index Index of the recess to be played.
+ * @return 15 item long Array with the current state of the game. The 15th item indicates which player has the next turn (possible values are 1 or 2).
+ */
+ int[] playPit(int index) throws MancalaException;
+
+ /**
+ * Method for returning the amount of stones in de specified pit. Index is as specified below:
+ *
+ * 12 11 10 9 8 7
+ * 13 6
+ * 0 1 2 3 4 5
+ *
+ * @param index Index of the pit.
+ * @return Amount of stone.
+ */
+ int getStonesForPit(int index);
+
+ /**
+ * Method for retrieving whether the game has ended or not.
+ *
+ * @return True is the game has ended otherwise False.
+ */
+ boolean isEndOfGame();
+
+ /**
+ * Method for retrieving the player that has won the game.
+ *
+ * @return Integer value representing which player(s) (if any) won the game.
+ */
+ int getWinner();
+
+}
diff --git a/domain/src/main/java/mancala/domain/MancalaException.java b/domain/src/main/java/mancala/domain/MancalaException.java
new file mode 100644
index 0000000..783b229
--- /dev/null
+++ b/domain/src/main/java/mancala/domain/MancalaException.java
@@ -0,0 +1,7 @@
+package mancala.domain;
+
+public class MancalaException extends Exception {
+ public MancalaException(String message) {
+ super(message);
+ }
+} \ No newline at end of file
diff --git a/domain/src/main/java/mancala/domain/MancalaImpl.java b/domain/src/main/java/mancala/domain/MancalaImpl.java
new file mode 100644
index 0000000..576eeb4
--- /dev/null
+++ b/domain/src/main/java/mancala/domain/MancalaImpl.java
@@ -0,0 +1,117 @@
+package mancala.domain;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+public class MancalaImpl implements Mancala {
+
+ public static final HashSet<Integer> PLAYER_ONE_PITS = new HashSet<>(
+ IntStream.rangeClosed(0, 5).boxed().collect(Collectors.toList())
+ );
+ public static final HashSet<Integer> PLAYER_TWO_PITS = new HashSet<>(
+ IntStream.rangeClosed(7, 12).boxed().collect(Collectors.toList())
+ );
+ public static final int PLAYER_ONE_KALAHA = 6;
+ public static final int PLAYER_TWO_KALAHA = 13;
+
+ private SmallBowl domainReference;
+
+ public MancalaImpl() {
+ try {
+ domainReference = new SmallBowl();
+ } catch (DomainSmallBowlException e) {
+ e.printStackTrace();
+ }
+ domainPlayer = domainReference.getMyOwner();
+ domainOpponent = domainPlayer.getOpponent();
+ }
+
+ public MancalaImpl(int[] stonesArray) {
+ try {
+ domainReference = new SmallBowl(
+ Arrays.stream(stonesArray)
+ .boxed().collect(Collectors.toList())
+ );
+ } catch (DomainSmallBowlException e) {
+ e.printStackTrace();
+ }
+ domainPlayer = domainReference.getMyOwner();
+ domainOpponent = domainPlayer.getOpponent();
+ }
+
+ @Override
+ public boolean isPlayersTurn(int player) {
+ switch (player) {
+ case Mancala.PLAYER_ONE:
+ return domainReference.getMyOwner().hasTheTurn();
+ case Mancala.PLAYER_TWO:
+ return domainReference.getMyOwner().getOpponent().hasTheTurn();
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public int[] playPit(int index) throws MancalaException {
+ if (isPlayersTurn(Mancala.PLAYER_ONE) && MancalaImpl.PLAYER_TWO_PITS.contains(index)) {
+ throw new MancalaException("Player one cannot play player two's pits.");
+ }
+ if (isPlayersTurn(Mancala.PLAYER_TWO) && MancalaImpl.PLAYER_ONE_PITS.contains(index)) {
+ throw new MancalaException("Player two cannot play player one's pits.");
+ }
+ if (index == MancalaImpl.PLAYER_ONE_KALAHA || index == MancalaImpl.PLAYER_TWO_KALAHA) {
+ throw new MancalaException("A kalaha can never be played!");
+ }
+ if (getStonesForPit(index) == 0) {
+ throw new MancalaException("The pit was empty when played!");
+ }
+
+ if (isPlayersTurn(Mancala.PLAYER_ONE)) {
+ domainReference.getNextSmallBowlTimes(index).play();
+ } else {
+ int skipKalahaIndex = index - 1;
+ domainReference.getNextSmallBowlTimes(skipKalahaIndex).play();
+ }
+
+ return domainReference.toStateArray(new int[15], 0);
+ }
+
+ @Override
+ public int getStonesForPit(int index) {
+ if (MancalaImpl.PLAYER_ONE_PITS.contains(index)) {
+ return domainReference.getNextSmallBowlTimes(index).getMyStones();
+ }
+ else if (MancalaImpl.PLAYER_TWO_PITS.contains(index)) {
+ return domainReference.getNextSmallBowlTimes(--index).getMyStones();
+ }
+ else if (index == MancalaImpl.PLAYER_ONE_KALAHA) {
+ return domainReference.getKalaha().getMyStones();
+ }
+ else if (index == MancalaImpl.PLAYER_TWO_KALAHA) {
+ return domainReference.getKalaha().getNextBowl().getKalaha().getMyStones();
+ }
+ else
+ return -1;
+ }
+
+ private final mancala.domain.Player domainPlayer;
+ private final mancala.domain.Player domainOpponent;
+
+ @Override
+ public boolean isEndOfGame() {
+ return domainPlayer.won() || domainOpponent.won();
+ }
+
+ @Override
+ public int getWinner() {
+ if (!isEndOfGame()) return Mancala.NO_PLAYERS;
+
+ if (domainPlayer.won() && domainOpponent.won()) return Mancala.BOTH_PLAYERS;
+ else if (domainPlayer.won()) return Mancala.PLAYER_ONE;
+ else if (domainOpponent.won()) return Mancala.PLAYER_TWO;
+ else return Mancala.NO_PLAYERS;
+ }
+
+}
diff --git a/domain/src/main/java/mancala/domain/SmallBowl.java b/domain/src/main/java/mancala/domain/SmallBowl.java
index 5c97d72..b62ef43 100644
--- a/domain/src/main/java/mancala/domain/SmallBowl.java
+++ b/domain/src/main/java/mancala/domain/SmallBowl.java
@@ -1,45 +1,53 @@
package mancala.domain;
-public class SmallBowl extends Bowl {
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
- public SmallBowl() {
- this.myRocks = 4;
- this.myOwner = new Player();
+public class SmallBowl extends Bowl {
- int boardSize = 14;
- int bowlsToAdd = boardSize - 1;
+ public static SmallBowl referencePoint;
- this.nextBowl = new SmallBowl(boardSize, bowlsToAdd, this, this.getMyOwner());
+ public SmallBowl() throws DomainSmallBowlException {
+ this(Arrays.stream(new int[] {4,4,4,4,4,4,0,4,4,4,4,4,4,0}).boxed().collect(Collectors.toList()));
+ referencePoint = this;
}
- public SmallBowl(int boardSize) {
- try {
- if (boardSize < 4) {
- throw new Exception("Can't have a board smaller than four bowls.");
- }
- } catch (Exception e) {
- e.printStackTrace();
+ public SmallBowl(List<Integer> stonesList) throws DomainSmallBowlException {
+ if (stonesList.size() % 2 != 0) {
+ throw new DomainSmallBowlException("Stones List should contain even number of elements.");
+ }
+ if (stonesList.size() < 4) {
+ throw new DomainSmallBowlException("Stones list should have length greater than or equal to 4.");
}
- this.myRocks = 4;
this.myOwner = new Player();
+
+ int boardSize = stonesList.size();
int bowlsToAdd = boardSize - 1;
- this.nextBowl = new SmallBowl(boardSize, bowlsToAdd, this, this.getMyOwner());
+
+ this.myStones = stonesList.remove(0);
+
+ if (boardSize == 4) this.nextBowl = new Kalaha(boardSize, bowlsToAdd, stonesList, this, this.getMyOwner());
+ else this.nextBowl = new SmallBowl(boardSize, bowlsToAdd, stonesList, this, this.getMyOwner());
+
+ referencePoint = this;
}
- SmallBowl(int boardSize, int bowlsToAdd, Bowl startBowl, Player playerOwningThisSide) {
+ SmallBowl(int boardSize, int bowlsToAdd, List<Integer> stonesList, Bowl startBowl, Player playerOwningThisSide) {
bowlsToAdd = bowlsToAdd - 1;
this.myOwner = playerOwningThisSide;
- this.myRocks = 4;
+ this.myStones = stonesList.remove(0);
if (bowlsToAdd == 0) nextBowl = startBowl;
- else if (bowlsToAdd == (boardSize / 2) + 1) nextBowl = new Kalaha(boardSize, bowlsToAdd, startBowl, playerOwningThisSide);
+ else if (bowlsToAdd == (boardSize / 2) + 1) nextBowl = new Kalaha(boardSize, bowlsToAdd, stonesList, startBowl, playerOwningThisSide);
- else if (bowlsToAdd == 1) nextBowl = new Kalaha(boardSize, bowlsToAdd, startBowl, playerOwningThisSide);
+ else if (bowlsToAdd == 1) nextBowl = new Kalaha(boardSize, bowlsToAdd, stonesList, startBowl, playerOwningThisSide);
- else nextBowl = new SmallBowl(boardSize, bowlsToAdd, startBowl, playerOwningThisSide);
+ else nextBowl = new SmallBowl(boardSize, bowlsToAdd, stonesList, startBowl, playerOwningThisSide);
}
+
public SmallBowl getNextSmallBowlTimes(int remainingTimes) {
if (remainingTimes == 0)
return this;
@@ -52,18 +60,18 @@ public class SmallBowl extends Bowl {
if (myOwner.hasTheTurn() == false) return;
if (isEmpty()) return;
- int passThese = myRocks;
- myRocks = 0;
+ int passThese = myStones;
+ myStones = 0;
getNextBowl().distribute(passThese);
}
@Override
boolean isEmpty() {
- return this.myRocks == 0;
+ return this.myStones == 0;
}
void distribute(int remainingRocks) {
- this.myRocks++;
+ this.myStones++;
// last?
if (remainingRocks == 1)
lastSmallBowl();
@@ -76,29 +84,42 @@ public class SmallBowl extends Bowl {
// Did play end in smallbowl of my player? steal, otherwise do nothing
if (getMyOwner().hasTheTurn()) stealTheBooty(false);
+ endTheGame();
+
getMyOwner().switchTurn();
endTheGame();
}
- SmallBowl getSmallBowl() {
+ SmallBowl getNextSmallBowl() {
return this;
}
+ @Override
+ SmallBowl goToFirstBowlOfPlayerWithTurn() {
+ if (getMyOwner().hasTheTurn()) {
+ return getKalaha().getNextBowl().getKalaha().getNextSmallBowl();
+ } else {
+ return getKalaha().getNextSmallBowl();
+ }
+ }
+
Kalaha getKalaha() {
return getNextBowl().getKalaha();
}
private void stealTheBooty(boolean victim) {
if (victim){
- getOpposite().getKalaha().claimStolenBooty(myRocks);
- myRocks = 0;
+ System.out.println("help! i'm being robbed, my precious " + getMyStones() + " stones are gone :(.");
+ getOpposite().getKalaha().claimStolenBooty(myStones);
+ myStones = 0;
- } else if (getMyRocks() == 1 &&
- getOpposite().getMyRocks() != 0) {
+ } else if (getMyStones() == 1 &&
+ getOpposite().getMyStones() != 0) {
+ System.out.println("stealing");
- getKalaha().claimStolenBooty(myRocks);
- myRocks = 0;
+ getKalaha().claimStolenBooty(myStones);
+ myStones = 0;
getOpposite().stealTheBooty(true);
}
}
@@ -111,4 +132,32 @@ public class SmallBowl extends Bowl {
count = count + 1;
return getNextBowl().getOpposite(count);
}
+
+ public String stateString() {
+ return SmallBowl.referencePoint.makeString("", "", "");
+ }
+
+ protected String makeString(String playerBowls, String opponentBowls, String kalahas) {
+ if (!this.getMyOwner().equals(SmallBowl.referencePoint.getMyOwner())) {
+ return getNextBowl().makeString(
+ playerBowls,
+ (getMyStones() + ", ") + opponentBowls,
+ kalahas);
+ } else {
+ return getNextBowl().makeString(
+ playerBowls + (playerBowls.equals("") ? getMyStones() : ", " + getMyStones()),
+ opponentBowls,
+ kalahas);
+ }
+ }
+
+ @Override
+ protected int[] toStateArray(int[] stateArray, int index) {
+ stateArray[index] = getMyStones();
+ if (index == stateArray.length - 2) {
+ return stateArray;
+ } else {
+ return getNextBowl().toStateArray(stateArray, ++index);
+ }
+ }
}
diff --git a/domain/src/test/java/mancala/domain/BowlTest.java b/domain/src/test/java/mancala/domain/BowlTest.java
index 530f628..e2eedb9 100644
--- a/domain/src/test/java/mancala/domain/BowlTest.java
+++ b/domain/src/test/java/mancala/domain/BowlTest.java
@@ -2,323 +2,315 @@ package mancala.domain;
import org.junit.jupiter.api.*;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
import static org.junit.jupiter.api.Assertions.*;
+@IndicativeSentencesGeneration(separator = " -> ", generator = DisplayNameGenerator.ReplaceUnderscores.class)
class BowlTest {
- protected void traverseAndCheckBoard(Bowl currentBowl, int position) {
- Bowl initialBowl = currentBowl;
- int traversedCount = 0;
- int currentPosition = 0;
- for (int i = 0; i < 14; i++) {
- if ((position + traversedCount) > 14) {
- // if looping around the board, position = ((start+traversed) - total)
- // in other words the amount of bowls that the absolute position is greater than the board's total bowls
- //
- // Only relevant to check construction btw, also only checking in the case where there are 14 bowls
- currentPosition = ((traversedCount + position) - 14);
- } else
- // Or just use normal position
- currentPosition = position + traversedCount;
-
- // check for kalaha's, and check for smallbowl otherwise
- if (currentPosition == 7 || currentPosition == 14)
- assertEquals(currentBowl.getClass(), Kalaha.class);
- else
- assertEquals(currentBowl.getClass(), SmallBowl.class);
-
- currentBowl = currentBowl.getNextBowl();
- assertNotNull(currentBowl);
- traversedCount++;
- }
- assertSame(initialBowl, currentBowl);
- }
@Nested
- @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
- class For_a_normal_mancala_bowl{
- SmallBowl firstSmallBowlPlayer;
-
- @BeforeEach
- public void makeASmallBowlInMancala() {
- firstSmallBowlPlayer = new SmallBowl();
- traverseAndCheckBoard(firstSmallBowlPlayer, 1);
- }
+ class instantiatingDefaultGame {
- @Nested
- class GIVEN_its_the_start_of_the_game {
- @Test
- public void WHEN_before_any_small_bowls_are_played_THEN_has_four_rocks() {
- Bowl current = firstSmallBowlPlayer;
- for (int i = 0; i < 14; i++) {
- current = current.getNextBowl();
- if (current.getClass() == SmallBowl.class)
- assertEquals(current.getMyRocks(), 4);
+ private void checkIfDefaultState(Bowl currentBowl, int position) {
+ Bowl initialBowl = currentBowl;
+ int traversedCount = 0;
+ int currentPosition = 0;
+ for (int i = 0; i < 14; i++) {
+ if ((position + traversedCount) > 14) {
+ // if looping around the board, position = ((start+traversed) - total)
+ // in other words the amount of bowls that the absolute position is greater than the board's total bowls
+ //
+ // Only relevant to check construction btw, also only checking in the case where there are 14 bowls
+ currentPosition = ((traversedCount + position) - 14);
+ } else
+ // Or just use normal position
+ currentPosition = position + traversedCount;
+
+ // check for kalaha's, and check for smallbowl otherwise
+ if (currentPosition == 7 || currentPosition == 14) {
+ assertEquals(currentBowl.getClass(), Kalaha.class);
+ assertEquals(0, currentBowl.getMyStones(),
+ "In a 'normal' game the kalaha should have 0 rocks when created.");
+ } else {
+ assertEquals(currentBowl.getClass(), SmallBowl.class);
+ assertEquals(4, currentBowl.getMyStones(),
+ "In a 'normal' game the smallbowl should have 4 rocks when created.");
}
- assertSame(current, firstSmallBowlPlayer);
+
+ currentBowl = currentBowl.getNextBowl();
+ assertNotNull(currentBowl);
+ traversedCount++;
}
+ assertSame(initialBowl, currentBowl);
+ }
- @Test
- public void WHEN_chosen_by_the_player_that_has_the_turn_THEN_distribute_its_rocks_anti_clockwise() {
- int initialRocks = firstSmallBowlPlayer.getMyRocks();
- firstSmallBowlPlayer.play();
- Bowl neighbour = firstSmallBowlPlayer.getNextBowl();
- for (int i = 0; i < initialRocks; i++) {
- assertEquals(5, neighbour.getMyRocks());
- neighbour = neighbour.getNextBowl();
- }
- assertEquals(4, neighbour.getMyRocks());
+ SmallBowl referenceSmallBowl;
+
+ {
+ try {
+ referenceSmallBowl = new SmallBowl();
+ } catch (DomainSmallBowlException e) {
+ e.printStackTrace();
}
}
+ @Test
+ public void default_stones_amount_check() {
+ checkIfDefaultState(referenceSmallBowl, 1);
+ }
+
@Nested
- class GIVEN_the_game_is_in_a_state_where {
+ class given_a_small_bowl {
+
+ @Nested
+ class and_its_the_start_of_the_game {
+ @Test
+ public void when_getMyStones_is_called_then_it_returns_four() {
+ SmallBowl next = referenceSmallBowl.getNextSmallBowl();
+ while (!next.equals(referenceSmallBowl)) {
+ assertEquals(4, next.getMyStones());
+ next = next.getNextSmallBowl();
+ }
+ }
- @Test
- public void its_not_the_players_turn_WHEN_played_by_the_player_THEN_nothing_happens() {
- firstSmallBowlPlayer.getMyOwner().switchTurn();
- int initialRocks = firstSmallBowlPlayer.getMyRocks();
- firstSmallBowlPlayer.play();
- Bowl neighbour = firstSmallBowlPlayer.getNextBowl();
- for (int i = 0; i < initialRocks; i++) {
- assertEquals(4, neighbour.getMyRocks());
- neighbour = neighbour.getNextBowl();
+ @Test
+ public void when_play_is_called_and_owner_has_turn_then_distribute_its_rocks_anti_clockwise() {
+ int initialRocks = referenceSmallBowl.getMyStones();
+ referenceSmallBowl.play();
+ Bowl neighbour = referenceSmallBowl.getNextBowl();
+ for (int i = 0; i < initialRocks; i++) {
+ assertEquals(5, neighbour.getMyStones());
+ neighbour = neighbour.getNextBowl();
+ }
+ assertEquals(4, neighbour.getMyStones());
}
- assertEquals(4, neighbour.getMyRocks());
}
+ }
- @Test
- public void play_can_reach_opponents_kalaha_WHEN_played_by_the_player_THEN_opponents_kalaha_is_skipped() {
- SmallBowl playWillSkipFromThisBowl = goToSkippableState();
- int opponentKalahaRocksBefore = firstSmallBowlPlayer.getNextSmallBowlTimes(11).getNextBowl().getMyRocks();
- playWillSkipFromThisBowl.play();
- int opponentKalahaRocksAfter = firstSmallBowlPlayer.getNextSmallBowlTimes(11).getNextBowl().getMyRocks();
- assertEquals(opponentKalahaRocksBefore, opponentKalahaRocksAfter);
- }
+ @Nested
+ class given_a_kalaha {
+
+ Kalaha playerKalaha = referenceSmallBowl.getKalaha();
+ Kalaha opponentKalaha = referenceSmallBowl.getKalaha().getNextSmallBowl().getKalaha();
@Test
- public void the_bowl_is_empty_WHEN_the_player_plays_the_empty_bowl_THEN_nothing_happens() {
- firstSmallBowlPlayer.play();
- firstSmallBowlPlayer.getMyOwner().switchTurn();
- assertTrue(firstSmallBowlPlayer.getMyOwner().hasTheTurn());
- firstSmallBowlPlayer.play();
- assertTrue(firstSmallBowlPlayer.getMyOwner().hasTheTurn());
- assertEquals(5, firstSmallBowlPlayer.getNextBowl().getMyRocks());
+ public void when_getMyStones_is_called_after_instantiating_then_has_zero_stones() {
+ assertEquals(0, playerKalaha.getMyStones());
+ assertEquals(0, opponentKalaha.getMyStones());
}
+ }
- @Test
- public void all_small_bowls_of_the_player_are_empty_WHEN_a_play_ends_THEN_tell_players_who_won() {
- Player player = firstSmallBowlPlayer.getMyOwner();
- Player opponent = firstSmallBowlPlayer.getNextSmallBowlTimes(6).getMyOwner();
- assertFalse(player.won());
- assertFalse(opponent.won());
- goToEndOfSillyGame();
- assertTrue(player.won());
- assertFalse(opponent.won());
+ }
- }
- @Test
- public void all_small_bowls_of_the_player_are_empty_WHEN_a_play_ends_THEN_tell_players_who_wonOPPONENTVARIATION() {
- Player player = firstSmallBowlPlayer.getMyOwner();
- Player opponent = firstSmallBowlPlayer.getNextSmallBowlTimes(6).getMyOwner();
- goToEndOfGameWhereOpponentWins();
- assertFalse(player.won());
- assertTrue(opponent.won());
- }
+ @Nested
+ class instantiatingGameWithStonesList {
+ SmallBowl referenceSmallBowl;
- @Test
- public void the_play_would_skip_past_opponent_kalaha_at_the_last_rock_and_steal_WHEN_played_THEN_should_skip_and_steal_correctly() {
- goToSkipAndStealOnLast();
- SmallBowl firstSmallBowlOpponent = firstSmallBowlPlayer.getNextSmallBowlTimes(6);
- assertEquals(3, firstSmallBowlPlayer.getNextSmallBowlTimes(5).getNextBowl().getMyRocks());
- firstSmallBowlOpponent.getNextSmallBowlTimes(3).play();
- assertEquals(19, firstSmallBowlOpponent.getNextSmallBowlTimes(5).getNextBowl().getMyRocks());
+ @Test
+ void given_a_stones_list_when_instantiating_a_small_bowl_then_configure_stones_as_in_list() {
+ int[] stonesArray = new int[] {1,2,3,4,5,6,7,8,9,10,11,12,13,14};
+ List<Integer> stonesList = Arrays.stream(stonesArray).boxed().collect(Collectors.toList());
+ try {
+ referenceSmallBowl = new SmallBowl(stonesList);
+ } catch (DomainSmallBowlException e) {
+ fail("Invalid instantiation.");
}
-
- private void goToSkipAndStealOnLast() {
- SmallBowl firstSmallBowlOpponent = firstSmallBowlPlayer.getNextSmallBowlTimes(6);
- firstSmallBowlPlayer.getNextSmallBowlTimes(1).play();
- firstSmallBowlOpponent.getNextSmallBowlTimes(2).play();
- firstSmallBowlOpponent.getNextSmallBowlTimes(5).play();
- firstSmallBowlPlayer.getNextSmallBowlTimes(1).play();
- firstSmallBowlOpponent.getNextSmallBowlTimes(1).play();
- firstSmallBowlPlayer.getNextSmallBowlTimes(2).play();
- firstSmallBowlOpponent.play();
- firstSmallBowlPlayer.getNextSmallBowlTimes(3).play();
- firstSmallBowlOpponent.getNextSmallBowlTimes(1).play();
- firstSmallBowlPlayer.getNextSmallBowlTimes(4).play();
- firstSmallBowlOpponent.play();
- // Cheating here, let player go again >:), i'm too dumb too make a loop/skip and steal play happen in fair game
- firstSmallBowlOpponent.getMyOwner().switchTurn();
- // Should skip and steal
- // this bowls rocks
- assertEquals(10, firstSmallBowlOpponent.getNextSmallBowlTimes(3).getMyRocks());
- // End up here by looping around the board, thus skipping
- assertEquals(0, firstSmallBowlOpponent.getMyRocks());
- // Thus steal from last bowl on players side
- assertEquals(8, firstSmallBowlPlayer.getNextSmallBowlTimes(5).getMyRocks());
- // Result is big kalaha booty
- assertEquals(8, firstSmallBowlOpponent.getNextSmallBowlTimes(5).getNextBowl().getMyRocks());
+ for (int i = 0; i < stonesArray.length; i++) {
+ if (i < 6) assertEquals(stonesArray[i], referenceSmallBowl.getNextSmallBowlTimes(i).getMyStones());
+ else if (i == 6) assertEquals(stonesArray[i], referenceSmallBowl.getKalaha().getMyStones());
+ else if (i == 13) assertEquals(stonesArray[i], referenceSmallBowl.getKalaha().getNextBowl().getKalaha().getMyStones());
+ else {
+ int index = i - 1;
+ assertEquals(stonesArray[i], referenceSmallBowl.getNextSmallBowlTimes(index).getMyStones());
+ }
}
+ }
- private void goToEndOfGameWhereOpponentWins() {
- goToSkipAndStealOnLast();
- SmallBowl firstSmallBowlOpponent = firstSmallBowlPlayer.getNextSmallBowlTimes(6);
- firstSmallBowlOpponent.getNextSmallBowlTimes(3).play();
- firstSmallBowlPlayer.getNextSmallBowlTimes(1).play();
- firstSmallBowlOpponent.getNextSmallBowlTimes(1).play();
- firstSmallBowlPlayer.play();
- firstSmallBowlPlayer.getMyOwner().switchTurn();
- firstSmallBowlPlayer.getNextSmallBowlTimes(3).play();
- firstSmallBowlPlayer.getMyOwner().switchTurn();
- firstSmallBowlPlayer.getNextSmallBowlTimes(4).play();
- firstSmallBowlPlayer.getNextSmallBowlTimes(5).play();
+ @Test
+ void given_a_stones_list_with_odd_number_of_elements_when_instantiating_small_bowl_then_throw_DomainSmallBowlException() {
+ int[] stonesArray = new int[] {1,2,3,4,5,6,7,8,9,10,11,12,13};
+ List<Integer> stonesList = Arrays.stream(stonesArray).boxed().collect(Collectors.toList());
+ try {
+ referenceSmallBowl = new SmallBowl(stonesList);
+ fail();
+ } catch (DomainSmallBowlException e) {
}
+ }
- private void goToEndOfSillyGame() {
- SmallBowl firstSmallBowlOpponent = firstSmallBowlPlayer.getNextSmallBowlTimes(6);
-
- // player
- // Best opening
- firstSmallBowlPlayer.getNextSmallBowlTimes(2).play();
- // Set up for steal move
- firstSmallBowlPlayer.getNextSmallBowlTimes(4).play();
- assertEquals(2, firstSmallBowlPlayer.getKalaha().getMyRocks());
-
- // opponent
- // ... worst opening?
- firstSmallBowlOpponent.play();
-
- // player
- assertSame(firstSmallBowlPlayer.getNextSmallBowlTimes(4).getOpposite(), firstSmallBowlPlayer.getKalaha().getNextBowl().getNextBowl());
- firstSmallBowlPlayer.play();
- // Check if i did it properly on paper
- assertEquals(9, firstSmallBowlPlayer.getKalaha().getMyRocks());
- assertEquals(0, firstSmallBowlPlayer.getNextSmallBowlTimes(4).getMyRocks());
- // assertEquals(0, firstSmallBowlPlayer.getNextSmallBowlTimes(4).getOpposite().getMyRocks());
-
- // opponent
- firstSmallBowlOpponent.getNextSmallBowlTimes(3).play();
-
- //Player
- firstSmallBowlPlayer.getNextSmallBowlTimes(3).play();
- assertEquals(10, firstSmallBowlPlayer.getNextSmallBowlTimes(5).getNextBowl().getMyRocks());
-
- // opponent makes stupid move again
- firstSmallBowlOpponent.getNextSmallBowlTimes(1).play();
-
- // player makes big steal
- //assertEquals(0, firstSmallBowlPlayer.getNextSmallBowlTimes(5).getNextBowl().getMyRocks());
- assertEquals(10, firstSmallBowlPlayer.getNextSmallBowlTimes(5).getNextBowl().getMyRocks());
- firstSmallBowlPlayer.getNextSmallBowlTimes(2).play();
- assertEquals(19, firstSmallBowlPlayer.getNextSmallBowlTimes(5).getNextBowl().getMyRocks());
-
- // opponent steals tiny booty
- firstSmallBowlOpponent.play();
- assertEquals(3, firstSmallBowlOpponent.getNextSmallBowlTimes(5).getNextBowl().getMyRocks());
+ @Test
+ void given_a_stones_list_with_less_than_four_elements_when_instantiating_small_bowl_then_throw_DomainSmallBowlException() {
+ int[] stonesArray = new int[] {1,2};
+ List<Integer> stonesList = Arrays.stream(stonesArray).boxed().collect(Collectors.toList());
+ try {
+ referenceSmallBowl = new SmallBowl(stonesList);
+ fail("No exception when stones list is too small");
+ } catch (DomainSmallBowlException e) {
+ }
+ stonesArray = new int[] {1,2,3,4};
+ stonesList = Arrays.stream(stonesArray).boxed().collect(Collectors.toList());
+ try {
+ referenceSmallBowl = new SmallBowl(stonesList);
+ } catch (DomainSmallBowlException e) {
+ fail("Should work fine");
+ }
+ }
- // player is stalling until the end
- firstSmallBowlPlayer.play();
+ void setupGameSituationAndFailIfInvalid(int[] stonesArray) {
+ try {
+ referenceSmallBowl = new SmallBowl(
+ Arrays.stream(
+ stonesArray
+ ).boxed().collect(Collectors.toList())
+ );
+ } catch (DomainSmallBowlException e) {
+ fail("Invalid instantiation.");
+ }
+ }
- // opponent is heading for disaster
- firstSmallBowlOpponent.getNextSmallBowlTimes(5).play();
- firstSmallBowlPlayer.play();
- firstSmallBowlOpponent.getNextSmallBowlTimes(4).play();
- firstSmallBowlPlayer.play();
- firstSmallBowlOpponent.getNextSmallBowlTimes(5).play();
- // everything empty!
- for (int i = 0; i < 6; i++) {
- assertEquals(0, firstSmallBowlOpponent.getNextSmallBowlTimes(i).getMyRocks());
+ @Nested
+ class playBehaviour {
+
+ {
+ // setup default game in this sub class
+ // by default
+ try {
+ referenceSmallBowl = new SmallBowl();
+ } catch (DomainSmallBowlException e) {
+ e.printStackTrace();
}
-
}
- private SmallBowl goToSkippableState() {
- SmallBowl firstSmallBowlOpponent = firstSmallBowlPlayer.getNextSmallBowlTimes(6);
-
- firstSmallBowlPlayer.getNextSmallBowlTimes(2).play();
- firstSmallBowlPlayer.getNextSmallBowlTimes(3).play();
-
- firstSmallBowlOpponent.getNextSmallBowlTimes(2).play();
- firstSmallBowlOpponent.getNextSmallBowlTimes(3).play();
-
- firstSmallBowlPlayer.play();
- firstSmallBowlOpponent.play();
+ @Test
+ void given_stones_can_reach_oppenent_kalaha_when_played_validly_then_opponents_kalaha_is_skipped() {
+ setupGameSituationAndFailIfInvalid(new int[] {0,0,0,0,0,100,0,0,0,0,0,0,0,0});
+ referenceSmallBowl.getNextSmallBowlTimes(5).play();
+ assertEquals(0, referenceSmallBowl.getKalaha().getNextBowl().getKalaha().getMyStones());
+ }
- firstSmallBowlPlayer.getNextSmallBowlTimes(4).play();
- firstSmallBowlOpponent.getNextSmallBowlTimes(4).play();
+ @Test
+ void given_its_not_the_players_turn_when_play_is_called_then_nothing_happens() {
+ referenceSmallBowl.getMyOwner().switchTurn();
+ int initialRocks = referenceSmallBowl.getMyStones();
+ referenceSmallBowl.play();
+ Bowl neighbour = referenceSmallBowl.getNextBowl();
+ for (int i = 0; i < initialRocks; i++) {
+ assertEquals(4, neighbour.getMyStones());
+ neighbour = neighbour.getNextBowl();
+ }
+ assertEquals(4, neighbour.getMyStones());
+ }
- // Playing this bowl should give a skip!
- assertTrue(firstSmallBowlPlayer.getNextSmallBowlTimes(5).getMyRocks() >= 8);
- return firstSmallBowlPlayer.getNextSmallBowlTimes(5);
+ @Test
+ void given_the_bowl_is_empty_when_play_called_on_the_bowl_then_nothing_happens() {
+ referenceSmallBowl.play();
+ referenceSmallBowl.getMyOwner().switchTurn();
+ assertTrue(referenceSmallBowl.getMyOwner().hasTheTurn());
+ referenceSmallBowl.play();
+ assertTrue(referenceSmallBowl.getMyOwner().hasTheTurn());
+ assertEquals(5, referenceSmallBowl.getNextBowl().getMyStones());
}
- }
- @Nested
- class GIVEN_the_play_ends{
+ @Test
+ void given_stones_would_skip_opponent_kalaha_at_the_last_rock_and_steal_when_played_then_should_skip_and_steal_correctly() {
+ setupGameSituationAndFailIfInvalid(new int[] {13,0,0,0,0,0,
+ 0,
+ 0,0,0,0,0,8,
+ 0});
+ System.out.println(referenceSmallBowl.getMyStones());
+ System.out.println(referenceSmallBowl.stateString());
+ referenceSmallBowl.play();
+ System.out.println(referenceSmallBowl.stateString());
+
+ assertEquals(11, referenceSmallBowl.getKalaha().getMyStones(),
+ "resulting kalaha stones after stealing should be 11.");
+ assertEquals(0, referenceSmallBowl.getMyStones(),
+ "played bowl should be zero, since steal happened");
+ assertEquals(0, referenceSmallBowl.getNextSmallBowlTimes(12).getMyStones());
+ }
@Test
- public void in_own_kalaha_WHEN_play_ends_THEN_turn_is_not_switched() {
- firstSmallBowlPlayer.getNextSmallBowlTimes(2).play();
- assertTrue(firstSmallBowlPlayer.getMyOwner().hasTheTurn());
+ void given_that_play_ends_in_own_kalaha_when_play_is_called_validly_then_turn_is_not_switched() {
+ referenceSmallBowl.getNextSmallBowlTimes(2).play();
+ assertTrue(referenceSmallBowl.getMyOwner().hasTheTurn());
}
@Test
- public void in_own_small_bowl_WHEN_play_ends_THEN_turn_is_switched() {
- firstSmallBowlPlayer.play();
- assertFalse(firstSmallBowlPlayer.getMyOwner().hasTheTurn());
+ void given_that_play_ends_in_own_small_bowl_when_play_is_called_validly_then_turn_is_switched() {
+ referenceSmallBowl.play();
+ assertFalse(referenceSmallBowl.getMyOwner().hasTheTurn());
}
@Test
- public void in_opponents_small_bowl_WHEN_player_plays_this_bowl_THEN_turn_is_switched() {
- firstSmallBowlPlayer.getNextSmallBowlTimes(5).play();
- assertFalse(firstSmallBowlPlayer.getMyOwner().hasTheTurn());
+ void given_that_play_ends_in_opponents_small_bowl_when_play_is_called_validly_then_turn_is_switched() {
+ referenceSmallBowl.getNextSmallBowlTimes(5).play();
+ assertFalse(referenceSmallBowl.getMyOwner().hasTheTurn());
}
@Test
- public void in_own_empty_small_bowl_and_opposite_has_rocks_WHEN_play_ends_THEN_rocks_of_opposite_plus_last_rock_of_play_are_added_to_kalaha() {
- firstSmallBowlPlayer.getNextSmallBowlTimes(5).play();
- SmallBowl firstSmallBowlOpponent = firstSmallBowlPlayer.getNextSmallBowlTimes(6);
+ void given_that_play_ends_in_own_empty_small_bowl_and_opposite_has_rocks_when_play_is_called_validly_then_rocks_of_opposite_plus_last_rock_of_play_are_added_to_next_kalaha() {
+ System.out.println(referenceSmallBowl.stateString());
+ referenceSmallBowl.getNextSmallBowlTimes(5).play();
+ System.out.println(referenceSmallBowl.stateString());
+ SmallBowl firstSmallBowlOpponent = referenceSmallBowl.getNextSmallBowlTimes(6);
firstSmallBowlOpponent.getNextSmallBowlTimes(5).play();
- assertSame(firstSmallBowlPlayer.getNextSmallBowlTimes(1).getOpposite(), firstSmallBowlPlayer.getKalaha().getSmallBowl().getNextSmallBowlTimes(4));
- // assertSame(firstSmallBowlPlayer.getOpposite(), firstSmallBowlPlayer.getKalaha().getNextSmallBowlTimes(5));
- firstSmallBowlPlayer.play();
- assertEquals(7, firstSmallBowlPlayer.getNextSmallBowlTimes(5).getNextBowl().getMyRocks());
+ System.out.println(referenceSmallBowl.stateString());
+ referenceSmallBowl.play();
+ System.out.println(referenceSmallBowl.stateString());
+ assertEquals(7, referenceSmallBowl.getKalaha().getMyStones());
+ assertEquals(0, referenceSmallBowl.getNextSmallBowlTimes(5).getMyStones());
+ assertEquals(0, referenceSmallBowl.getKalaha().getNextBowl().getMyStones());
}
-
}
+ @Nested
+ class endGameBehaviour {
- }
-
- @Nested
- @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
- class a_kalaha {
-
- SmallBowl smallBowl;
- Kalaha kalaha;
-
- @BeforeEach
- public void makeKalahaInBoard() {
- smallBowl = new SmallBowl();
- kalaha = smallBowl.getNextSmallBowlTimes(6).getKalaha();
- }
+ @Test
+ void given_all_small_bowls_of_the_player_that_did_the_turn_are_empty_when_a_play_ends_then_tell_players_who_won() {
+ setupGameSituationAndFailIfInvalid(new int[] {0,0,0,0,0,1,0,4,4,4,4,4,4,0});
+ Player player = referenceSmallBowl.getMyOwner();
+ Player opponent = referenceSmallBowl.getNextSmallBowlTimes(6).getMyOwner();
+ assertFalse(player.won(), "players haven't won at start of game");
+ assertFalse(opponent.won(), "players haven't won at start of game");
+ referenceSmallBowl.getNextSmallBowlTimes(5).play();
+ assertFalse(player.won(), "player should lose here.");
+ assertTrue(opponent.won(), "opponent should win here.");
+
+ setupGameSituationAndFailIfInvalid(new int[] {4,4,4,4,4,4,0,0,0,0,0,0,1,0});
+ player = referenceSmallBowl.getMyOwner();
+ opponent = referenceSmallBowl.getNextSmallBowlTimes(6).getMyOwner();
+ assertFalse(player.won(), "players haven't won at start of game");
+ assertFalse(opponent.won(), "players haven't won at start of game");
+ player.switchTurn();
+ referenceSmallBowl.getNextSmallBowlTimes(6 + 5).play();
+ assertTrue(player.won(), "player should win here.");
+ assertFalse(opponent.won(), "opponent should lose here.");
+ }
- @Test
- public void exists_in_a_mancala_board() {
- traverseAndCheckBoard(kalaha, 14);
- }
+ @Test
+ void given_all_small_bowls_of_the_player_are_empty_and_score_is_tied_when_a_play_ends_then_tell_both_player_they_won() {
+ setupGameSituationAndFailIfInvalid(new int[] {0,0,0,0,0,1,0,0,0,0,0,0,1,0});
+ System.out.println(referenceSmallBowl.stateString());
+ referenceSmallBowl.getNextSmallBowlTimes(5).play();
+ System.out.println(referenceSmallBowl.stateString());
+ assertTrue(referenceSmallBowl.getMyOwner().won() && referenceSmallBowl.getMyOwner().getOpponent().won());
+ }
- @Test
- public void has_zero_rocks_when_created() {
- Bowl current = kalaha;
- for (int i = 0; i < 14; i++) {
- current = current.getNextBowl();
- if (current.getClass() == Kalaha.class)
- assertEquals(current.getMyRocks(), 0);
+ @Test
+ void given_that_the_opponents_board_is_emptied_by_stealing_when_player_made_a_play_then_tell_players_who_won() {
+ setupGameSituationAndFailIfInvalid(new int[] {1,0,0,0,1,0,0,1,0,0,0,0,0,0});
+ System.out.println(referenceSmallBowl.stateString());
+ referenceSmallBowl.getNextSmallBowlTimes(4).play();
+ System.out.println(referenceSmallBowl.stateString());
+ assertTrue(referenceSmallBowl.getMyOwner().won() || referenceSmallBowl.getMyOwner().getOpponent().won());
}
+
}
}
} \ No newline at end of file
diff --git a/domain/src/test/java/mancala/domain/MancalaImplTest.java b/domain/src/test/java/mancala/domain/MancalaImplTest.java
new file mode 100644
index 0000000..61409ac
--- /dev/null
+++ b/domain/src/test/java/mancala/domain/MancalaImplTest.java
@@ -0,0 +1,291 @@
+package mancala.domain;
+
+import org.junit.jupiter.api.*;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@IndicativeSentencesGeneration(separator = " -> ", generator = DisplayNameGenerator.ReplaceUnderscores.class)
+class MancalaImplTest {
+
+ Mancala mancala;
+
+ @BeforeEach
+ void setUp() {
+ mancala = new MancalaImpl();
+ }
+
+ /**
+ * Method indicating if the first player has the next turn or not.
+ * If player 1 is not in turn, then player 2 is in turn.
+ *
+ * @param The player which you want to know the turn for.
+ * @return True if the first player has the next turn, false if it's the turn of the other player.
+ */
+ @Nested
+ class isPlayersTurn {
+ @Test
+ void given_mancala_PLAYER_ONE_when_first_player_has_next_turn_then_return_true() {
+ assertTrue(mancala.isPlayersTurn(Mancala.PLAYER_ONE));
+ }
+
+ @Test
+ void given_mancala_PLAYER_ONE_when_second_player_has_next_turn_then_return_false() {
+ playPitAndFailIfNotValid(0);
+ assertFalse(mancala.isPlayersTurn(Mancala.PLAYER_ONE));
+ }
+
+
+ @Test
+ void given_mancala_PLAYER_TWO_when_second_player_has_next_turn_then_return_true() {
+ playPitAndFailIfNotValid(0);
+ assertTrue(mancala.isPlayersTurn(Mancala.PLAYER_TWO));
+ }
+
+ @Test
+ void given_mancala_PLAYER_TWO_when_second_player_has_turn_then_return_false() {
+ assertFalse(mancala.isPlayersTurn(Mancala.PLAYER_TWO));
+ }
+ }
+
+ /**
+ * Method for playing the specified recess. Index is as specified below:
+ *
+ * 12 11 10 9 8 7
+ * 13 6
+ * 0 1 2 3 4 5
+ *
+ * @param index Index of the recess to be played.
+ * @return 15 item long Array with the current state of the game. The 15th item indicates which player has the next turn (possible values are 1 or 2).
+ */
+ @Nested
+ class playPit {
+ @Test
+ void given_a_pit_index_from_PLAYER_one_choice_when_pit_doesnt_belong_to_player_one_then_throw_MancalaException() {
+ for (int index: MancalaImpl.PLAYER_TWO_PITS) {
+ playPitAndFailIfNoException(index, "Player one could play a pit that was not his without an exception!");
+ }
+ }
+
+ @Test
+ void given_a_pit_index_from_PLAYER_two_choice_when_pit_doesnt_belong_to_player_two_then_throw_MancalaException() {
+ assumeTurn(Mancala.PLAYER_ONE);
+ playPitAndFailIfNotValid(0);
+
+ assumeTurn(Mancala.PLAYER_TWO);
+ for (int index: MancalaImpl.PLAYER_ONE_PITS) {
+ playPitAndFailIfNoException(index, "Player two could play a pit that was not his without an exception!");
+ }
+ }
+
+ @Test
+ void given_a_Kalaha_index_when_playPit_is_called_then_always_throw_MancalaException() {
+ assumeTurn(Mancala.PLAYER_ONE);
+ playPitAndFailIfNoException(MancalaImpl.PLAYER_ONE_KALAHA, "Kalaha of player one was played without throwing exception!");
+ playPitAndFailIfNoException(MancalaImpl.PLAYER_TWO_KALAHA, "Kalaha of player two was played without throwing exception!");
+
+ playPitAndFailIfNotValid(0);
+
+ assumeTurn(Mancala.PLAYER_TWO);
+ playPitAndFailIfNoException(MancalaImpl.PLAYER_ONE_KALAHA, "Kalaha of player one was played without throwing exception!");
+ playPitAndFailIfNoException(MancalaImpl.PLAYER_TWO_KALAHA, "Kalaha of player two was played without throwing exception!");
+ }
+
+ @Test
+ void given_that_valid_play_is_made_when_play_is_done_then_players_switch_turns() {
+ assumeTurn(Mancala.PLAYER_ONE);
+ playPitAndFailIfNotValid(0);
+
+ assumeNotTurn(Mancala.PLAYER_ONE);
+ assumeTurn(Mancala.PLAYER_TWO);
+ }
+
+ @Test
+ void given_that_pit_has_no_stones_when_play_is_made_by_player_one_then_throw_MancalaException() {
+ assumeTurn(Mancala.PLAYER_ONE);
+ playPitAndFailIfNotValid(0);
+
+ assumeTurn(Mancala.PLAYER_TWO);
+ playPitAndFailIfNotValid(7);
+
+ assumeTurn(Mancala.PLAYER_ONE);
+ playPitAndFailIfNoException(0, "Didn't throw exception when Pit was empty when played!");
+ }
+
+ @Test
+ void given_that_pit_has_no_stones_when_play_is_made_by_player_two_then_throw_MancalaException() {
+ assumeTurn(Mancala.PLAYER_ONE);
+ playPitAndFailIfNotValid(5);
+
+ assumeTurn(Mancala.PLAYER_TWO);
+ playPitAndFailIfNotValid(7);
+
+ assumeTurn(Mancala.PLAYER_ONE);
+ playPitAndFailIfNotValid(0);
+
+ assumeTurn(Mancala.PLAYER_TWO);
+ playPitAndFailIfNoException(7, "Didn't throw exception when Pit was empty when played!");
+ }
+
+ @Test
+ void given_that_pit_has_stones_and_player_has_turn_when_playPit_is_called_then_return_array_representing_state() {
+ mancala = new MancalaImpl(new int[] {1,0,0,0,0,0,0,1,0,0,0,0,0,0});
+ assumeTurn(Mancala.PLAYER_ONE);
+ int[] stateArray = playPitAndFailIfNotValid(0);
+ assertEquals(15, stateArray.length,
+ "length of the state array should be 15.");
+ assertTrue(Arrays.equals(new int[] {0,1,0,0,0,0,0,1,0,0,0,0,0,0,2}, stateArray));
+
+ stateArray = playPitAndFailIfNotValid(7);
+ assertEquals(15, stateArray.length,
+ "length of the state array should be 15.");
+ assertTrue(Arrays.equals(new int[] {0,1,0,0,0,0,0,0,1,0,0,0,0,0,1}, stateArray));
+ }
+
+ }
+
+ /**
+ * Method for returning the amount of stones in de specified pit. Index is as specified below:
+ *
+ * 12 11 10 9 8 7
+ * 13 6
+ * 0 1 2 3 4 5
+ *
+ * @param index Index of the pit.
+ * @return Amount of stone.
+ */
+ @Nested
+ class getStonesForPit {
+ @Test
+ void given_any_Pit_index_when_getStonesForPit_is_called_then_return_stones_of_pits() {
+ HashSet<Integer> allPitIndexes = new HashSet<>(MancalaImpl.PLAYER_ONE_PITS);
+ allPitIndexes.addAll(MancalaImpl.PLAYER_TWO_PITS);
+
+ for (int pitIndex: allPitIndexes) {
+ assertEquals(4, mancala.getStonesForPit(pitIndex),
+ "pit should have four stones when created in the domain model.");
+ }
+ }
+
+ @Test
+ void given_any_Kalaha_index_when_getStonesForPit_is_called_then_return_stones_of_Kalaha() {
+ HashSet<Integer> allKalahaIndexes = new HashSet<>();
+ allKalahaIndexes.add(MancalaImpl.PLAYER_ONE_KALAHA);
+ allKalahaIndexes.add(MancalaImpl.PLAYER_TWO_KALAHA);
+ for (int kalahaIndex: allKalahaIndexes) {
+ assertEquals(0, mancala.getStonesForPit(kalahaIndex),
+ "Kalaha should have zero stones when created in the domain model.");
+ }
+ }
+
+ @Test
+ void given_that_a_play_has_been_made_and_not_looped_around_board_when_getting_stones_then_should_give_zero() {
+ assumeTurn(Mancala.PLAYER_ONE);
+ playPitAndFailIfNotValid(5);
+
+ assertEquals(0, mancala.getStonesForPit(5),
+ "In this situation play should leave zero rocks!");
+
+ assumeTurn(Mancala.PLAYER_TWO);
+ playPitAndFailIfNotValid(7);
+
+ assertEquals(0, mancala.getStonesForPit(7),
+ "In this situation play should leave zero rocks!");
+ }
+
+ }
+
+ /**
+ * Method for retrieving whether the game has ended or not.
+ *
+ * @return True is the game has ended otherwise False.
+ */
+ @Nested
+ class isEndOfGame {
+ @Test
+ void given_the_game_has_not_ended_when_isEndOfGame_is_called_then_return_false() {
+ assertFalse(mancala.isEndOfGame());
+ }
+
+ @Test
+ void given_the_game_has_ended_when_isEndOfGame_is_called_then_return_true() {
+ mancala = new MancalaImpl(new int[] {0,0,0,0,0,1,0,0,0,0,0,0,0,0});
+ playPitAndFailIfNotValid(5);
+ assertTrue(mancala.isEndOfGame());
+ }
+
+
+ }
+
+ /**
+ * Method for retrieving the player that has won the game.
+ *
+ * @return Integer value representing which player(s) (if any) won the game.
+ */
+ @Nested
+ class getWinner {
+ @Test
+ void given_the_game_has_not_ended_when_getWinner_is_called_then_immediately_return_Mancala_NO_PLAYERS() {
+ assertEquals(Mancala.NO_PLAYERS, mancala.getWinner());
+ }
+
+ @Test
+ void given_PLAYER_ONE_has_won_in_the_domain_model_when_getWinner_is_called_then_return_Mancala_PLAYER_ONE() {
+ mancala = new MancalaImpl(new int[] {0,0,0,0,0,1,0,0,0,0,0,0,0,0});
+ playPitAndFailIfNotValid(5);
+ assertEquals(Mancala.PLAYER_ONE, mancala.getWinner());
+ }
+
+ @Test
+ void given_PLAYER_TWO_has_won_in_the_domain_model_when_getWinner_is_called_then_return_Mancala_PLAYER_TWO() {
+ mancala = new MancalaImpl(new int[] {0,1,0,0,0,0,0,0,0,0,0,2,0,0});
+ playPitAndFailIfNotValid(1);
+ playPitAndFailIfNotValid(7 + 4);
+ playPitAndFailIfNotValid(7 + 5);
+ assertEquals(Mancala.PLAYER_TWO, mancala.getWinner(),
+ "PLAYER TWO should win here.");
+ }
+
+ @Test
+ void given_BOTH_PLAYER_have_won_in_the_domain_model_when_getWinner_is_called_then_return_Mancala_BOTH_PLAYERS() {
+ mancala = new MancalaImpl(new int[] {0,0,0,0,0,1,0,0,0,0,0,0,1,0});
+ playPitAndFailIfNotValid(5);
+ assertEquals(Mancala.BOTH_PLAYERS, mancala.getWinner(),
+ "PLAYER TWO should win here.");
+ }
+
+ }
+
+ void assumeTurn(int player) {
+ assertTrue(mancala.isPlayersTurn(player),
+ "It's not PLAYER " + (player == 1 ? "ONE's" : "TWO's") + " turn!");
+ }
+
+ void assumeNotTurn(int player) {
+ assertFalse(mancala.isPlayersTurn(player),
+ "It's PLAYER " + (player == 1 ? "ONE's" : "TWO's") + " turn!");
+ }
+
+ int[] playPitAndFailIfNotValid(int index) {
+ try {
+ return mancala.playPit(index);
+ } catch (MancalaException e) {
+ fail("Invalid play.");
+ return new int[0];
+ }
+ }
+
+ void playPitAndFailIfNoException(int index, String message) {
+ try {
+ mancala.playPit(index);
+ fail(message);
+ } catch (MancalaException e) {
+ }
+ }
+
+ void notImplementedYet() {
+ fail("Not implemented yet.");
+ }
+} \ No newline at end of file