Merge remote-tracking branch 'origin/main'

This commit is contained in:
Leonardo Brandenberger 2021-12-10 18:34:41 +01:00
commit 8a5dab76e4
15 changed files with 155 additions and 93 deletions

View File

@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_16" project-jdk-name="openjdk-17" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="openjdk-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@ -6,19 +6,20 @@ strategic game where you have to choose wisely where to build your structures,
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 two roads and two settlements free of cost at the beginning of
1. The minimum Player amount is 2 and the maximum Player amount is 4.
2. The minimum amount if win points is 3.
3. 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
4. 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.
5. A player cannot build two settlements or cities right next one another.
There have to be at least two roads between them.
5. The cost for each structure is set and is nonnegotiable.
6. The player with the longest road (most roads connecting to one another)
6. The cost for each structure is set and is nonnegotiable.
7. The player with the longest road (most roads connecting to one another), which is longer then 4
will be awarded two additional points.
7. If a player rolls a 7 on a dice throw, then the resources of every player that has
8. If a player rolls a 7 on a dice throw, then the resources of every player that has
more than 7 resources will be halved. The resources that are being taken are chosen
at random.
by random.
For a more detailed version of the rules please look here: https://www.catan.de/sites/prod/files/2021-06/CATAN_DasSpiel_Spielregel.pdf
@ -29,12 +30,25 @@ be appointed to a faction. In the next step, the program ask for the number of w
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.
Now that the setup is complete the player that placed the last settlement will
begin. After the players have rolled the dice the resources connected to the
number that the player rolled with the dice.
Now that the setup is complete the next player can start with the first dice throw. After the players have rolled the dice the fields connected to the
number that the player rolled with the dice will pay the associated resources to the players who have placed a settlement on a corner around of the field.
If the settlement is upgraded to a city, the player gets two of the appropriate resource.
To execute a action type in the associated number of the command, which is showed in the terminal.
#1. Next Player
``next player`` Ends a players turn
When the current player has done all the building and trading they wanted and now
want to end their turn they can end it by entering the command next player. By entering
this command the player relinquishes their turn and the next player may start their
turn.
#2. Build Settlement
``build settlement`` Builds a settlement
Now as for the commands a player has to put in while it's their turn:
#Build Settlement
When it's the players turn, they can build a new settlement by giving the command
build settlement. With that they will be asked where they want to build said settlement
and to enter the coordinates, then the program will check if those coordinates are available or not. Then the
@ -42,7 +56,9 @@ program will subtract the resources needed to build a settlement. If the player
insufficient resources the settlement will not be built and an error message will
appear. The turn of the current player will continue until the player ends it.
#Build City
#3. Build City
``build city`` Builds a city
During the players turn they can build a city on the same coordinates that they
have already built a settlement on. To do that they have to enter the command
build city. Then they have to add the coordinates that they want the city to be
@ -52,9 +68,11 @@ will then check if the player has sufficient resources to build the city, then
the program will subtract them of the players resources, otherwise the city won't
be build and the player continues their turn until they end it.
#Build Road
#4. Build Road
``build road`` Builds a road
During the current players turn, the player can build a new road by giving the
command build road. Then the player will be asked to give the coordinates for where
command build road. Then the player will be asked to give the coordinates of the start corner and the end corner for where
they want to build the new road after entering the coordinates the program will
check to see if they are valid coordinates and if they aren't occupied.
If the coordinates are checked and there was no error message, then the program
@ -63,7 +81,9 @@ program will then subtract the amount of resources of the player. If they do not
have enough resources the road will not be built and the player will receive
an error message. The player continues their turn until they end it.
#Trade with Bank
#5. Trade with Bank
``trade with bank`` Let's the player trade resources with the bank
The current player can trade resources with the bank by entering the command
trade with bank. The player then can enter what and how many resources they want
then they have to enter what resources they will give in return. The trade course
@ -71,15 +91,18 @@ for the resources is set to 1:4. That means the player will have to give 4 resou
trade for one of their choosing from the bank. If they do not have enough resources
to give the trade will not be completed and the player may continue their turn.
#Next Player
When the current player has done all the building and trading they wanted and now
want to end their turn they can end it by entering the command next player. By entering
this command the player relinquishes their turn and the next player may start their
turn.
#Quit
#6. Quit
``quit`` Let's a player quit the game
If a player wants to quit the game they can enter the command quit while it's their
turn to quit the game.
#Coordinates
![Coordinates](doc/Coordinates_SiedlerBoard.PNG)
#Class Diagram
![Class Diagramm](doc/ClassDiagramm.png)

