Merge remote-tracking branch 'origin/main' into main

This commit is contained in:
MikeZyeman 2021-12-09 16:15:09 +01:00
commit f3b9cd2771
10 changed files with 95 additions and 63 deletions

View File

@ -23,4 +23,35 @@ at 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 For a more detailed version of the rules please look here: https://www.catan.de/sites/prod/files/2021-06/CATAN_DasSpiel_Spielregel.pdf
#Usermanual #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
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 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 the program will check if those coordinates are available or not. Then the
program will subtract the resources needed to build a settlement. If the player has
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
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
built at. If the coordinates are available and the settlement at that coordinate is
of the same faction as the player then the city can be built there. The program
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
build road

View File

@ -5,7 +5,7 @@ import ch.zhaw.hexboard.Label;
public class Field { public class Field {
private Config.Land land; private Config.Land land;
private Label label; private final Label label;
public Field(Config.Land land, Label label){ public Field(Config.Land land, Label label){
this.land = land; this.land = land;

View File

@ -4,11 +4,9 @@ import org.beryx.textio.TextIO;
import org.beryx.textio.TextIoFactory; import org.beryx.textio.TextIoFactory;
import org.beryx.textio.TextTerminal; import org.beryx.textio.TextTerminal;
import java.awt.*; import java.awt.Point;
import java.util.HashMap; import java.util.HashMap;
import static ch.zhaw.catan.Command.*;
/** /**
* This class performs all communication with the player, includes asking for input and showing the map. * This class performs all communication with the player, includes asking for input and showing the map.
* *

View File

@ -2,7 +2,7 @@ package ch.zhaw.catan;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
//TODO Java Doc bearbeiten
/** /**
* New Class PLayer * New Class PLayer
* This class is here in order to maintain the resources of the players, the amount of structures that they can build, * This class is here in order to maintain the resources of the players, the amount of structures that they can build,
@ -10,9 +10,9 @@ import java.util.List;
*/ */
public class Player { public class Player {
private Config.Faction faction; private final Config.Faction faction;
private HashMap<Config.Resource, Integer> resources; private final HashMap<Config.Resource, Integer> resources;
private HashMap<Config.Structure, Integer> structureToUse; private final HashMap<Config.Structure, Integer> structureToUse;
/** /**
* The constructor creates a new instance of the player class that initializes the Hashmap resources and structureToUse. * The constructor creates a new instance of the player class that initializes the Hashmap resources and structureToUse.
@ -63,7 +63,7 @@ public class Player {
} }
/** /**
* This method adds a specific resource to resourcess * This method adds a specific resource to resources
* *
* @param resource to add * @param resource to add
* @param numberToAdd how much to add * @param numberToAdd how much to add
@ -90,7 +90,7 @@ public class Player {
/** /**
* This method has to be used when a player wants to build a structure. It checks if a player has enough of the specific structure * This method has to be used when a player wants to build a structure. It checks if a player has enough of the specific structure
* and resources to build one more. If the player is able to build, this method subtracts the buildcost from the resources * and resources to build one more. If the player is able to build, this method subtracts the building cost from the resources
* in possession by the player. * in possession by the player.
* It reduces the amount of the specific structure a player can build by 1. * It reduces the amount of the specific structure a player can build by 1.
* @return true if the structure can be created false if the structure can't be created. * @return true if the structure can be created false if the structure can't be created.

View File

@ -1,7 +1,7 @@
package ch.zhaw.catan; package ch.zhaw.catan;
import java.awt.Point; import java.awt.Point;
/// TODO: 09/12/2021 Java Doc
public class Road extends Structure { public class Road extends Structure {
private final Point start,end; private final Point start,end;

View File

@ -1,7 +1,7 @@
package ch.zhaw.catan; package ch.zhaw.catan;
import java.awt.*; import java.awt.Point;
//TODO Java Doc
public class Settlement extends Structure { public class Settlement extends Structure {
private Point position; private Point position;

View File

@ -4,7 +4,7 @@ import java.util.HashMap;
import java.util.Random; import java.util.Random;
/** /**
* This Class manages the game process and contains the Main Method wich creates and starts a new Parser and a new Game. * This Class manages the game process and contains the Main Method which creates and starts a new Parser and a new Game.
*/ */
public class Siedler { public class Siedler {
/** /**
@ -20,7 +20,7 @@ public class Siedler {
/** /**
* The Method for the usual game Process. It contains the Main loop to get new commands from the players and calls the associated methods. * The Method for the usual game Process. It contains the Main loop to get new commands from the players and calls the associated methods.
* @param parser The Parser Object which will interact with the player. * @param parser The Parser Object which will interact with the player.
* @param game The Game object which is already created and has the foundig phase completed. * @param game The Game object which is already created and has the founding phase completed.
*/ */
private static void gamePhase(Parser parser, SiedlerGame game) { private static void gamePhase(Parser parser, SiedlerGame game) {
boolean running = true; boolean running = true;
@ -33,7 +33,7 @@ public class Siedler {
throwDice(parser, game); throwDice(parser, game);
diceThrown = true; diceThrown = true;
} }
parser.displayPlayerInfo(game.getCurrentPlayerResource(), game.getCurrentPlayerWinpoints()); parser.displayPlayerInfo(game.getCurrentPlayerResource(), game.getCurrentPlayerWinPoints());
switch (parser.getAction()) { switch (parser.getAction()) {
case NEXTPLAYER: case NEXTPLAYER:
if(caseNextPlayer(parser, game)){ if(caseNextPlayer(parser, game)){
@ -145,7 +145,7 @@ public class Siedler {
} }
} }
//each Player bilds their second Settlement and second Road and gets a Payout for these Structures in usual order. //each Player builds their second Settlement and second Road and gets a Payout for these Structures in usual order.
for(int player = 1; player <= gameInfo.get("NumberOfPlayers"); player++){ for(int player = 1; player <= gameInfo.get("NumberOfPlayers"); player++){
buildStructuresInFoundingPhase(parser, game, true); buildStructuresInFoundingPhase(parser, game, true);
game.switchToNextPlayer(); game.switchToNextPlayer();
@ -157,7 +157,7 @@ public class Siedler {
* The Method is called by foundingPhase. It prompts the Player to build a Settlement and a Road. * The Method is called by foundingPhase. It prompts the Player to build a Settlement and a Road.
* @param parser The parser Object which will interact with the player. * @param parser The parser Object which will interact with the player.
* @param game The game Object which will be used to execute the Method. * @param game The game Object which will be used to execute the Method.
* @param payout true (for second Settlement in founding Phase): the Player gets a payout for the settlment. false (for first Settlement in founding Phase): The Player gets no payout. * @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){ private static void buildStructuresInFoundingPhase(Parser parser, SiedlerGame game, Boolean payout){
parser.displayGameboard(game.getBoard().getTextView()); parser.displayGameboard(game.getBoard().getTextView());
@ -165,27 +165,27 @@ public class Siedler {
//build Settlement //build Settlement
parser.giveCoordinatesForStructures(Config.Structure.SETTLEMENT); parser.giveCoordinatesForStructures(Config.Structure.SETTLEMENT);
boolean sucessful = false; boolean successful = false;
do{ do{
if(game.placeInitialSettlement(parser.getPoint(), payout)) { if(game.placeInitialSettlement(parser.getPoint(), payout)) {
sucessful = true; successful = true;
} }
else{ else{
parser.errorMessage(); parser.errorMessage();
} }
} while(!sucessful); } while(!successful);
//build Road //build Road
parser.displayGameboard(game.getBoard().getTextView()); parser.displayGameboard(game.getBoard().getTextView());
parser.giveCoordinatesForStructures(Config.Structure.ROAD); parser.giveCoordinatesForStructures(Config.Structure.ROAD);
sucessful = false; successful = false;
do{ do{
if(game.placeInitialRoad(parser.getPoint(), parser.getPoint())) { if(game.placeInitialRoad(parser.getPoint(), parser.getPoint())) {
sucessful = true; successful = true;
} }
else{ else{
parser.errorMessage(); parser.errorMessage();
} }
} while(!sucessful); } while(!successful);
} }
} }

View File

@ -6,16 +6,17 @@ import ch.zhaw.hexboard.Label;
import java.awt.Point; import java.awt.Point;
import java.util.*; import java.util.*;
//TODO Enhance JavaDoc
/** /**
* Subclass of HexBoard * Subclass of HexBoard
* Saves the fields wich are set and handels Methods with specific Dice Numbers * Saves the fields which are set and handles Methods with specific Dice Numbers.
*/ */
public class SiedlerBoard extends HexBoard<Land, Settlement, Road, String> { public class SiedlerBoard extends HexBoard<Land, Settlement, Road, String> {
/** /**
* HashMap to save all Fields which are set yet. * HashMap to save all Fields which are set yet.
* Key: Point with coordinates of the field * Key: Point with coordinates of the field
* //TODO Enhance JavaDoc
* Value: Field Object * Value: Field Object
*/ */
HashMap<Point, Field> fields = new HashMap<>(); HashMap<Point, Field> fields = new HashMap<>();
@ -81,13 +82,13 @@ public class SiedlerBoard extends HexBoard<Land, Settlement, Road, String> {
} }
/** /**
* Method to get the Resources which are payed to a specific faction for a specific field. * Method to get the Resources which are paid to a specific faction for a specific field.
* *
* @param point The Point with the Coordinates of the field, which should pay resources. * @param point The Point with the Coordinates of the field, which should pay resources.
* @param faction The faction, which should get paied. * @param faction The faction, which should get paid.
* @return a ArrayList with all resources, which will be paied to the specified faction. * @return a ArrayList with all resources, which will be paid to the specified faction.
*/ */
public ArrayList<Config.Resource> getResourcesforFaction(Point point, Config.Faction faction){ public ArrayList<Config.Resource> getResourcesForFaction(Point point, Config.Faction faction){
List <Settlement> possibleSettlementField = super.getCornersOfField(point); List <Settlement> possibleSettlementField = super.getCornersOfField(point);
ArrayList<Config.Resource> resourcesToPlayer = new ArrayList<>(); ArrayList<Config.Resource> resourcesToPlayer = new ArrayList<>();
for (Settlement settlement : possibleSettlementField) { for (Settlement settlement : possibleSettlementField) {

View File

@ -2,11 +2,8 @@ package ch.zhaw.catan;
import ch.zhaw.catan.Config.Land; import ch.zhaw.catan.Config.Land;
import ch.zhaw.hexboard.HexBoardTextView; import ch.zhaw.hexboard.HexBoardTextView;
import ch.zhaw.hexboard.Label;
import java.awt.*;
import java.util.Set;
//TODO Java Docs
public class SiedlerBoardTextView extends HexBoardTextView<Land, Settlement, Road, String> { public class SiedlerBoardTextView extends HexBoardTextView<Land, Settlement, Road, String> {
public SiedlerBoardTextView(SiedlerBoard board) { public SiedlerBoardTextView(SiedlerBoard board) {

View File

@ -3,9 +3,14 @@ package ch.zhaw.catan;
import ch.zhaw.catan.Config.Faction; import ch.zhaw.catan.Config.Faction;
import ch.zhaw.catan.Config.Resource; import ch.zhaw.catan.Config.Resource;
import java.awt.*; import java.awt.Point;
import java.util.*; import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Random;
import java.util.Iterator;
import java.util.HashSet;
/** /**
@ -77,7 +82,7 @@ public class SiedlerGame {
activePlayer = allPlayers.size()-1; activePlayer = allPlayers.size()-1;
} }
} }
//TODO JavaDoc
private boolean addResourcesToPlayer(Player player, Resource resource, int numberToAdd){ private boolean addResourcesToPlayer(Player player, Resource resource, int numberToAdd){
if(bank.getResourceFromBank(resource, numberToAdd)){ if(bank.getResourceFromBank(resource, numberToAdd)){
player.addResource(resource, numberToAdd); player.addResource(resource, numberToAdd);
@ -85,10 +90,10 @@ public class SiedlerGame {
} }
return false; return false;
} }
//TODO JavaDoc
private boolean substractResourceFromPlayer(Player player, Resource resource, int numberToSubstract){ private boolean subtractResourceFromPlayer(Player player, Resource resource, int numberToSubtract){
if(player.substractResource(resource, numberToSubstract)){ if(player.substractResource(resource, numberToSubtract)){
bank.storeResourceToBank(resource, numberToSubstract); bank.storeResourceToBank(resource, numberToSubtract);
return true; return true;
} }
return false; return false;
@ -212,21 +217,21 @@ public class SiedlerGame {
* cards of a certain type (relevant if there are not enough left in the bank). * cards of a certain type (relevant if there are not enough left in the bank).
* </p> * </p>
* *
* @param dicethrow the resource cards that have been distributed to the players * @param diceThrow the resource cards that have been distributed to the players
* @return the resource cards added to the stock of the different players * @return the resource cards added to the stock of the different players
*/ */
public Map<Faction, List<Resource>> throwDice(int dicethrow) { public Map<Faction, List<Resource>> throwDice(int diceThrow) {
if (dicethrow == 7) { if (diceThrow == 7) {
for(Player player : allPlayers) { for(Player player : allPlayers) {
handleDiceThrow7(player); handleDiceThrow7(player);
} }
} else { } else {
Map<Faction,List<Resource>> returnMap= new HashMap<>(); Map<Faction,List<Resource>> returnMap= new HashMap<>();
List<Point> diceValueFields = board.getFieldsForDiceValue(dicethrow); List<Point> diceValueFields = board.getFieldsForDiceValue(diceThrow);
for (Player player : allPlayers) { for (Player player : allPlayers) {
returnMap.put(player.getFaction(), new ArrayList<>()); returnMap.put(player.getFaction(), new ArrayList<>());
for (Point field : diceValueFields) { for (Point field : diceValueFields) {
List<Resource> resources = board.getResourcesforFaction(field,player.getFaction()); List<Resource> resources = board.getResourcesForFaction(field,player.getFaction());
for (Config.Resource resource : resources){ for (Config.Resource resource : resources){
returnMap.get(player.getFaction()).add(resource); returnMap.get(player.getFaction()).add(resource);
addResourcesToPlayer(player, resource, 1); addResourcesToPlayer(player, resource, 1);
@ -237,7 +242,7 @@ public class SiedlerGame {
} }
return null; return null;
} }
//TODO JavaDoc
public void handleDiceThrow7(Player player) { public void handleDiceThrow7(Player player) {
ArrayList<Config.Resource> resourceArrayList = new ArrayList<>(); ArrayList<Config.Resource> resourceArrayList = new ArrayList<>();
HashMap<Resource, Integer> resources = player.getResources(); HashMap<Resource, Integer> resources = player.getResources();
@ -250,7 +255,7 @@ public class SiedlerGame {
int resourcesToRemove =resourceArrayList.size() - (resourceArrayList.size() / 2); int resourcesToRemove =resourceArrayList.size() - (resourceArrayList.size() / 2);
Random random = new Random(); Random random = new Random();
for(int i = 0; i < resourcesToRemove; i++){ for(int i = 0; i < resourcesToRemove; i++){
substractResourceFromPlayer(player, resourceArrayList.remove(random.nextInt(resourceArrayList.size())), 1); subtractResourceFromPlayer(player, resourceArrayList.remove(random.nextInt(resourceArrayList.size())), 1);
} }
} }
} }
@ -286,7 +291,7 @@ public class SiedlerGame {
List<Config.Resource> costs = Config.Structure.SETTLEMENT.getCosts(); List<Config.Resource> costs = Config.Structure.SETTLEMENT.getCosts();
for (Config.Resource resource : costs) { for (Config.Resource resource : costs) {
substractResourceFromPlayer(allPlayers.get(activePlayer), resource, 1); subtractResourceFromPlayer(allPlayers.get(activePlayer), resource, 1);
} }
//4. Insert Settlement to map //4. Insert Settlement to map
@ -324,7 +329,7 @@ public class SiedlerGame {
List<Config.Resource> costs = Config.Structure.CITY.getCosts(); List<Config.Resource> costs = Config.Structure.CITY.getCosts();
for (Config.Resource resource : costs) { for (Config.Resource resource : costs) {
substractResourceFromPlayer(allPlayers.get(activePlayer), resource, 1); subtractResourceFromPlayer(allPlayers.get(activePlayer), resource, 1);
} }
//4.Insert City into the map. //4.Insert City into the map.
@ -359,7 +364,7 @@ public class SiedlerGame {
List<Config.Resource> costs = Config.Structure.ROAD.getCosts(); List<Config.Resource> costs = Config.Structure.ROAD.getCosts();
for (Config.Resource resource : costs) { for (Config.Resource resource : costs) {
substractResourceFromPlayer(allPlayers.get(activePlayer), resource, 1); subtractResourceFromPlayer(allPlayers.get(activePlayer), resource, 1);
} }
//3. Insert Road to map //3. Insert Road to map
@ -371,19 +376,19 @@ public class SiedlerGame {
/** /**
* This Method is used to check if the chosen position for a road is valid or not. * This Method is used to check if the chosen position for a road is valid or not.
* @param roadStart the coordinates where the road begins. * @param roadStart the coordinates where the road begins.
* @param roadEnd the coordinates where the roads ends. * @param roadEnd the coordinates where the road ends.
* @return true if road position is valid otherwise false * @return true if road position is valid otherwise false
*/ */
private boolean validPositionForRoad(Point roadStart, Point roadEnd){ private boolean validPositionForRoad(Point roadStart, Point roadEnd){
//1. Check if Edge //1. Check if it is an edge
if (!board.hasEdge(roadStart, roadEnd)) { if (!board.hasEdge(roadStart, roadEnd)) {
return false; return false;
} }
//2. Check if Edge is empty //2. Check if edge is empty
if (board.getEdge(roadStart, roadEnd) != null) { if (board.getEdge(roadStart, roadEnd) != null) {
return false; return false;
} }
//3. Check if NeighbourEdge are Roads //3. Check if neighbouring edges are roads
boolean hasNeighbourRoad = (checkAdjacentEdgesList(roadStart) || checkAdjacentEdgesList(roadEnd)); boolean hasNeighbourRoad = (checkAdjacentEdgesList(roadStart) || checkAdjacentEdgesList(roadEnd));
if(hasNeighbourRoad) { if(hasNeighbourRoad) {
return true; return true;
@ -399,7 +404,7 @@ public class SiedlerGame {
* @return true if valid position for settlement * @return true if valid position for settlement
*/ */
private boolean validPositionForSettlement(Point position){ private boolean validPositionForSettlement(Point position){
//1. Check if Corner //1. Check if corner
if (!board.hasCorner(position)) { if (!board.hasCorner(position)) {
return false; return false;
} }
@ -407,11 +412,11 @@ public class SiedlerGame {
if(checkIfWater(position)) { if(checkIfWater(position)) {
return false; return false;
} }
//3. Check if Corner is empty //3. Check if corner is empty
if(board.getCorner(position) != null) { if(board.getCorner(position) != null) {
return false; return false;
} }
//3. Check if neighbourCorners are empty //3. Check if neighbouring corners are empty
return checkAdjacentCornerList(position); return checkAdjacentCornerList(position);
} }
@ -464,7 +469,7 @@ public class SiedlerGame {
public boolean tradeWithBankFourToOne(Resource offer, Resource want) { public boolean tradeWithBankFourToOne(Resource offer, Resource want) {
Player player = allPlayers.get(activePlayer); Player player = allPlayers.get(activePlayer);
if(player.getSpecificResource(offer) >= FOUR_TO_ONE_TRADE_OFFER && addResourcesToPlayer(player, want, FOUR_TO_ONE_TRADE_WANT)){ if(player.getSpecificResource(offer) >= FOUR_TO_ONE_TRADE_OFFER && addResourcesToPlayer(player, want, FOUR_TO_ONE_TRADE_WANT)){
substractResourceFromPlayer(player, offer, FOUR_TO_ONE_TRADE_OFFER); subtractResourceFromPlayer(player, offer, FOUR_TO_ONE_TRADE_OFFER);
return true; return true;
} }
return false; return false;
@ -476,13 +481,13 @@ public class SiedlerGame {
* @return the winner of the game or null, if there is no winner (yet) * @return the winner of the game or null, if there is no winner (yet)
*/ */
public Faction getWinner() { public Faction getWinner() {
if(getCurrentPlayerWinpoints() >= winPointsForWin){ if(getCurrentPlayerWinPoints() >= winPointsForWin){
return getCurrentPlayerFaction(); return getCurrentPlayerFaction();
} }
return null; return null;
} }
//Todo Java Doc
public int getCurrentPlayerWinpoints(){ public int getCurrentPlayerWinPoints(){
int winPoints = 0; int winPoints = 0;
List<Settlement> settlements = board.getCorners(); List<Settlement> settlements = board.getCorners();
for(Structure structure : settlements) { for(Structure structure : settlements) {
@ -515,7 +520,7 @@ public class SiedlerGame {
* placed there (e.g., on water) * placed there (e.g., on water)
*/ */
public boolean placeThiefAndStealCard(Point field) { public boolean placeThiefAndStealCard(Point field) {
//TODO: Implement (or longest road functionality) // Implemented longest road.
return false; return false;
} }