Merge remote-tracking branch 'origin/main'

This commit is contained in:
Leonardo Brandenberger 2021-12-10 11:11:27 +01:00
commit 9096e28d78
4 changed files with 267 additions and 169 deletions

View File

@ -7,8 +7,8 @@ to be able to dominate your friends.
#Rules
1. The min. Player amount is 2 and the max. Player amount is 4.
2. Each Player can build a road and a settlement free of cost at the beginning of
the game.
2. Each Player can build two roads and two settlements free of cost at the beginning of
the game. After the placement, each player gets resources from the field around the second settlement.
3. Every Player is being sorted into a faction. There cannot be two players in the
same faction.
4. A player cannot build two settlements or cities right next one another.
@ -25,7 +25,7 @@ For a more detailed version of the rules please look here: https://www.catan.de/
#Usermanual
First the program will ask how many players will be playing the game. The minimum
amount of players is 2 and the maximum amount of players is 4. Each player will
be appointed to a faction. Now every player can build a settlement and a road
be appointed to a faction. In the next step, the program ask for the number of win points. The first player who reaches this number of win points, will win the game. Now every player can build a settlement and a road
after every player has built a settlement and road, they can build a second
settlement and road in reversed order. When the players build their second
settlement they then receive the resources surrounding that specific settlement.

View File