BIN
doc/ClassDiagramm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

View File

@ -2,39 +2,19 @@ package ch.zhaw.catan;
import java.util.HashMap;
/**
* Bank Class that stores Resources when not being owned by a player,
* and the needed functions to take and give resources to it.
*
* @author Leonardo Brandenberger
*/
public class Bank {
private final HashMap<Config.Resource, Integer> resources = new HashMap<>();
/**
* Construct a Bank Object and stores Config Values in own HashMap.
*/
public Bank() {
resources.putAll(Config.INITIAL_RESOURCE_CARDS_BANK);
}
/**
* Stores a desired resource in desired quantity in the bank.
*
* @param resource the resource type that gets added to the bank
* @param numberOfResources the quantity of resources of the chosen type get added
*/
public void storeResourceToBank(Config.Resource resource, int numberOfResources) {
resources.put(resource, resources.get(resource) + numberOfResources);
}
/**
* Checks if a Resource is available in the quantity desired. and then deducts it from the bank inventory.
*
* @param resource the resource type that has to be deducted
* @param numberOfResources the quantity of the resource that gets deducted from the inventory
* @return true if resources available and deducted false if not enough resources are in the bank
*/
public boolean getResourceFromBank(Config.Resource resource, int numberOfResources) {
if (resources.get(resource) >= numberOfResources) {
Integer newResourceNumber = resources.get(resource) - numberOfResources;

View File

@ -8,10 +8,8 @@ package ch.zhaw.catan;
public enum Command {
NEXT_PLAYER("next player"), BUILD_SETTLEMENT("build settlement"), BUILD_CITY("build city"),
BUILD_ROAD("build road"), TRADE_WITH_BANK("trade with bank"), QUIT("quit");
private final String commandWord;
Command(String commandWord) {
this.commandWord = commandWord;
}

View File

@ -11,6 +11,11 @@ import java.util.List;
*/
public class Player {
/**
* faction: The faction of the player
* resources: The resources the player owns
* structureToUse: The structures a player can build.
*/
private final Config.Faction faction;
private final HashMap<Config.Resource, Integer> resources;
private final HashMap<Config.Structure, Integer> structureToUse;

View File

@ -1,6 +1,6 @@
package ch.zhaw.catan;
import java.awt.Point;
import java.awt.*;
/**
* Sub Class of Structure and Super Class of City

View File

@ -31,7 +31,7 @@ public class Siedler {
boolean diceThrown = false;
while (running) {
Config.Faction currentPlayerFaction = game.getCurrentPlayerFaction();
parser.displayGameboard(game.getBoard().getTextView());
parser.displayGameboard(game.getBoardTextView());
parser.playerTurn(currentPlayerFaction);
if (!diceThrown) {
throwDice(parser, game);
@ -170,7 +170,7 @@ public class Siedler {
* @param payout true (for second Settlement in founding Phase): the Player gets a payout for the settlement. false (for first Settlement in founding Phase): The Player gets no payout.
*/
private static void buildStructuresInFoundingPhase(Parser parser, SiedlerGame game, Boolean payout) {
parser.displayGameboard(game.getBoard().getTextView());
parser.displayGameboard(game.getBoardTextView());
parser.playerTurn(game.getCurrentPlayerFaction());
//build Settlement
@ -185,7 +185,7 @@ public class Siedler {
} while (!successful);
//build Road
parser.displayGameboard(game.getBoard().getTextView());
parser.displayGameboard(game.getBoardTextView());
parser.giveCoordinatesForStructures(Config.Structure.ROAD);
successful = false;
do {

View File

@ -2,7 +2,6 @@ package ch.zhaw.catan;
import ch.zhaw.hexboard.HexBoard;
import ch.zhaw.hexboard.Label;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Collections;
@ -73,7 +72,7 @@ public class SiedlerBoard extends HexBoard<Config.Land, Settlement, Road, String
*
* @return String of actual board.
*/
public String getTextView() {
public String toString() {
SiedlerBoardTextView view = new SiedlerBoardTextView(this);
for (Map.Entry<Point, Field> field : fields.entrySet()) {
view.setLowerFieldLabel(field.getKey(), field.getValue().getLabel());

View File

@ -3,11 +3,13 @@ package ch.zhaw.catan;
import ch.zhaw.catan.Config.Land;
import ch.zhaw.hexboard.HexBoardTextView;
//TODO Java Docs
/**
* This Class extends the Class HexBoardTextView
*/
public class SiedlerBoardTextView extends HexBoardTextView<Land, Settlement, Road, String> {
public SiedlerBoardTextView(SiedlerBoard board) {
super(board);
}
public SiedlerBoardTextView(SiedlerBoard board) {
super(board);
}
}

View File

@ -1,19 +1,17 @@
package ch.zhaw.catan;
import java.awt.Point;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* This class performs all actions related to modifying the game state.
* <p>
* TODO: (your documentation)
*
* @author TODO
* @author Andrin Fassbind, Leonardo Brandenberger, Roman Schenk, Stefan Amador
*/
public class SiedlerGame {
static final int FOUR_TO_ONE_TRADE_OFFER = 4;
@ -34,9 +32,6 @@ public class SiedlerGame {
* 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) {
throw new IllegalArgumentException();
}
bank = new Bank();
board = new SiedlerBoard();
board.createFixGameField();
@ -74,7 +69,14 @@ public class SiedlerGame {
}
}
//TODO JavaDoc
/**
* This methode is used to add resources to the player.
*
* @param player the active Player
* @param resource the resource to add
* @param numberToAdd the quantity of resources to add
* @return true if resource has been added else false
*/
private boolean addResourcesToPlayer(Player player, Config.Resource resource, int numberToAdd) {
if (bank.getResourceFromBank(resource, numberToAdd)) {
player.addResource(resource, numberToAdd);
@ -83,7 +85,14 @@ public class SiedlerGame {
return false;
}
//TODO JavaDoc
/**
* This methode is used to subtract resources from Player
*
* @param player the active player
* @param resource the resource to subtract
* @param numberToSubtract the quantity of resource to subtract
* @return true if resource has been subtracted
*/
private boolean subtractResourceFromPlayer(Player player, Config.Resource resource, int numberToSubtract) {
if (player.subtractResource(resource, numberToSubtract)) {
bank.storeResourceToBank(resource, numberToSubtract);
@ -114,7 +123,7 @@ public class SiedlerGame {
}
/**
* Returns the game board.
* Returns the game board. Used for test
*
* @return the game board
*/
@ -122,6 +131,13 @@ public class SiedlerGame {
return board;
}
/**
* Returns the String used to show the Board
*
* @return String of the Board.
*/
public String getBoardTextView(){return board.toString();}
/**
* Returns the {@link Config.Faction} of the current player.
*
@ -142,6 +158,11 @@ public class SiedlerGame {
return allPlayers.get(activePlayer).getSpecificResource(resource);
}
/**
* Returns the resources of the current player.
*
* @return a hashmap with all resources the player has. Key: Resource name Value: number of resources
*/
public HashMap<Config.Resource, Integer> getCurrentPlayerResource() {
return allPlayers.get(activePlayer).getResources();
}
@ -234,7 +255,11 @@ public class SiedlerGame {
return null;
}
//TODO JavaDoc
/**
* This method handles the case if a 7 has been diced.
*
* @param player the active player who rolls the dice.
*/
public void handleDiceThrow7(Player player) {
ArrayList<Config.Resource> resourceArrayList = new ArrayList<>();
HashMap<Config.Resource, Integer> resources = player.getResources();
@ -376,7 +401,7 @@ public class SiedlerGame {
if (!board.hasEdge(roadStart, roadEnd)) {
return false;
}
//2. Check if edge is empty //TODO Check if always inverted is allowed
//2. Check if edge is empty
if (board.getEdge(roadStart, roadEnd) != null) {
return false;
}
@ -482,7 +507,11 @@ public class SiedlerGame {
return null;
}
//Todo Java Doc
/**
* This methode counts the winpoints of the current player.
*
* @return the winpoints as an integer
*/
public int getCurrentPlayerWinPoints() {
int winPoints = 0;
List<Settlement> settlements = board.getCorners();

View File

@ -12,11 +12,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
public class SiedlerBoardTest {
/**
* To Test getLongestRoad in SiedlerBoard
*/
@Nested
class LongestRoadTest {
/**
* To Test getLongestRoad in SiedlerBoard
*/
List<Config.Faction> factionList = Arrays.asList(Config.Faction.values());
@ -38,7 +38,7 @@ public class SiedlerBoardTest {
@Test
public void testLongestRoadSimple() {
System.out.println(board.getTextView());
System.out.println(board.toString());
assertEquals(Config.Faction.BLUE, board.getLongestRoadFaction(factionList));
assertEquals(6, board.getLongestRoadLength());
@ -47,7 +47,7 @@ public class SiedlerBoardTest {
@Test
public void testLongestRoadWithInterrupt() {
board.setCorner(new Point(4, 10), new Settlement(Config.Faction.RED, new Point(4, 10)));
System.out.println(board.getTextView());
System.out.println(board.toString());
assertEquals(Config.Faction.BLUE, board.getLongestRoadFaction(factionList));
assertEquals(5, board.getLongestRoadLength());

View File

@ -20,7 +20,21 @@ import java.util.List;
*
*/
/**
* @class SiedlerGameTest
*
* contains all of the test cases for SiedlerGame class.
* The Test cases are categorized into
* - Positive TestCases
* Tests the methods of SiedlerGame with the intended values
*
* - Negative TestCases
* Tests the methods of SiedlerGame with values, that results to errors and failure
*
* - SystemTestCases
* Tests the coordination of all methods and simulates a game with all moves programmed
* Checks if the methods are being executed and the values are set correctly
*/
public class SiedlerGameTest {
private final static int DEFAULT_WINPOINTS = 5;
@ -40,7 +54,7 @@ public class SiedlerGameTest {
);
/**
* START_ROADS_POSITION
* Property 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
@ -92,16 +106,15 @@ public class SiedlerGameTest {
@Test
@DisplayName("Test")
public void TestHandle7() {
SiedlerGame game = startGame();
//todo
}
}
/**
* @Class NegtiveTestcases
* @Class NegAtiveTestcases
*
* This class contains all negative test cases
* contains all negative test cases
*/
@Nested
@DisplayName("Negative test cases")
@ -190,7 +203,7 @@ public class SiedlerGameTest {
class SystemTestcases {
/**
* This will test if the players can place initial settlements and roads
* TestS if the players can place initial settlements and roads
*/
@Test
@DisplayName("2 Players initialize a settlement and position")
@ -216,7 +229,21 @@ public class SiedlerGameTest {
public void TestGameAfterSetupPhase() {
SiedlerGame game = gameAfterSetupPhase();
System.out.println(game.getBoard().toString());
throwDiceSeveralTimes(game, 5, 5);
throwDiceSeveralTimes(game, 5, 5);
throwDiceSeveralTimes(game, 5, 5);
throwDiceSeveralTimes(game, 5, 5);
throwDiceSeveralTimes(game, 5, 5);
//game.switchToNextPlayer();
//throwDiceSeveralTimes(game, 6, 5);
//throwDiceSeveralTimes(game, 6, 5);
//throwDiceSeveralTimes(game, 6, 5);
//throwDiceSeveralTimes(game, 6, 5);
//throwDiceSeveralTimes(game, 6, 5);
soutDistribution(game);
}
@ -234,9 +261,9 @@ public class SiedlerGameTest {
//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()) {
for (int i = 0 ; i < game.getPlayerFactions().size(); i++) {
HashMap<Config.Resource, Integer> resources = game.getCurrentPlayerResource();
System.out.println(faction.toString() + "\n");
System.out.println(game.getCurrentPlayerFaction().toString() + "\n");
System.out.println(" BRICK " + resources.get(Config.Resource.BRICK).toString());
System.out.println(" GRAIN " + resources.get(Config.Resource.GRAIN));
System.out.println(" LUMBER " + resources.get(Config.Resource.LUMBER));
@ -284,6 +311,8 @@ public class SiedlerGameTest {
game.placeInitialRoad(secondRoad.first, secondRoad.second);
}
System.out.println(game.getBoard().toString());
return game;
}
@ -295,8 +324,10 @@ public class SiedlerGameTest {
* @param amountDiceThrows Type int, The amount of dice throws
*/
private static void throwDiceSeveralTimes(SiedlerGame game, int dice, int amountDiceThrows) {
//System.out.println(game.getCurrentPlayerFaction().toString() + " got " + dice + " and throw " + amountDiceThrows + " times");
for (int i = 0; i < amountDiceThrows; i++) {
System.out.println(game.getCurrentPlayerFaction().toString());
game.throwDice(dice);
}
}