Add files via upload

This commit is contained in:
fassband
2021-11-19 08:32:32 +01:00
committed by GitHub Enterprise
parent e9a9181cd0
commit f2fe06f720
19 changed files with 8166 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
package ch.zhaw.catan;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
/***
* TODO Write your own tests in this class.
*
* Note: Have a look at {@link ch.zhaw.catan.games.ThreePlayerStandard}. It can be used
* to get several different game states.
*
*/
public class SiedlerGameTest {
@Test
public void dummyTestMethod() {
assertTrue(false);
}
}
@@ -0,0 +1,258 @@
package ch.zhaw.catan;
import ch.zhaw.catan.games.ThreePlayerStandard;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import java.awt.*;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.*;
/**
* This class contains some basic tests for the {@link SiedlerGame} class
* <p></p>
* <p>DO NOT MODIFY THIS CLASS</p>
*
* @author tebe
*/
public class SiedlerGameTestBasic {
private final static int DEFAULT_WINPOINTS = 5;
private final static int DEFAULT_NUMBER_OF_PLAYERS = 3;
/**
* Tests whether the functionality for switching to the next/previous player
* works as expected for different numbers of players.
*
* @param numberOfPlayers the number of players
*/
@ParameterizedTest
@ValueSource(ints = {2, 3, 4})
public void requirementPlayerSwitching(int numberOfPlayers) {
SiedlerGame model = new SiedlerGame(DEFAULT_WINPOINTS, numberOfPlayers);
assertTrue(numberOfPlayers == model.getPlayerFactions().size(),
"Wrong number of players returned by getPlayers()");
//Switching forward
for (int i = 0; i < numberOfPlayers; i++) {
assertEquals(Config.Faction.values()[i], model.getCurrentPlayerFaction(),
"Player order does not match order of Faction.values()");
model.switchToNextPlayer();
}
assertEquals(Config.Faction.values()[0], model.getCurrentPlayerFaction(),
"Player wrap-around from last player to first player did not work.");
//Switching backward
for (int i = numberOfPlayers - 1; i >= 0; i--) {
model.switchToPreviousPlayer();
assertEquals(Config.Faction.values()[i], model.getCurrentPlayerFaction(),
"Switching players in reverse order does not work as expected.");
}
}
/**
* Tests whether the game board meets the required layout/land placement.
*/
@Test
public void requirementLandPlacementTest() {
SiedlerGame model = new SiedlerGame(DEFAULT_WINPOINTS, DEFAULT_NUMBER_OF_PLAYERS);
assertTrue(Config.getStandardLandPlacement().size() == model.getBoard().getFields().size(),
"Check if explicit init must be done (violates spec): "
+ "modify initializeSiedlerGame accordingly.");
for (Map.Entry<Point, Config.Land> e : Config.getStandardLandPlacement().entrySet()) {
assertEquals(e.getValue(), model.getBoard().getField(e.getKey()),
"Land placement does not match default placement.");
}
}
/**
* Tests whether the {@link ThreePlayerStandard#getAfterSetupPhase(int)}} game board is not empty (returns
* an object) at positions where settlements and roads have been placed.
*/
@Test
public void requirementSettlementAndRoadPositionsOccupiedThreePlayerStandard() {
SiedlerGame model = ThreePlayerStandard.getAfterSetupPhase(DEFAULT_WINPOINTS);
assertEquals(DEFAULT_NUMBER_OF_PLAYERS, model.getPlayerFactions().size());
for (Config.Faction f : model.getPlayerFactions()) {
assertTrue(model.getBoard().getCorner(ThreePlayerStandard.INITIAL_SETTLEMENT_POSITIONS.get(f).first) != null);
assertTrue(model.getBoard().getCorner(ThreePlayerStandard.INITIAL_SETTLEMENT_POSITIONS.get(f).second) != null);
assertTrue(model.getBoard().getEdge(ThreePlayerStandard.INITIAL_SETTLEMENT_POSITIONS.get(f).first, ThreePlayerStandard.INITIAL_ROAD_ENDPOINTS.get(f).first) != null);
assertTrue(model.getBoard().getEdge(ThreePlayerStandard.INITIAL_SETTLEMENT_POSITIONS.get(f).second, ThreePlayerStandard.INITIAL_ROAD_ENDPOINTS.get(f).second) != null);
}
}
/**
* Checks that the resource card payout for different dice values matches
* the expected payout for the game state {@link ThreePlayerStandard#getAfterSetupPhase(int)}}.
*
* Note, that for the test to work, the {@link Map} returned by {@link SiedlerGame#throwDice(int)}
* must contain a {@link List} with resource cards (empty {@link List}, if the player gets none)
* for each of the players.
*
* @param diceValue the dice value
*/
@ParameterizedTest
@ValueSource(ints = {2, 3, 4, 5, 6, 8, 9, 10, 11, 12})
public void requirementDiceThrowResourcePayoutThreePlayerStandardTest(int diceValue) {
SiedlerGame model = ThreePlayerStandard.getAfterSetupPhase(DEFAULT_WINPOINTS);
Map<Config.Faction, List<Config.Resource>> expectd = ThreePlayerStandard.INITIAL_DICE_THROW_PAYOUT.get(diceValue);
Map<Config.Faction, List<Config.Resource>> actual = model.throwDice(diceValue);
assertEquals(ThreePlayerStandard.INITIAL_DICE_THROW_PAYOUT.get(diceValue), model.throwDice(diceValue));
}
/**
* Tests whether the resource card stock of the players matches the expected stock
* for the game state {@link ThreePlayerStandard#getAfterSetupPhase(int)}}.
*/
@Test
public void requirementPlayerResourceCardStockAfterSetupPhase() {
SiedlerGame model = ThreePlayerStandard.getAfterSetupPhase(DEFAULT_WINPOINTS);
assertPlayerResourceCardStockEquals(model, ThreePlayerStandard.INITIAL_PLAYER_CARD_STOCK);
}
/**
* Tests whether the resource card stock of the players matches the expected stock
* for the game state {@link ThreePlayerStandard#getAfterSetupPhaseAlmostEmptyBank(int)}}.
*/
@Test
public void requirementPlayerResourceCardStockAfterSetupPhaseAlmostEmptyBank() {
SiedlerGame model = ThreePlayerStandard.getAfterSetupPhaseAlmostEmptyBank(DEFAULT_WINPOINTS);
assertPlayerResourceCardStockEquals(model, ThreePlayerStandard.BANK_ALMOST_EMPTY_RESOURCE_CARD_STOCK);
}
/**
* Tests whether the resource card stock of the players matches the expected stock
* for the game state {@link ThreePlayerStandard#getAfterSetupPhaseAlmostEmptyBank(int)}}.
*/
@Test
public void requirementPlayerResourceCardStockPlayerOneReadyToBuildFifthSettlement() {
SiedlerGame model = ThreePlayerStandard.getPlayerOneReadyToBuildFifthSettlement(DEFAULT_WINPOINTS);
assertPlayerResourceCardStockEquals(model, ThreePlayerStandard.PLAYER_ONE_READY_TO_BUILD_FIFTH_SETTLEMENT_RESOURCE_CARD_STOCK);
}
/**
* Throws each dice value except 7 once and tests whether the resource
* card stock of the players matches the expected stock.
*/
@Test
public void requirementDiceThrowPlayerResourceCardStockUpdateTest() {
SiedlerGame model = ThreePlayerStandard.getAfterSetupPhase(DEFAULT_WINPOINTS);
for(int i : List.of(2, 3, 4, 5, 6, 8, 9, 10, 11, 12)) {
model.throwDice(i);
}
Map<Config.Faction, Map<Config.Resource, Integer>> expected = Map.of(
Config.Faction.values()[0], Map.of(Config.Resource.GRAIN, 1, Config.Resource.WOOL, 2,
Config.Resource.BRICK, 2, Config.Resource.ORE, 1, Config.Resource.LUMBER, 1),
Config.Faction.values()[1],
Map.of(Config.Resource.GRAIN, 1, Config.Resource.WOOL, 5, Config.Resource.BRICK, 0,
Config.Resource.ORE, 0, Config.Resource.LUMBER, 0),
Config.Faction.values()[2],
Map.of(Config.Resource.GRAIN, 0, Config.Resource.WOOL, 0, Config.Resource.BRICK, 2,
Config.Resource.ORE, 0, Config.Resource.LUMBER, 1));
assertPlayerResourceCardStockEquals(model, expected);
}
private void assertPlayerResourceCardStockEquals(SiedlerGame model, Map<Config.Faction, Map<Config.Resource, Integer>> expected) {
for (int i = 0; i < expected.keySet().size(); i++) {
Config.Faction f = model.getCurrentPlayerFaction();
for (Config.Resource r : Config.Resource.values()) {
assertEquals(expected.get(f).get(r), model.getCurrentPlayerResourceStock(r),
"Resource card stock of player " + i + " [faction " + f + "] for resource type " + r + " does not match.");
}
model.switchToNextPlayer();
}
}
/**
* Tests whether player one can build two roads starting in game state
* {@link ThreePlayerStandard#getAfterSetupPhaseAlmostEmptyBank(int)}.
*/
@Test
public void requirementBuildRoad() {
SiedlerGame model = ThreePlayerStandard.getAfterSetupPhaseAlmostEmptyBank(DEFAULT_WINPOINTS);
assertTrue(model.buildRoad(new Point(6, 6), new Point(6, 4)));
assertTrue(model.buildRoad(new Point(6, 4), new Point(7, 3)));
}
/**
* Tests whether player one can build a road and a settlement starting in game state
* {@link ThreePlayerStandard#getAfterSetupPhaseAlmostEmptyBank(int)}.
*/
@Test
public void requirementBuildSettlement() {
SiedlerGame model = ThreePlayerStandard.getAfterSetupPhaseAlmostEmptyBank(DEFAULT_WINPOINTS);
assertTrue(model.buildRoad(new Point(9, 15), new Point(9, 13)));
assertTrue(model.buildSettlement(new Point(9, 13)));
}
/**
* Tests whether payout with multiple settlements of the same player at one field works
* {@link ThreePlayerStandard#getAfterSetupPhaseAlmostEmptyBank(int)}.
*/
@Test
public void requirementTwoSettlementsSamePlayerSameFieldResourceCardPayout() {
SiedlerGame model = ThreePlayerStandard.getAfterSetupPhase(DEFAULT_WINPOINTS);
for(int diceValue : List.of(2, 6, 6, 11)){
model.throwDice(diceValue);
}
assertTrue(model.buildRoad(new Point(6, 6), new Point(7, 7)));
assertTrue(model.buildSettlement(new Point(7, 7)));
assertEquals(List.of(Config.Resource.ORE, Config.Resource.ORE), model.throwDice(4).get(model.getCurrentPlayerFaction()));
}
/**
* Tests whether player one can build a city starting in game state
* {@link ThreePlayerStandard#getAfterSetupPhaseAlmostEmptyBank(int)}.
*/
@Test
public void requirementBuildCity() {
SiedlerGame model = ThreePlayerStandard.getAfterSetupPhaseAlmostEmptyBank(DEFAULT_WINPOINTS);
assertTrue(model.buildCity(new Point(10, 16)));
}
/**
* Tests whether player two can trade in resources with the bank and has the
* correct number of resource cards afterwards. The test starts from game state
* {@link ThreePlayerStandard#getAfterSetupPhaseAlmostEmptyBank(int)}.
*/
@Test
public void requirementCanTradeFourToOneWithBank() {
SiedlerGame model = ThreePlayerStandard.getAfterSetupPhaseAlmostEmptyBank(DEFAULT_WINPOINTS);
model.switchToNextPlayer();
Map<Config.Resource, Integer> expectedResourceCards = ThreePlayerStandard.BANK_ALMOST_EMPTY_RESOURCE_CARD_STOCK.get(model.getCurrentPlayerFaction());
assertEquals(expectedResourceCards.get(Config.Resource.WOOL), model.getCurrentPlayerResourceStock(Config.Resource.WOOL));
assertEquals(expectedResourceCards.get(Config.Resource.LUMBER), model.getCurrentPlayerResourceStock(Config.Resource.LUMBER));
model.tradeWithBankFourToOne(Config.Resource.WOOL, Config.Resource.LUMBER);
int cardsOffered = 4;
int cardsReceived = 1;
assertEquals(expectedResourceCards.get(Config.Resource.WOOL)-cardsOffered, model.getCurrentPlayerResourceStock(Config.Resource.WOOL));
assertEquals(expectedResourceCards.get(Config.Resource.LUMBER)+cardsReceived, model.getCurrentPlayerResourceStock(Config.Resource.LUMBER));
}
/***
* This test is not actually a test and should be removed. However,
* we leave it in for you to have a quick and easy way to look at the
* game board produced by {@link ThreePlayerStandard#getAfterSetupPhase(int)},
* augmented by annotations, which you won't need since we do not ask for
* more advanced trading functionality using harbours.
*/
@Disabled
@Test
public void print(){
SiedlerGame model = ThreePlayerStandard.getAfterSetupPhase(DEFAULT_WINPOINTS);
model.getBoard().addFieldAnnotation(new Point(6, 8),new Point(6, 6), "N ");
model.getBoard().addFieldAnnotation(new Point(6, 8),new Point(5, 7), "NE");
model.getBoard().addFieldAnnotation(new Point(6, 8),new Point(5, 9), "SE");
model.getBoard().addFieldAnnotation(new Point(6, 8),new Point(6, 10), "S ");
model.getBoard().addFieldAnnotation(new Point(6, 8),new Point(7, 7), "NW");
model.getBoard().addFieldAnnotation(new Point(6, 8),new Point(7, 9), "SW");
System.out.println(new SiedlerBoardTextView(model.getBoard()).toString());
}
}
+42
View File
@@ -0,0 +1,42 @@
package ch.zhaw.catan;
public class Tuple<X, Y> {
public final X first;
public final Y second;
public Tuple(X x, Y y) {
this.first = x;
this.second = y;
}
@Override
public String toString() {
return "(" + first + "," + second + ")";
}
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
if (!(other instanceof Tuple)) {
return false;
}
@SuppressWarnings("unchecked")
Tuple<X, Y> otherCasted = (Tuple<X, Y>) other;
// null is not a valid value for first and second tuple element
return otherCasted.first.equals(this.first) && otherCasted.second.equals(this.second);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((first == null) ? 0 : first.hashCode());
result = prime * result + ((second == null) ? 0 : second.hashCode());
return result;
}
}
@@ -0,0 +1,480 @@
package ch.zhaw.catan.games;
import ch.zhaw.catan.Config;
import ch.zhaw.catan.Config.Resource;
import ch.zhaw.catan.Tuple;
import ch.zhaw.catan.SiedlerGame;
import java.awt.*;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* This class can be used to prepare some predefined siedler game situations and, for some
* of the situations, it provides information about the expected game state,
* for example the number of resource cards in each player's stock or the expected resource
* card payout when the dices are thrown (for each dice value).
* <br>
* The basic game situations upon which all other situations that can be retrieved are based is
* the following:
* <pre>
* ( ) ( ) ( ) ( )
* // \\ // \\ // \\ // \\
* ( ) ( ) ( ) ( ) ( )
* || ~~ || ~~ || ~~ || ~~ ||
* || || || || ||
* ( ) ( ) ( ) ( ) ( )
* // \\ // \\ // \\ // \\ // \\
* ( ) ( ) ( ) (bb) ( ) ( )
* || ~~ || LU || WL bb WL || ~~ ||
* || || 06 || 03 bb 08 || ||
* ( ) ( ) ( ) ( ) ( ) ( )
* // \\ // \\ rr \\ // \\ // \\ // \\
* ( ) ( ) (rr) ( ) ( ) ( ) ( )
* || ~~ || GR || OR || GR || LU || ~~ ||
* || || 02 || 04 || 05 || 10 || ||
* ( ) ( ) ( ) ( ) ( ) ( ) ( )
* // \\ // \\ // \\ // \\ // \\ // \\ // \\
* ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( )
* || ~~ gg LU || BR || -- || OR || GR || ~~ ||
* || gg 05 || 09 || 07 || 06 || 09 || ||
* ( ) (gg) ( ) ( ) ( ) ( ) ( ) ( )
* \\ // \\ // \\ // \\ // \\ // \\ bb \\ //
* ( ) ( ) ( ) ( ) ( ) (bb) ( )
* || ~~ || GR || OR || LU || WL || ~~ ||
* || || 10 || 11 || 03 || 12 || ||
* ( ) ( ) ( ) ( ) ( ) ( ) ( )
* \\ // \\ // \\ // \\ // rr // \\ //
* ( ) ( ) ( ) ( ) (rr) ( )
* || ~~ || WL || BR || BR || ~~ ||
* || || 08 || 04 || 11 || ||
* ( ) ( ) ( ) ( ) ( ) ( )
* \\ // \\ // \\ gg \\ // \\ //
* ( ) ( ) (gg) ( ) ( )
* || ~~ || ~~ || ~~ || ~~ ||
* || || || || ||
* ( ) ( ) ( ) ( ) ( )
* \\ // \\ // \\ // \\ //
* ( ) ( ) ( ) ( )
* </pre>
* Resource cards after the setup phase:
* <ul>
* <li>Player 1: WOOL BRICK</li>
* <li>Player 2: WOOL WOOL</li>
* <li>Player 3: BRICK</li>
* </ul>
* <p>The main ideas for this setup were the following:</p>
* <ul>
* <li>Player one has access to all resource types from the start so that any resource card can be acquired by
* throwing the corresponding dice value.</li>
* <li>The settlements are positioned in a way that for each dice value, there is only one resource card paid
* to one player, except for the dice values 4 and 12.</li>
* <li>There is a settlement next to water and the owner has access to resource types required to build roads</li>
* <li>The initial resource card stock of each player does not allow to build anything without getting
* additional resources first</li>
* </ul>
*
* @author tebe
*/
public class ThreePlayerStandard {
public final static int NUMBER_OF_PLAYERS = 3;
public static final Map<Config.Faction, Tuple<Point, Point>> INITIAL_SETTLEMENT_POSITIONS =
Map.of( Config.Faction.values()[0], new Tuple<>(new Point(5, 7), new Point(10, 16)),
Config.Faction.values()[1], new Tuple<>(new Point(11, 13), new Point(8, 4)),
Config.Faction.values()[2], new Tuple<>(new Point(2, 12), new Point(7, 19)));
public static final Map<Config.Faction, Tuple<Point, Point>> INITIAL_ROAD_ENDPOINTS = Map.of(Config.Faction.values()[0],
new Tuple<>(new Point(6, 6), new Point(9, 15)), Config.Faction.values()[1],
new Tuple<>(new Point(12, 12), new Point(8, 6)), Config.Faction.values()[2],
new Tuple<>(new Point(2, 10), new Point(8, 18)));
public static final Map<Config.Faction, Map<Config.Resource, Integer>> INITIAL_PLAYER_CARD_STOCK = Map.of(
Config.Faction.values()[0], Map.of(Config.Resource.GRAIN, 0, Config.Resource.WOOL, 1,
Config.Resource.BRICK, 1, Config.Resource.ORE, 0, Config.Resource.LUMBER, 0),
Config.Faction.values()[1],
Map.of(Config.Resource.GRAIN, 0, Config.Resource.WOOL, 2, Config.Resource.BRICK, 0,
Config.Resource.ORE, 0, Config.Resource.LUMBER, 0),
Config.Faction.values()[2],
Map.of(Config.Resource.GRAIN, 0, Config.Resource.WOOL, 0, Config.Resource.BRICK, 1,
Config.Resource.ORE, 0, Config.Resource.LUMBER, 0));
public static final Map<Config.Faction, Map<Config.Resource, Integer>> BANK_ALMOST_EMPTY_RESOURCE_CARD_STOCK = Map.of(
Config.Faction.values()[0], Map.of(Config.Resource.GRAIN, 8, Config.Resource.WOOL, 9,
Config.Resource.BRICK, 9, Config.Resource.ORE, 7, Config.Resource.LUMBER, 9),
Config.Faction.values()[1],
Map.of(Config.Resource.GRAIN, 8, Config.Resource.WOOL, 10, Config.Resource.BRICK, 0,
Config.Resource.ORE, 0, Config.Resource.LUMBER, 0),
Config.Faction.values()[2],
Map.of(Config.Resource.GRAIN, 0, Config.Resource.WOOL, 0, Config.Resource.BRICK, 8,
Config.Resource.ORE, 0, Config.Resource.LUMBER, 9));
public static final Map<Config.Faction, Map<Config.Resource, Integer>> PLAYER_ONE_READY_TO_BUILD_FIFTH_SETTLEMENT_RESOURCE_CARD_STOCK = Map.of(
Config.Faction.values()[0], Map.of(Config.Resource.GRAIN, 2, Config.Resource.WOOL, 2,
Config.Resource.BRICK, 3, Config.Resource.ORE, 0, Config.Resource.LUMBER, 3),
Config.Faction.values()[1],
Map.of(Config.Resource.GRAIN, 0, Config.Resource.WOOL, 5, Config.Resource.BRICK, 0,
Config.Resource.ORE, 0, Config.Resource.LUMBER, 0),
Config.Faction.values()[2],
Map.of(Config.Resource.GRAIN, 0, Config.Resource.WOOL, 0, Config.Resource.BRICK, 1,
Config.Resource.ORE, 0, Config.Resource.LUMBER, 0));
public static final Map<Integer, Map<Config.Faction, List<Resource>>> INITIAL_DICE_THROW_PAYOUT = Map.of(
2, Map.of(
Config.Faction.values()[0], List.of(Resource.GRAIN),
Config.Faction.values()[1], List.of(),
Config.Faction.values()[2], List.of()),
3, Map.of(
Config.Faction.values()[0], List.of(),
Config.Faction.values()[1], List.of(Resource.WOOL),
Config.Faction.values()[2], List.of()),
4, Map.of(
Config.Faction.values()[0], List.of(Resource.ORE),
Config.Faction.values()[1], List.of(),
Config.Faction.values()[2], List.of(Resource.BRICK)),
5, Map.of(
Config.Faction.values()[0], List.of(),
Config.Faction.values()[1], List.of(),
Config.Faction.values()[2], List.of(Resource.LUMBER)),
6, Map.of(
Config.Faction.values()[0], List.of(Resource.LUMBER),
Config.Faction.values()[1], List.of(),
Config.Faction.values()[2], List.of()),
8, Map.of(
Config.Faction.values()[0], List.of(),
Config.Faction.values()[1], List.of(Resource.WOOL),
Config.Faction.values()[2], List.of()),
9, Map.of(
Config.Faction.values()[0], List.of(),
Config.Faction.values()[1], List.of(Resource.GRAIN),
Config.Faction.values()[2], List.of()),
10, Map.of(
Config.Faction.values()[0], List.of(),
Config.Faction.values()[1], List.of(),
Config.Faction.values()[2], List.of()),
11, Map.of(
Config.Faction.values()[0], List.of(Resource.BRICK),
Config.Faction.values()[1], List.of(),
Config.Faction.values()[2], List.of()),
12, Map.of(
Config.Faction.values()[0], List.of(Resource.WOOL),
Config.Faction.values()[1], List.of(Resource.WOOL),
Config.Faction.values()[2], List.of()));
public static final Map<Resource, Integer> RESOURCE_CARDS_IN_BANK_AFTER_STARTUP_PHASE = Map.of(Resource.LUMBER, 19,
Resource.BRICK, 17, Resource.WOOL, 16, Resource.GRAIN, 19, Resource.ORE, 19);
public static final Point PLAYER_ONE_READY_TO_BUILD_FIFTH_SETTLEMENT_FIFTH_SETTLEMENT_POSITION = new Point(9, 13);
public static final List<Point> playerOneReadyToBuildFifthSettlementAllSettlementPositions =
List.of(INITIAL_SETTLEMENT_POSITIONS.get(Config.Faction.values()[0]).first,
INITIAL_SETTLEMENT_POSITIONS.get(Config.Faction.values()[0]).second,
new Point(7, 7),new Point(6, 4), PLAYER_ONE_READY_TO_BUILD_FIFTH_SETTLEMENT_FIFTH_SETTLEMENT_POSITION);
/**
* Returns a siedler game after the setup phase in the setup
* and with the initial resource card setup as described
* in {@link ThreePlayerStandard}.
*
* @param winpoints the number of points required to win the game
* @return the siedler game
*/
public static SiedlerGame getAfterSetupPhase(int winpoints) {
SiedlerGame model = new SiedlerGame(winpoints, NUMBER_OF_PLAYERS);
for (int i = 0; i < model.getPlayerFactions().size(); i++) {
Config.Faction f = model.getCurrentPlayerFaction();
assertTrue(model.placeInitialSettlement(INITIAL_SETTLEMENT_POSITIONS.get(f).first, false));
assertTrue(model.placeInitialRoad(INITIAL_SETTLEMENT_POSITIONS.get(f).first, INITIAL_ROAD_ENDPOINTS.get(f).first));
model.switchToNextPlayer();
}
for (int i = 0; i < model.getPlayerFactions().size(); i++) {
model.switchToPreviousPlayer();
Config.Faction f = model.getCurrentPlayerFaction();
assertTrue(model.placeInitialSettlement(INITIAL_SETTLEMENT_POSITIONS.get(f).second, true));
assertTrue(model.placeInitialRoad(INITIAL_SETTLEMENT_POSITIONS.get(f).second, INITIAL_ROAD_ENDPOINTS.get(f).second));
}
return model;
}
/**
* Returns a siedler game after the setup phase in the setup
* described in {@link ThreePlayerStandard} and with the bank almost empty.
*
* The following resource cards should be in the stock of the bank:
* <ul>
* <li>LUMBER: 1</li>
* <li>BRICK: 2</li>
* <li>GRAIN: 3</li>
* <li>ORE: 13</li>
* <li>WOOL: 0</li>
* </ul>
*
* The stocks of the players should contain:
* <br>
* Player 1:
* <ul>
* <li>LUMBER: 9</li>
* <li>BRICK: 9</li>
* <li>GRAIN: 8</li>
* <li>ORE: 7</li>
* <li>WOOL: 9</li>
* </ul>
* Player 2:
* <ul>
* <li>LUMBER: 0</li>
* <li>BRICK: 0</li>
* <li>GRAIN: 8</li>
* <li>ORE: 0</li>
* <li>WOOL: 10</li>
* </ul>
* Player 3:
* <ul>
* <li>LUMBER: 9</li>
* <li>BRICK: 8</li>
* <li>GRAIN: 0</li>
* <li>ORE: 0</li>
* <li>WOOL: 0</li>
* </ul>
*
* @param winpoints the number of points required to win the game
* @return the siedler game
*/
public static SiedlerGame getAfterSetupPhaseAlmostEmptyBank(int winpoints) {
SiedlerGame model = getAfterSetupPhase(winpoints);
throwDiceMultipleTimes(model, 6, 9);
throwDiceMultipleTimes(model, 11, 8);
throwDiceMultipleTimes(model, 2, 8);
throwDiceMultipleTimes(model, 4, 7);
throwDiceMultipleTimes(model, 12, 8);
throwDiceMultipleTimes(model, 5, 9);
throwDiceMultipleTimes(model, 9, 8);
return model;
}
/**
* Returns a {@link SiedlerGame} with several roads added but none longer than
* 4 elements. Hence, no player meets the longest road criteria yet. Furthermore,
* players one and three have enough resource cards to build additional roads and settlements.
*
* <p></p>
* <p>The game board should look as follows:
* <pre>
* ( ) ( ) ( ) ( )
* // \\ // \\ // \\ // \\
* ( ) ( ) ( ) ( ) ( )
* || ~~ || ~~ || ~~ || ~~ ||
* || || || || ||
* ( ) ( ) ( ) ( ) ( )
* // \\ // \\ // \\ // \\ // \\
* ( ) ( ) ( ) (bb) ( ) ( )
* || ~~ || LU || WL bb WL || ~~ ||
* || || 06 || 03 bb 08 || ||
* ( ) ( ) ( ) ( ) ( ) ( )
* // \\ // \\ rr \\ // \\ // \\ // \\
* ( ) ( ) (rr) ( ) ( ) ( ) ( )
* || ~~ gg GR rr OR || GR || LU || ~~ ||
* || gg 02 rr 04 || 05 || 10 || ||
* ( ) ( ) ( ) ( ) ( ) ( ) ( )
* // \\ gg rr rr \\ // \\ // \\ // \\ // \\
* ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( )
* || ~~ gg LU || BR || -- || OR || GR || ~~ ||
* || gg 05 || 09 || 07 || 06 || 09 || ||
* ( ) (gg) ( ) ( ) ( ) ( ) ( ) ( )
* \\ // gg // \\ // \\ // \\ rr \\ bb \\ //
* ( ) ( ) ( ) ( ) ( ) (bb) ( )
* || ~~ || GR || OR || LU rr WL || ~~ ||
* || || 10 || 11 || 03 rr 12 || ||
* ( ) ( ) ( ) ( ) ( ) ( ) ( )
* \\ // \\ // \\ // \\ // rr rr \\ //
* ( ) ( ) ( ) ( ) (rr) ( )
* || ~~ || WL gg BR gg BR rr ~~ ||
* || || 08 gg 04 gg 11 rr ||
* ( ) ( ) ( ) ( ) ( ) ( )
* \\ // \\ // gg gg \\ // \\ //
* ( ) ( ) (gg) ( ) ( )
* || ~~ || ~~ || ~~ || ~~ ||
* || || || || ||
* ( ) ( ) ( ) ( ) ( )
* \\ // \\ // \\ // \\ //
* ( ) ( ) ( ) ( )
* </pre>
* <p>
* And the player resource card stocks:
* <br>
* Player 1:
* <ul>
* <li>LUMBER: 6</li>
* <li>BRICK: 6</li>
* <li>GRAIN: 1</li>
* <li>ORE: 11</li>
* <li>WOOL: 1</li>
* </ul>
* Player 2:
* <ul>
* <li>LUMBER: 0</li>
* <li>BRICK: 0</li>
* <li>GRAIN: 0</li>
* <li>ORE: 0</li>
* <li>WOOL: 2</li>
* </ul>
* Player 3:
* <ul>
* <li>LUMBER: 6</li>
* <li>BRICK: 6</li>
* <li>GRAIN: 1</li>
* <li>ORE: 0</li>
* <li>WOOL: 1</li>
* </ul>
*
* @param winpoints the number of points required to win the game
* @return the siedler game
*/
public static SiedlerGame getAfterSetupPhaseSomeRoads(int winpoints) {
SiedlerGame model = getAfterSetupPhase(winpoints);
throwDiceMultipleTimes(model, 6, 7);
throwDiceMultipleTimes(model, 11, 6);
throwDiceMultipleTimes(model, 4, 5);
throwDiceMultipleTimes(model, 5, 6);
throwDiceMultipleTimes(model, 2, 1);
model.switchToNextPlayer();
model.switchToNextPlayer();
model.buildRoad(new Point(2,12), new Point(3,13));
buildRoad(model, List.of(new Point(2,10), new Point(3,9), new Point(3,7)));
model.buildRoad(new Point(8,18), new Point(8,16));
buildRoad(model, List.of(new Point(7,19), new Point(6,18), new Point(6,16)));
model.switchToNextPlayer();
model.buildRoad(new Point(10,16), new Point(11,15));
model.buildRoad(new Point(10,16), new Point(10,18));
buildRoad(model, List.of(new Point(9,15), new Point(9,13), new Point(10,12)));
buildRoad(model, List.of(new Point(5,7), new Point(5,9), new Point(4,10), new Point(3, 9)));
throwDiceMultipleTimes(model, 6, 6);
throwDiceMultipleTimes(model, 11, 6);
throwDiceMultipleTimes(model, 4, 6);
throwDiceMultipleTimes(model, 5, 6);
model.switchToNextPlayer();
model.switchToNextPlayer();
throwDiceMultipleTimes(model, 5, 4);
model.tradeWithBankFourToOne(Resource.LUMBER, Resource.GRAIN);
throwDiceMultipleTimes(model, 5, 4);
model.tradeWithBankFourToOne(Resource.LUMBER, Resource.WOOL);
model.switchToNextPlayer();
return model;
}
private static SiedlerGame throwDiceMultipleTimes(SiedlerGame model, int diceValue, int numberOfTimes) {
for(int i=0; i<numberOfTimes; i++) {
model.throwDice(diceValue);
}
return model;
}
/**
* Returns a siedler game after building four additional roads and two
* settlements after the setup phase with the resource cards and roads
* for player one ready to build a fifth settlement at {@link #PLAYER_ONE_READY_TO_BUILD_FIFTH_SETTLEMENT_FIFTH_SETTLEMENT_POSITION}
*<p></p>
*<p>The game board should look as follows:
* <pre>
* ( ) ( ) ( ) ( )
* // \\ // \\ // \\ // \\
* ( ) ( ) ( ) ( ) ( )
* || ~~ || ~~ || ~~ || ~~ ||
* || || || || ||
* ( ) ( ) ( ) ( ) ( )
* // \\ // \\ // \\ // \\ // \\
* ( ) ( ) (rr) (bb) ( ) ( )
* || ~~ || LU rr WL bb WL || ~~ ||
* || || 06 rr 03 bb 08 || ||
* ( ) ( ) ( ) ( ) ( ) ( )
* // \\ // \\ rr rr // \\ // \\ // \\
* ( ) ( ) (rr) (rr) ( ) ( ) ( )
* || ~~ || GR || OR || GR || LU || ~~ ||
* || || 02 || 04 || 05 || 10 || ||
* ( ) ( ) ( ) ( ) ( ) ( ) ( )
* // \\ // \\ // \\ // \\ // \\ // \\ // \\
* ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( )
* || ~~ gg LU || BR || -- || OR || GR || ~~ ||
* || gg 05 || 09 || 07 || 06 || 09 || ||
* ( ) (gg) ( ) ( ) ( ) ( ) ( ) ( )
* \\ // \\ // \\ // \\ // \\ // \\ bb \\ //
* ( ) ( ) ( ) ( ) ( ) (bb) ( )
* || ~~ || GR || OR || LU rr WL || ~~ ||
* || || 10 || 11 || 03 rr 12 || ||
* ( ) ( ) ( ) ( ) ( ) ( ) ( )
* \\ // \\ // \\ // \\ // rr // \\ //
* ( ) ( ) ( ) ( ) (rr) ( )
* || ~~ || WL || BR || BR || ~~ ||
* || || 08 || 04 || 11 || ||
* ( ) ( ) ( ) ( ) ( ) ( )
* \\ // \\ // \\ gg \\ // \\ //
* ( ) ( ) (gg) ( ) ( )
* || ~~ || ~~ || ~~ || ~~ ||
* || || || || ||
* ( ) ( ) ( ) ( ) ( )
* \\ // \\ // \\ // \\ //
* ( ) ( ) ( ) ( )
*
* </pre>
* <br>
* <p>And the player resource card stocks:</p>
* <br>
* Player 1:
* <ul>
* <li>LUMBER: 3</li>
* <li>BRICK: 3</li>
* <li>GRAIN: 2</li>
* <li>ORE: 0</li>
* <li>WOOL: 2</li>
* </ul>
* Player 2:
* <ul>
* <li>LUMBER: 0</li>
* <li>BRICK: 0</li>
* <li>GRAIN: 0</li>
* <li>ORE: 0</li>
* <li>WOOL: 5</li>
* </ul>
* Player 3:
* <ul>
* <li>LUMBER: 0</li>
* <li>BRICK: 1</li>
* <li>GRAIN: 0</li>
* <li>ORE: 0</li>
* <li>WOOL: 0</li>
* </ul>
*
* @param winpoints the number of points required to win the game
* @return the siedler game
*/
public static SiedlerGame getPlayerOneReadyToBuildFifthSettlement(int winpoints) {
SiedlerGame model = getAfterSetupPhase(winpoints);
//generate resources to build four roads and four settlements.
throwDiceMultipleTimes(model, 6, 8);
throwDiceMultipleTimes(model, 11, 7);
throwDiceMultipleTimes(model, 2, 4);
throwDiceMultipleTimes(model, 12, 3);
model.buildRoad(new Point(6,6), new Point(7,7));
model.buildRoad(new Point(6,6), new Point(6,4));
model.buildRoad(new Point(9,15), new Point(9,13));
model.buildSettlement(playerOneReadyToBuildFifthSettlementAllSettlementPositions.get(2));
model.buildSettlement(playerOneReadyToBuildFifthSettlementAllSettlementPositions.get(3));
return model;
}
private static void buildSettlement(SiedlerGame model, Point position, List<Point> roads) {
buildRoad(model, roads);
assertTrue(model.buildSettlement(position));
}
private static void buildRoad(SiedlerGame model, List<Point> roads) {
for (int i = 0; i < roads.size()-1; i++) {
assertTrue(model.buildRoad(roads.get(i), roads.get(i + 1)));
}
}
}
+106
View File
@@ -0,0 +1,106 @@
package ch.zhaw.hexboard;
import java.awt.Point;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
/***
* <p>
* This class performs tests for the class {@link Edge}.
* </p>
*
* @author tebe
*
**/
public class EdgeTest {
private Point[] hexagon22 = { new Point(2, 0), new Point(3, 1), new Point(3, 3), new Point(2, 4),
new Point(1, 3), new Point(1, 1) };
private Point[] hexagon75 = { new Point(7, 3), new Point(8, 4), new Point(8, 6), new Point(7, 7),
new Point(6, 6), new Point(6, 4) };
@Test
public void createValidEdge() {
new Edge(new Point(0, 0), new Point(1, 1));
}
@Test
public void edgeEqualityStartEndPointReversed() {
for (int i = 0; i < hexagon22.length - 1; i++) {
assertEquals(new Edge(hexagon22[i], hexagon22[i + 1]),
new Edge(hexagon22[i + 1], hexagon22[i]));
}
for (int i = 0; i < hexagon75.length - 1; i++) {
assertEquals(new Edge(hexagon75[i], hexagon75[i + 1]),
new Edge(hexagon75[i + 1], hexagon75[i]));
}
}
@Test
public void notEquals() {
assertNotEquals(new Edge(hexagon22[0], hexagon22[1]),
new Edge(hexagon22[1], hexagon22[2]));
}
@Test
public void createWithBothArgumentsNull() {
assertThrows(IllegalArgumentException.class, () -> new Edge(null, null));
}
@Test
public void createWithFirstArgumentNull() {
assertThrows(IllegalArgumentException.class, () -> new Edge(null, new Point(1, 0)));
}
@Test
public void createWithSecondArgumentNull() {
assertThrows(IllegalArgumentException.class, () -> new Edge(new Point(1, 0), null));
}
@Test
public void createWithStartAndEndpointIdentical() {
assertThrows(IllegalArgumentException.class, () -> new Edge(hexagon22[0], hexagon22[0]));
}
@Test
public void notAnEdgeHorizontalOddTop() {
assertThrows(IllegalArgumentException.class, () -> new Edge(new Point(5, 7), new Point(7, 7)));
}
@Test
public void notAnEdgeHorizontalOddMiddle() {
assertThrows(IllegalArgumentException.class, () -> new Edge(new Point(3, 2), new Point(5, 2)));
}
@Test
public void notAnEdgeHorizontalOddBottom() {
assertThrows(IllegalArgumentException.class, () -> new Edge(new Point(5, 3), new Point(7, 3)));
}
@Test
public void notAnEdgeHorizontalEvenTop() {
assertThrows(IllegalArgumentException.class, () -> new Edge(new Point(4, 4), new Point(6, 4)));
}
@Test
public void notAnEdgeHorizontalEvenMiddle() {
assertThrows(IllegalArgumentException.class, () -> new Edge(new Point(2, 5), new Point(4, 5)));
}
@Test
public void notAnEdgeHorizontalEvenBottom() {
assertThrows(IllegalArgumentException.class, () -> new Edge(new Point(4, 6), new Point(6, 6)));
}
@Test
public void notAnEdgeVerticalEven() {
assertThrows(IllegalArgumentException.class, () -> new Edge(new Point(7, 7), new Point(7, 3)));
}
@Test
public void notAnEdgeVerticalOdd() {
assertThrows(IllegalArgumentException.class, () -> new Edge(new Point(6, 4), new Point(6, 0)));
}
}
+121
View File
@@ -0,0 +1,121 @@
package ch.zhaw.hexboard;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.awt.Point;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/***
* <p>
* Tests for the class {@link HexBoard}.
* </p>
* @author tebe
*/
public class HexBoardTest {
private HexBoard<String, String, String, String> board;
private Point[] corner;
/**
* Setup for a test - Instantiates a board and adds one field at (7,5).
*
* <pre>
* 0 1 2 3 4 5 6 7 8
* | | | | | | | | | ...
*
* 0----
*
* 1----
*
* 2----
*
* 3---- C
* / \
* 4---- C C
*
* 5---- | F | ...
*
* 6---- C C
* \ /
* 7---- C
* </pre>
*/
@BeforeEach
public void setUp() {
board = new HexBoard<>();
board.addField(new Point(7, 5), "00");
Point[] singleField = { new Point(7, 3), new Point(8, 4), new Point(8, 6), new Point(7, 7),
new Point(6, 6), new Point(6, 4) };
this.corner = singleField;
}
// Edge retrieval
@Test
public void edgeTest() {
for (int i = 0; i < corner.length - 1; i++) {
assertNull(board.getEdge(corner[i], corner[i + 1]));
board.setEdge(corner[i], corner[i + 1], Integer.toString(i));
assertEquals(board.getEdge(corner[i], corner[i + 1]), Integer.toString(i));
}
}
@Test
public void noEdgeCoordinatesTest() {
assertThrows(IllegalArgumentException.class,
() -> board.getEdge(new Point(2, 2), new Point(0, 2)));
}
@Test
public void edgeDoesNotExistTest() {
assertThrows(IllegalArgumentException.class,
() -> board.getEdge(new Point(0, 2), new Point(3, 1)));
}
// Corner retrieval
@Test
public void cornerTest() {
for (Point p : corner) {
assertNull(board.getCorner(p));
board.setCorner(p, p.toString());
assertEquals(board.getCorner(p), p.toString());
}
}
@Test
public void noCornerCoordinateTest() {
assertThrows(IllegalArgumentException.class, () -> board.getCorner(new Point(2, 2)));
}
@Test
public void cornerDoesNotExistTest() {
assertThrows(IllegalArgumentException.class, () -> board.getCorner(new Point(2, 2)));
}
// Field addition/retrieval
@Test
public void fieldAreadyExistsErrorTest() {
board.addField(new Point(2, 2), "22");
assertThrows(IllegalArgumentException.class, () -> board.addField(new Point(2, 2), "22"));
}
@Test
public void fieldRetrievalTest() {
Point field = new Point(2, 2);
board.addField(field, new String("22"));
assertTrue(board.hasField(field));
assertEquals(board.getField(field), "22");
}
@Test
public void fieldRetrievalWrongCoordinatesOutsideTest() {
assertThrows(IllegalArgumentException.class, () -> board.getField(new Point(10, 10)));
}
@Test
public void fieldRetrievalWrongCoordinatesInsideTest() {
assertThrows(IllegalArgumentException.class, () -> board.getField(new Point(2, 2)));
}
}