259 lines
13 KiB
Java
259 lines
13 KiB
Java
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());
|
|
}
|
|
}
|