@ -30,8 +30,8 @@ public class SiedlerGame {
*
* @param winPoints the number of points required to win the game
* @param numberOfPlayers the number of players
* @throws IllegalArgumentException if winPoints is lower than
* three or players is not between two and four
* @throws IllegalArgumentException if winPoints is lower than 3
* or players is not between two and four
*/
public SiedlerGame(int winPoints, int numberOfPlayers) {
if (winPoints < 3 || numberOfPlayers < Config.MIN_NUMBER_OF_PLAYERS || numberOfPlayers > 4) {

View File

@ -0,0 +1,57 @@
package ch.zhaw.catan;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import java.awt.*;
import java.util.Arrays;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class SiedlerBoardTest {
@Nested
class LongestRoadTest {
/**
* To Test getLongestRoad in SiedlerBoard
*/
List<Config.Faction> factionList = Arrays.asList(Config.Faction.values());
SiedlerBoard board = new SiedlerBoard();
@BeforeEach
public void buildLongestRoad(){
board.createFixGameField();
board.setEdge(new Point(6, 6), new Point(5, 7), new Road(Config.Faction.BLUE, new Point(6, 6), new Point(5, 7)));
board.setEdge(new Point(4, 6), new Point(5, 7), new Road(Config.Faction.BLUE, new Point(4, 6), new Point(5, 7)));
board.setEdge(new Point(4, 6), new Point(4, 4), new Road(Config.Faction.BLUE, new Point(4, 6), new Point(4, 4)));
board.setEdge(new Point(4, 6), new Point(3, 7), new Road(Config.Faction.BLUE, new Point(4, 6), new Point(3, 7)));
board.setEdge(new Point(3, 7), new Point(3, 9), new Road(Config.Faction.BLUE, new Point(3, 7), new Point(3, 9)));
board.setEdge(new Point(3, 9), new Point(4, 10), new Road(Config.Faction.BLUE, new Point(3, 9), new Point(4, 10)));
board.setEdge(new Point(4, 10), new Point(5, 9), new Road(Config.Faction.BLUE, new Point(4, 10), new Point(5, 9)));
board.setCorner(new Point(3, 7), new Settlement(Config.Faction.BLUE, new Point(3, 7)));
}
@Test
public void testLongestRoadSimple() {
System.out.println(board.getTextView());
assertEquals(Config.Faction.BLUE, board.getLongestRoadFaction(factionList));
assertEquals(6, board.getLongestRoadLenth());
}
@Test
public void testLongestRoadWithInterrupt() {
board.setCorner(new Point(4, 10), new Settlement(Config.Faction.RED, new Point(4, 10)));
System.out.println(board.getTextView());
assertEquals(Config.Faction.BLUE, board.getLongestRoadFaction(factionList));
assertEquals(5, board.getLongestRoadLenth());
}
}
}

View File

@ -1,10 +1,11 @@
package ch.zhaw.catan;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertThrows;
import ch.zhaw.catan.games.ThreePlayerStandard;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import java.awt.*;
import java.util.*;
@ -25,52 +26,63 @@ public class SiedlerGameTest {
private final static int DEFAULT_WINPOINTS = 5;
private final static int DEFAULT_PLAYERAMOUNT = 4;
/**
* Property START_SETTLEMENT_POSITIONS
*
* Lists all positions of Settlement for every faction in the initialization phase.
* Each faction is assigned to a list of specific settlements, which represents as a list of points
*/
private final static Map<Config.Faction, ArrayList<Point>> START_SETTLEMENT_POSITIONS = Map.of(
Config.Faction.BLUE, new ArrayList<>(List.of(new Point(4, 4), new Point(5, 7))),
Config.Faction.RED, new ArrayList<>(List.of(new Point(10, 4), new Point(9, 7))),
Config.Faction.GREEN, new ArrayList<>(List.of(new Point(4, 18), new Point(5, 15))),
Config.Faction.YELLOW, new ArrayList<>(List.of(new Point(10, 18), new Point(9, 15)))
);
/**
* START_ROADS_POSITION
*
* Lists all endpoints of roads for every faction in the initialization phase.
* Each faction is assigned to a specific Road, which represents as a tuple of 2 points
*/
private final static Map<Config.Faction, ArrayList<Tuple<Point, Point>>> START_ROADS_POSITIONS = Map.of(
Config.Faction.BLUE, new ArrayList<>(List.of(
new Tuple<>(new Point(4, 4), new Point(4, 6)), new Tuple<>(new Point(4, 6), new Point(5, 7)))),
Config.Faction.RED, new ArrayList<>(List.of(
new Tuple<>(new Point(10, 4), new Point(10, 6)), new Tuple<>(new Point(10, 6), new Point(9, 7)))),
Config.Faction.GREEN, new ArrayList<>(List.of(
new Tuple<>(new Point(4, 18), new Point(4, 16)), new Tuple<>(new Point(4, 16), new Point(5, 15)))),
Config.Faction.YELLOW, new ArrayList<>(List.of(
new Tuple<>(new Point(10, 18), new Point(10, 16)), new Tuple<>(new Point(10, 16), new Point(9, 15))))
);
/**
* This test class contains all positive test cases.
*/
@Nested
@DisplayName("Positive test cases")
class PositiveTestcases {
@Nested
class LongestRoadTest {
/**
* To Test getLongestRoad in SiedlerBoard
*/
/**
* This test will check, if the game initializes with all 4 factions.
* All factions should have no resources
*/
@ParameterizedTest(name = "Test with {arguments} players")
@ValueSource(ints = {2, 3, 4})
@DisplayName("Game initializing with different amount of players within the domain (Players have no resources), expected ok")
public void TestGameInitializationWithAllPlayercounts(int playerAmount) {
SiedlerGame game = new SiedlerGame(DEFAULT_WINPOINTS, playerAmount);
List<Config.Faction> factionList = Arrays.asList(Config.Faction.values());
for (Config.Faction faction: game.getPlayerFactions()) {
HashMap<Config.Resource, Integer> resources = game.getCurrentPlayerResource();
SiedlerBoard board = new SiedlerBoard();
Assertions.assertEquals(0, resources.get(Config.Resource.BRICK));
Assertions.assertEquals(0, resources.get(Config.Resource.GRAIN));
Assertions.assertEquals(0, resources.get(Config.Resource.LUMBER));
Assertions.assertEquals(0, resources.get(Config.Resource.ORE));
Assertions.assertEquals(0, resources.get(Config.Resource.WOOL));
@BeforeEach
public void buildLongestRoad(){
board.createFixGameField();
board.setEdge(new Point(6, 6), new Point(5, 7), new Road(Config.Faction.BLUE, new Point(6, 6), new Point(5, 7)));
board.setEdge(new Point(4, 6), new Point(5, 7), new Road(Config.Faction.BLUE, new Point(4, 6), new Point(5, 7)));
board.setEdge(new Point(4, 6), new Point(4, 4), new Road(Config.Faction.BLUE, new Point(4, 6), new Point(4, 4)));
board.setEdge(new Point(4, 6), new Point(3, 7), new Road(Config.Faction.BLUE, new Point(4, 6), new Point(3, 7)));
board.setEdge(new Point(3, 7), new Point(3, 9), new Road(Config.Faction.BLUE, new Point(3, 7), new Point(3, 9)));
board.setEdge(new Point(3, 9), new Point(4, 10), new Road(Config.Faction.BLUE, new Point(3, 9), new Point(4, 10)));
board.setEdge(new Point(4, 10), new Point(5, 9), new Road(Config.Faction.BLUE, new Point(4, 10), new Point(5, 9)));
board.setCorner(new Point(3, 7), new Settlement(Config.Faction.BLUE, new Point(3, 7)));
}
@Test
public void testLongestRoadSimple() {
System.out.println(board.getTextView());
assertEquals(Config.Faction.BLUE, board.getLongestRoadFaction(factionList));
assertEquals(6, board.getLongestRoadLenth());
}
@Test
public void testLongestRoadWithInterrupt() {
board.setCorner(new Point(4, 10), new Settlement(Config.Faction.RED, new Point(4, 10)));
System.out.println(board.getTextView());
assertEquals(Config.Faction.BLUE, board.getLongestRoadFaction(factionList));
assertEquals(5, board.getLongestRoadLenth());
game.switchToNextPlayer();
}
}
@ -81,55 +93,90 @@ public class SiedlerGameTest {
@DisplayName("Test")
public void TestHandle7() {
SiedlerGame game = SystemTestcases.startGame();
SiedlerGame game = startGame();
}
}
/**
* @Class NegtiveTestcases
*
* This class contains all negative test cases
*/
@Nested
@DisplayName("Negative test cases")
class NegativeTestcases {
/**
* Tests if the method will fail when given false Data
* {@link ThreePlayerStandard#getAfterSetupPhaseAlmostEmptyBank(int)}
* Tests if siedlergame will start with one or five players.
* 1 Player is below the minimum
* 5 Players are above the maximum
*/
@Test
public void destructiveTestBuildCity() {
SiedlerGame model = ThreePlayerStandard.getAfterSetupPhaseAlmostEmptyBank(DEFAULT_WINPOINTS);
@ParameterizedTest(name = "Test with {arguments} players")
@ValueSource(ints = {1, 5})
@DisplayName("Starting Siedler game with one player or 5 players, expects fail")
public void startSiedlerGameWithOnePlayerorMoreThanMaximum(int playerAmount) {
Exception exc = assertThrows(IllegalArgumentException.class, () -> {
new SiedlerGame(DEFAULT_WINPOINTS, playerAmount);
});
//Too
Assertions.assertFalse(model.buildCity(new Point(50, 60)));
//Factions wants to build a city on a city from another faction
Assertions.assertFalse(model.buildCity(new Point(3, 3)));
Assertions.assertEquals(IllegalArgumentException.class, exc.getClass());
}
/**
* Tests if the method fails when given false Data
* {@link ThreePlayerStandard#getAfterSetupPhase(int)}
* Tests if the game crashes when passing an amount of points, that is below the minimum amount
*/
@Test
public void destructiveTestBuildRoad() {
@DisplayName("Starting Siedler game with one player, expects fail")
public void startSiedlerGameWithLowerThanMinimumWinPoints() {
SiedlerGame model = ThreePlayerStandard.getAfterSetupPhase(DEFAULT_WINPOINTS);
Exception exc = assertThrows(IllegalArgumentException.class, () -> {
SiedlerGame game = new SiedlerGame(1, 4);
});
Assertions.assertEquals(IllegalArgumentException.class, exc.getClass());
}
/**
* This testcase will test, if the methods placeInitialRoad and placeInitialSettlement are overwritting
* already occupied positions if the same faction or any other faction are calling the method with the same positions
*
* Expected: Method placeInitialRoad placeInitialSettlement should return false, independent of the current faction playing
*/
@Test
@DisplayName("Test placeInitialRoad and placeInitialSettlement with already occupied positions")
public void testPlaceInitialStructuresInAlreadyOccupiedPositions() {
SiedlerGame game = startGame();
Point settlementPoint = START_SETTLEMENT_POSITIONS.get(Config.Faction.BLUE).get(1);
Assertions.assertTrue(game.placeInitialSettlement(settlementPoint, false));
Assertions.assertFalse(game.placeInitialSettlement(settlementPoint, false));
Tuple<Point, Point> roadEndpoints = START_ROADS_POSITIONS.get(Config.Faction.BLUE).get(1);
Assertions.assertTrue(game.placeInitialRoad(roadEndpoints.first, roadEndpoints.second));
Assertions.assertFalse(game.placeInitialRoad(roadEndpoints.first, roadEndpoints.second));
// Switch to other player to see if the occupied fields can be overwritten, when switched to the next player/faction
game.switchToNextPlayer();
Assertions.assertFalse(game.placeInitialRoad(roadEndpoints.first, roadEndpoints.second));
Assertions.assertFalse(game.placeInitialSettlement(settlementPoint, false));
System.out.println(model.buildRoad(new Point(3, 7),new Point(3, 9)));
}
/**
* Tests if the method fails when trading material with the same material
* {@link ThreePlayerStandard#getAfterSetupPhaseAlmostEmptyBank(int)}
* This testcase will test, if the methods buildRoad, buildCity buildSettlement are overwritting
* already occupied positions if the same faction or any other faction are calling the method with the same positions
*
* Expected: Method placeInitialRoad placeInitialSettlement should return false, independent of the current faction playing
*/
@Test
public void destructiveTestTradeWithBank() {
SiedlerGame model = ThreePlayerStandard.getAfterSetupPhaseAlmostEmptyBank(DEFAULT_WINPOINTS);
model.switchToNextPlayer();
@DisplayName("Test buildRoad, buildCity and buildSettlement with already occupied positions")
public void testBuildStructuresOnOccupiedFields() {
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));
System.out.println(model.tradeWithBankFourToOne(Config.Resource.WOOL, Config.Resource.WOOL));
}
}
@ -137,97 +184,55 @@ public class SiedlerGameTest {
* @Class SystemTestCases
*
* This class simulates a running game and tests multiple sequences of this game.
* Those test cases will be
*
*/
@Nested
@DisplayName("System test cases")
class SystemTestcases {
private final static Map<Config.Faction, Point> START_SETTLEMENT_POSITIONS = new HashMap<>(
Map.of(
Config.Faction.BLUE, new Point(4, 4),
Config.Faction.RED, new Point(10, 4),
Config.Faction.GREEN, new Point(4, 18),
Config.Faction.YELLOW, new Point(10, 18)
));
/**
* @Datafield START_ROADS_POSITION
*
* This are a set of Roads, that have been
*/
private final static Map<Config.Faction, Tuple<Point, Point>> START_ROADS_POSITIONS = new HashMap<>(
Map.of(
Config.Faction.BLUE, new Tuple<>(new Point(4, 4), new Point(4, 6)),
Config.Faction.RED, new Tuple<>(new Point(10, 4), new Point(10, 6)),
Config.Faction.GREEN, new Tuple<>(new Point(4, 18), new Point(4, 16)),
Config.Faction.YELLOW, new Tuple<>(new Point(10, 18), new Point(10, 16))
));
private static SiedlerGame startGame() {
return new SiedlerGame(DEFAULT_WINPOINTS, DEFAULT_PLAYERAMOUNT);
}
@Test
@DisplayName("Game initializing")
public void TestGameInitialization() {
SiedlerGame game = startGame();
for (Config.Faction faction: game.getPlayerFactions()) {
HashMap<Config.Resource, Integer> resources = game.getCurrentPlayerResource();
Assertions.assertEquals(0, resources.get(Config.Resource.BRICK));
Assertions.assertEquals(0, resources.get(Config.Resource.GRAIN));
Assertions.assertEquals(0, resources.get(Config.Resource.LUMBER));
Assertions.assertEquals(0, resources.get(Config.Resource.ORE));
Assertions.assertEquals(0, resources.get(Config.Resource.WOOL));
game.switchToNextPlayer();
}
}
/**
* This will test when
* This will test if the players can place initial settlements and roads
*/
@Test
@DisplayName("2 Players initialize a settlement and position")
public void TestGameInSetupPhase() {
SiedlerGame game = gameInSetupPhase();
for (Config.Faction faction: game.getPlayerFactions()) {
HashMap<Config.Resource, Integer> resources = game.getCurrentPlayerResource();
Assertions.assertEquals(0, resources.get(Config.Resource.BRICK));
Assertions.assertEquals(0, resources.get(Config.Resource.GRAIN));
Assertions.assertEquals(0, resources.get(Config.Resource.LUMBER));
Assertions.assertEquals(0, resources.get(Config.Resource.ORE));
Assertions.assertEquals(0, resources.get(Config.Resource.WOOL));
game.switchToNextPlayer();
}
}
private static SiedlerGame gameInSetupPhase() {
SiedlerGame game = startGame();
for (Config.Faction faction: game.getPlayerFactions()) {
Assertions.assertTrue(game.placeInitialSettlement(START_SETTLEMENT_POSITIONS.get(game.getCurrentPlayerFaction()).get(0), false));
Tuple<Point, Point> road1 = START_ROADS_POSITIONS.get(game.getCurrentPlayerFaction()).get(0);
Assertions.assertTrue(game.placeInitialRoad(road1.first, road1.second));
game.placeInitialSettlement(START_SETTLEMENT_POSITIONS.get(faction), false);
game.placeInitialRoad(START_ROADS_POSITIONS.get(faction).first, START_ROADS_POSITIONS.get(faction).second);
game.switchToNextPlayer();
game.switchToNextPlayer();
}
Assertions.assertTrue(game.placeInitialSettlement(START_SETTLEMENT_POSITIONS.get(game.getCurrentPlayerFaction()).get(1), false));
Tuple<Point, Point> road2 = START_ROADS_POSITIONS.get(game.getCurrentPlayerFaction()).get(1);
Assertions.assertTrue(game.placeInitialRoad(road2.first, road2.second));
return game;
}
/**
* tests, if the players can do all pf the actions in the building phase
*/
@Test
public void TestGameAfterSetupPhase() {
SiedlerGame game = gameAfterSetupPhase();
throwDiceSeveralTimes(game, 5, 5);
soutDistribution(game);
}
/**
* tests, if a player wins when reached the amount of points.
*/
@Test
@DisplayName("End of Game test")
public void TestGameEnd() {
}
//TEMPORARY METHOD, WILL BE REMOVED SOON
private static void soutDistribution(SiedlerGame game) {
System.out.println("\n\nVerteilung \n\n");
for (Config.Faction faction: game.getPlayerFactions()) {
HashMap<Config.Resource, Integer> resources = game.getCurrentPlayerResource();
@ -241,35 +246,71 @@ public class SiedlerGameTest {
game.switchToNextPlayer();
}
}
private static SiedlerGame gameAfterSetupPhase() {
SiedlerGame game = gameInSetupPhase();
return game;
}
@Test
@DisplayName("End of Game test")
public void TestGameEnd() {
}
private static SiedlerGame gameNearEnd() {
SiedlerGame game = gameAfterSetupPhase();
return game;
}
private static void throwDiceSeveralTimes(SiedlerGame game, int dice, int amountDiceThrows) {
for (int i = 0; i < amountDiceThrows; i++) {
System.out.println(game.getCurrentPlayerFaction().toString());
game.throwDice(dice);
}
}
}
/**
* Initializes a game with the default values of winning points and amount of player
*
* @return
*/
private static SiedlerGame startGame() {
return new SiedlerGame(DEFAULT_WINPOINTS, DEFAULT_PLAYERAMOUNT);
}
/**
* This method will set the game to the timeline after the setup.
* Players have already set each 2 Settlements and 2 Roads.
*
* @return SiedlerGame The game after the setup phase
*/
private static SiedlerGame gameAfterSetupPhase() {
SiedlerGame game = startGame();
for (int i = 0; i < game.getPlayerFactions().size(); i++) {
Config.Faction f = game.getCurrentPlayerFaction();
game.placeInitialSettlement(START_SETTLEMENT_POSITIONS.get(f).get(0), false);
Tuple<Point, Point> firstRoad = START_ROADS_POSITIONS.get(f).get(0);
game.placeInitialRoad(firstRoad.first, firstRoad.second);
game.switchToNextPlayer();
}
for (int i = 0; i < game.getPlayerFactions().size(); i++) {
game.switchToPreviousPlayer();
Config.Faction f = game.getCurrentPlayerFaction();
game.placeInitialSettlement(START_SETTLEMENT_POSITIONS.get(f).get(1), false);
Tuple<Point, Point> secondRoad = START_ROADS_POSITIONS.get(f).get(1);
game.placeInitialRoad(secondRoad.first, secondRoad.second);
}
return game;
}
/**
* This method will call the method "throwDice" multiple times and passes the set value of the dice
*
* @param game Type SiedlerGame, the game itself in a running state
* @param dice Type int, Set Value of dice
* @param amountDiceThrows Type int, The amount of dice throws
*/
private static void throwDiceSeveralTimes(SiedlerGame game, int dice, int amountDiceThrows) {
for (int i = 0; i < amountDiceThrows; i++) {
System.out.println(game.getCurrentPlayerFaction().toString());
game.throwDice(dice);
}
}
/**
* This method will setup a game to a state before a player has the points
* for being able to win the game
*
* @return SiedlerGame which is near the
*/
private static SiedlerGame gameNearEnd() {
SiedlerGame game = gameAfterSetupPhase();
return game;
}
}