diff --git a/.gitignore b/.gitignore index 6a3417b..a425ad5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,80 @@ +<<<<<<< HEAD /out/ +======= +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf +misc.xml +SiedlerBoard.class + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser +>>>>>>> origin/main diff --git a/.idea/.gitignore b/.idea/.gitignore index 0047fc0..2367661 100644 --- a/.idea/.gitignore +++ b/.idea/.gitignore @@ -5,4 +5,6 @@ /dataSources/ /dataSources.local.xml # Editor-based HTTP Client requests -/httpRequests/ \ No newline at end of file +/httpRequests/ +/misc.xml +/out/ \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 797acea..0000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Config$Faction.class b/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Config$Faction.class deleted file mode 100644 index d312fff..0000000 Binary files a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Config$Faction.class and /dev/null differ diff --git a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Config$Land.class b/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Config$Land.class deleted file mode 100644 index 2a20065..0000000 Binary files a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Config$Land.class and /dev/null differ diff --git a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Config$Resource.class b/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Config$Resource.class deleted file mode 100644 index 58f80c1..0000000 Binary files a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Config$Resource.class and /dev/null differ diff --git a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Config$Structure.class b/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Config$Structure.class deleted file mode 100644 index 169ab41..0000000 Binary files a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Config$Structure.class and /dev/null differ diff --git a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Config.class b/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Config.class deleted file mode 100644 index 922ab81..0000000 Binary files a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Config.class and /dev/null differ diff --git a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Dummy$1.class b/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Dummy$1.class deleted file mode 100644 index f4062e0..0000000 Binary files a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Dummy$1.class and /dev/null differ diff --git a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Dummy$Actions.class b/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Dummy$Actions.class deleted file mode 100644 index 3410db7..0000000 Binary files a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Dummy$Actions.class and /dev/null differ diff --git a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Dummy.class b/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Dummy.class deleted file mode 100644 index d1759cf..0000000 Binary files a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/Dummy.class and /dev/null differ diff --git a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/SiedlerBoard.class b/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/SiedlerBoard.class deleted file mode 100644 index ae45f03..0000000 Binary files a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/SiedlerBoard.class and /dev/null differ diff --git a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/SiedlerBoardTextView.class b/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/SiedlerBoardTextView.class deleted file mode 100644 index fd38f02..0000000 Binary files a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/SiedlerBoardTextView.class and /dev/null differ diff --git a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/SiedlerGame.class b/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/SiedlerGame.class deleted file mode 100644 index 1abbc24..0000000 Binary files a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/catan/SiedlerGame.class and /dev/null differ diff --git a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/hexboard/Edge.class b/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/hexboard/Edge.class deleted file mode 100644 index a034cf4..0000000 Binary files a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/hexboard/Edge.class and /dev/null differ diff --git a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/hexboard/FieldAnnotationPosition.class b/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/hexboard/FieldAnnotationPosition.class deleted file mode 100644 index 50b3008..0000000 Binary files a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/hexboard/FieldAnnotationPosition.class and /dev/null differ diff --git a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/hexboard/HexBoard.class b/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/hexboard/HexBoard.class deleted file mode 100644 index 54b55a6..0000000 Binary files a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/hexboard/HexBoard.class and /dev/null differ diff --git a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/hexboard/HexBoardTextView.class b/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/hexboard/HexBoardTextView.class deleted file mode 100644 index d987cad..0000000 Binary files a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/hexboard/HexBoardTextView.class and /dev/null differ diff --git a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/hexboard/Label.class b/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/hexboard/Label.class deleted file mode 100644 index 3dd5342..0000000 Binary files a/out/production/gruppe06-hufflepuff-projekt3-catan/ch/zhaw/hexboard/Label.class and /dev/null differ diff --git a/src/ch/zhaw/catan/Bank.java b/src/ch/zhaw/catan/Bank.java new file mode 100644 index 0000000..2bb84d7 --- /dev/null +++ b/src/ch/zhaw/catan/Bank.java @@ -0,0 +1,43 @@ +package ch.zhaw.catan; + +import java.util.List; +import java.util.Map; + +public class Bank { + private Map resources; + + public Bank(){ + resources = Config.INITIAL_RESOURCE_CARDS_BANK; + + } + + public void storeResourceToBank(List resourceToGive) { + for (Config.Resource resource : resourceToGive) { + resources.put(resource,resources.get(resource)+1); + } + } + + public boolean getResourceFromBank(Config.Resource resource,int numberOfResources) { + if(resources.get(resource) >= numberOfResources) { + Integer newResourceNumber = resources.get(resource) - numberOfResources; + resources.put(resource, newResourceNumber); + return true; + } + else { + return false; + } + } + + public boolean tradeWithBank(Config.Resource resourceToReceive, Config.Resource resourceToGive, int toWant, int toGive) { + if(resources.get(resourceToReceive) >= toWant){ + Integer newResourceReceived = resources.get(resourceToReceive) + toGive; + Integer newResourcesGiven = resources.get(resourceToGive) - toWant; + resources.put(resourceToReceive, newResourceReceived); + resources.put(resourceToGive, newResourcesGiven); + return true; + } + else{ + return false; + } + } +} diff --git a/src/ch/zhaw/catan/City.java b/src/ch/zhaw/catan/City.java new file mode 100644 index 0000000..499bf87 --- /dev/null +++ b/src/ch/zhaw/catan/City.java @@ -0,0 +1,12 @@ +package ch.zhaw.catan; + +public class City extends Settlement { + + public City(Config.Faction faction) { + super(faction); + } + + public String toString() { + return super.getFaction().toString().toUpperCase(); + } +} diff --git a/src/ch/zhaw/catan/Command.java b/src/ch/zhaw/catan/Command.java new file mode 100644 index 0000000..7e7b24e --- /dev/null +++ b/src/ch/zhaw/catan/Command.java @@ -0,0 +1,20 @@ +package ch.zhaw.catan; + +import org.beryx.textio.TextIO; + +public enum Command { + NEXTPLAYER ("next player"), BUILDSETTLEMENT ("build settlement"), BUILDCITY("build city"), + BUILDROAD("build road"), TRADEWITHBANK("trade with bank"),QUIT("quit"); + + private String commandWord; + + + + + Command(String commandWord) { + this.commandWord = commandWord; + } + public String toString() { + return commandWord; + } +} diff --git a/src/ch/zhaw/catan/Dummy.java b/src/ch/zhaw/catan/Dummy.java index fdcab53..ca1bbe2 100644 --- a/src/ch/zhaw/catan/Dummy.java +++ b/src/ch/zhaw/catan/Dummy.java @@ -15,15 +15,13 @@ public class Dummy { SHOW, QUIT } - private void run() { TextIO textIO = TextIoFactory.getTextIO(); TextTerminal textTerminal = textIO.getTextTerminal(); - SiedlerBoard board = new SiedlerBoard(); board.addField(new Point(2, 2), Land.FOREST); - board.setCorner(new Point(3, 3), "RR"); - board.setEdge(new Point(2, 0), new Point(3, 1), "r"); + board.setCorner(new Point(3, 3), new Settlement(Config.Faction.RED)); + board.setEdge(new Point(2, 0), new Point(3, 1), new Road(Config.Faction.BLUE)); board.addFieldAnnotation(new Point(2, 2), new Point(3, 1), "AA"); Map lowerFieldLabel = new HashMap<>(); diff --git a/src/ch/zhaw/catan/Field.java b/src/ch/zhaw/catan/Field.java new file mode 100644 index 0000000..1da46c7 --- /dev/null +++ b/src/ch/zhaw/catan/Field.java @@ -0,0 +1,26 @@ +package ch.zhaw.catan; + +import ch.zhaw.hexboard.Label; + +public class Field { + + private Config.Land land; + private Label label; + + public Field(Config.Land land, Label label){ + this.land = land; + this.label = label; + } + + public Config.Resource getResource(){ + return land.getResource(); + } + + public Config.Land getLand() { + return land; + } + + public Label getLabel() { + return label; + } +} diff --git a/src/ch/zhaw/catan/Parser.java b/src/ch/zhaw/catan/Parser.java new file mode 100644 index 0000000..b298b74 --- /dev/null +++ b/src/ch/zhaw/catan/Parser.java @@ -0,0 +1,88 @@ +package ch.zhaw.catan; +import org.beryx.textio.TextIO; +import org.beryx.textio.TextIoFactory; +import org.beryx.textio.TextTerminal; + +import java.awt.*; +import java.util.HashMap; + +import static ch.zhaw.catan.Command.*; + +public class Parser { + TextIO textIO = TextIoFactory.getTextIO(); + TextTerminal textTerminal; + + public Parser() { + textTerminal = textIO.getTextTerminal(); + } + + public Point getPoint() { + return new Point(textIO.newIntInputReader().withMinVal(0).read("x coordinate:"), + textIO.newIntInputReader().withMinVal(0).read("y coordinate:")); + } + + public void displayGameboard(String gameboard) { + textTerminal.println(gameboard); + } + + public void displayPlayerInfo(HashMap currentPlayerResource, int winpoints){ + textTerminal.println("You are currently holding " + winpoints + " winpoints."); + textTerminal.println("You own the follwing resources:"); + for(Config.Resource resource : currentPlayerResource.keySet()){ + textTerminal.println(resource.name() + ":" + currentPlayerResource.get(resource)); + } + } + + public void displayWinnertext(Config.Faction winner){ + textTerminal.println(winner.name() + " won the game!"); + } + + public HashMap gameStart(){ + HashMap gameStartValues = new HashMap<>(); + gameStartValues.put("NumberOfPlayers", textIO.newIntInputReader().withMinVal(2).withMaxVal(4).read("Number of players:")); + gameStartValues.put("NumberOfWinPoints", textIO.newIntInputReader().withMinVal(5).withMaxVal(15).read("Winpoints needed for Victory:")); + return gameStartValues; + } + + public void giveCoordinatesForStructures(Config.Structure structure) { + textTerminal.println("Please insert coordinates for " + structure); + if(structure == Config.Structure.ROAD) { + textTerminal.println("Please first insert the start coordinate and when prompted again the coordinate of the end of the road."); + } + } + + public void thrownDices(int number){ + textTerminal.println ("Dices have been thrown, the combined value is: " + number); + } + + public void playerTurn(Config.Faction faction) { + textTerminal.println("It is " + faction.name() + "'s turn."); + } + + public void errorMessage(){ + textTerminal.println("The command was not excecuted successfully!"); + } + + public Command getAction() { + return textIO.newEnumInputReader(Command.class).read("What would you like to do?"); + } + + /** + * + * @param give if true ask for resource to give if false for resource to receive + * @return + */ + public Config.Resource trade(boolean give) { + String output = "give"; + if (!give){ + output = "receive"; + } + return textIO.newEnumInputReader(Config.Resource.class).read("Which Resource would you like to " + output ); + } + public void quit(){ + textTerminal.dispose(); + textIO.dispose(); + } + +} + diff --git a/src/ch/zhaw/catan/Player.java b/src/ch/zhaw/catan/Player.java new file mode 100644 index 0000000..2011fe8 --- /dev/null +++ b/src/ch/zhaw/catan/Player.java @@ -0,0 +1,138 @@ +package ch.zhaw.catan; + +import java.util.HashMap; +import java.util.List; + +/** + * New Class PLayer + * This class is here to add players to the game. + */ +public class Player { + + private Config.Faction faction; + private HashMap resources; + private int roadsToUse; + private int settlementsToUse; + private int citiesToUse; + + public Player (Config.Faction faction){ + //Datenfelder + this.faction = faction; + roadsToUse = Config.Structure.ROAD.getStockPerPlayer(); + settlementsToUse = Config.Structure.SETTLEMENT.getStockPerPlayer(); + //Ressourcen initialisiern + resources = new HashMap<>(); + for(Config.Resource resource : Config.Resource.values()) { + resources.put(resource,0); + } + + } + + /** + * This method returns all the resources the player has at the moment + * @return HashMap with the count of every resource + */ + public HashMap getResources() { + return resources; + } + + /** + * This method returns player faction + * @return + */ + public Config.Faction getFaction() { return faction; } + + /** + * This method returns for specific resource how much player possesess. + * @param resource + * @return + */ + public int getSpecificResource(Config.Resource resource) { return resources.get(resource); } + + /** + * This method adds a specific resource to resourcess + * @param resource to add + * @param numberToAdd how much to add + */ + public void addResource(Config.Resource resource, int numberToAdd) { + resources.put(resource, resources.get(resource) + numberToAdd); + } + + /** + * This method substracts a specific resource from resourcess but check first if player has enough resources. + * @param resource to substract + * @param numberToTake how much to substract + * @return true if resource has been substracted false if player has not enough resources + */ + public boolean substractResource(Config.Resource resource, int numberToTake) { + int inPossesion = resources.get(resource); + if(inPossesion - numberToTake < 0) { + return false; + } + resources.put(resource,inPossesion - numberToTake); + return true; + } + + /** + * This method has to be used when a player wants to build a road. It checks if a player has enough roads + * and resources to build one more. If player is able to build, the method substract the buildcost from the resources + * in possesion by the player. + * @return true if road can be created false if road can't be created + */ + public boolean buildRoad() { + List costs = Config.Structure.ROAD.getCosts(); + if ( roadsToUse == 0 || !checkRessourceToBuild(costs)) { + return false; + } + for (Config.Resource resource : costs) { + resources.put(resource,resources.get(resource)-1); + } + return true; + } + + /** + * This method has to be used when a player wants to build a settlement. It checks if a player has enough roads + * and resources to build one more. If the player is able to build, this method subtracts the buildcost from the resources + * in possession by the player. + * @return true if road can be created false if road can't be created. + */ + public boolean buildSettlement() { + List costs = Config.Structure.SETTLEMENT.getCosts(); + if ( settlementsToUse == 0 || !checkRessourceToBuild(costs)) { + return false; + } + for (Config.Resource resource : costs) { + resources.put(resource,resources.get(resource)-1); + } + return true; + } + + /** + * This method has to be used when a player wants to build a city. It checks if a player already has a settlement + * on that position and if he has enough resource to build one. If the player is able to build, this method subtracts + * the buildcost from the resources in possession by the player. + * @return true if road can be created false if road can't be created. + */ + public boolean buildCity() { + List costs = Config.Structure.CITY.getCosts(); + if ( citiesToUse == 0 || !checkRessourceToBuild(costs)){ + return false; + } + for (Config.Resource resource : costs){ + resources.put(resource,resources.get(resource)-1); + } + return true; + } + + //returns true if player has enough resources else false + private boolean checkRessourceToBuild(List liste) { + for (Config.Resource resource : liste) { + int possesion = resources.get(resource); + if (possesion == 0) { + return false; + } + } + return true; + } + +} diff --git a/src/ch/zhaw/catan/Road.java b/src/ch/zhaw/catan/Road.java index 7ba52c8..5131770 100644 --- a/src/ch/zhaw/catan/Road.java +++ b/src/ch/zhaw/catan/Road.java @@ -1,22 +1,8 @@ package ch.zhaw.catan; -import java.util.HashMap; +public class Road extends Structure { -/** - * This Class represents a Road Object. It informs about the ressources needed to build a road - */ -public class Road { - - final private HashMap buildCost; - - public Road() { - buildCost = new HashMap<>(); - buildCost.put(Config.Resource.LUMBER, 1); - buildCost.put(Config.Resource.BRICK, 1); + public Road(Config.Faction faction) { + super(faction); } - - public HashMap getBuildCost() { - return buildCost; - } - } diff --git a/src/ch/zhaw/catan/Settlement.java b/src/ch/zhaw/catan/Settlement.java new file mode 100644 index 0000000..c70734c --- /dev/null +++ b/src/ch/zhaw/catan/Settlement.java @@ -0,0 +1,8 @@ +package ch.zhaw.catan; + +public class Settlement extends Structure { + + public Settlement(Config.Faction faction) { + super(faction); + } +} diff --git a/src/ch/zhaw/catan/Siedler.java b/src/ch/zhaw/catan/Siedler.java index 9c3ea12..eaee90e 100644 --- a/src/ch/zhaw/catan/Siedler.java +++ b/src/ch/zhaw/catan/Siedler.java @@ -1,20 +1,132 @@ package ch.zhaw.catan; -import org.beryx.textio.TextIO; -import org.beryx.textio.TextIoFactory; -import org.beryx.textio.TextTerminal; +import java.util.HashMap; +import java.util.Random; public class Siedler { public static void main(String[] args) { //Spiel erstellen - SiedlerGame game = new SiedlerGame(0, 0); - - //Spielfeld ausgeben - TextIO textIO = TextIoFactory.getTextIO(); - TextTerminal textTerminal = textIO.getTextTerminal(); - textTerminal.println(game.getBoard().getTextView()); - + Parser parser = new Parser(); + SiedlerGame game = foundingPhase(parser); + boolean running = true; + boolean diceThrown = false; + while (running){ + Config.Faction currentPlayerFaction = game.getCurrentPlayerFaction(); + parser.displayGameboard(game.getBoard().getTextView()); + parser.playerTurn(currentPlayerFaction); + if(!diceThrown) { + throwDice(game, parser); + diceThrown = true; + } + parser.displayPlayerInfo(game.getCurruntPlayerResource(), game.getCurrentPlayerWinpoints()); + switch (parser.getAction()) { + case NEXTPLAYER: + Config.Faction winner = game.getWinner(); + if(winner == null) { + game.switchToNextPlayer(); + diceThrown = false; + } else { + parser.displayWinnertext(winner); + running = false; + } + break; + case BUILDSETTLEMENT: + parser.giveCoordinatesForStructures(Config.Structure.SETTLEMENT); + if(!game.buildSettlement(parser.getPoint())){ + parser.errorMessage(); + } + break; + case BUILDCITY: + parser.giveCoordinatesForStructures(Config.Structure.CITY); + if(!game.buildCity(parser.getPoint())){ + parser.errorMessage(); + } + break; + case BUILDROAD: + parser.giveCoordinatesForStructures(Config.Structure.ROAD); + if(game.buildRoad(parser.getPoint(), parser.getPoint())){ + parser.errorMessage(); + } + break; + case TRADEWITHBANK: + Config.Resource offer = parser.trade(true); + Config.Resource want = parser.trade(false); + if(!game.tradeWithBankFourToOne(offer, want)){ + parser.errorMessage(); + } + break; + case QUIT: + running = false; + parser.quit(); + break; + default: + parser.errorMessage(); + } + } } + + private static void throwDice(SiedlerGame game, Parser parser) { + Random random = new Random(); + //sum of two integers from 0-5 + 2 --> sum of two integers from 1-6 + int thrownDices = random.nextInt(6) + random.nextInt(6) + 2; + //todo check if 7 + parser.thrownDices(thrownDices); + game.throwDice(thrownDices); + } + + + private static SiedlerGame foundingPhase(Parser parser) { + HashMap gameInfo = parser.gameStart(); + SiedlerGame game = new SiedlerGame(gameInfo.get("NumberOfWinPoints"), gameInfo.get("NumberOfPlayers")); + + for(int player = 1; player <= gameInfo.get("NumberOfPlayers"); player++){ + buildStructuresInFoundingPhase(game, parser, false); + if(player < gameInfo.get("NumberOfPlayers")){ + game.switchToPreviousPlayer(); + } + } + + for(int player = 1; player <= gameInfo.get("NumberOfPlayers"); player++){ + buildStructuresInFoundingPhase(game, parser, true); + game.switchToNextPlayer(); + } + return game; + } + + + private static void buildStructuresInFoundingPhase(SiedlerGame game, Parser parser, Boolean payout){ + + parser.displayGameboard(game.getBoard().getTextView()); + parser.playerTurn(game.getCurrentPlayerFaction()); + + + //build Settlement + parser.giveCoordinatesForStructures(Config.Structure.SETTLEMENT); + boolean sucessful = false; + do{ + if(game.placeInitialSettlement(parser.getPoint(), payout)) { + sucessful = true; + } + else{ + parser.errorMessage(); + } + } while(!sucessful); + + //build Road + parser.displayGameboard(game.getBoard().getTextView()); + parser.giveCoordinatesForStructures(Config.Structure.ROAD); + sucessful = false; + do{ + if(game.placeInitialRoad(parser.getPoint(), parser.getPoint())) { + sucessful = true; + } + else{ + parser.errorMessage(); + } + } while(!sucessful); + } + + } diff --git a/src/ch/zhaw/catan/SiedlerBoard.java b/src/ch/zhaw/catan/SiedlerBoard.java index b073e13..864a217 100644 --- a/src/ch/zhaw/catan/SiedlerBoard.java +++ b/src/ch/zhaw/catan/SiedlerBoard.java @@ -5,66 +5,46 @@ import ch.zhaw.hexboard.HexBoard; import ch.zhaw.hexboard.Label; import java.awt.*; -import java.util.*; import java.util.List; +import java.util.*; -public class SiedlerBoard extends HexBoard { +public class SiedlerBoard extends HexBoard { - Map lowerFieldLabel = new HashMap<>(); + Map fields = new HashMap<>(); public void createFixGamefield(){ - Integer[][] waterCoordinates = {{4,2},{6,2},{8,2},{10,2},{3,5},{11,5},{2,8},{12,8},{1,11}, - {13,11},{2,14},{12,14},{3,17},{11,17},{4,20},{6,20},{8,20},{10,20}}; - Integer[][] desertCoordinates = {{7,11}}; - Integer[][] forestCoordinates = {{5,5,6},{10,8,10},{3,11,5},{8,14,3}}; - Integer[][] hillCoordinates = {{5,11,9},{5,17,8},{9,17,11}}; - Integer[][] fieldCoordinates = {{4,8,2},{8,8,5},{11,11,9},{4,14,10}}; - Integer[][] pastureCoordinates = {{7,5,3},{9,5,8},{10,14,12},{7,17,4}}; - Integer[][] mountainCoordinates = {{6,8,4},{9,11,6},{6,14,11}}; - - placeFieldWithoutLabel(Land.WATER, waterCoordinates); - placeFieldWithoutLabel(Land.DESERT, desertCoordinates); - placeFieldWithLabel(Land.FOREST, forestCoordinates); - placeFieldWithLabel(Land.HILLS, hillCoordinates); - placeFieldWithLabel(Land.FIELDS, fieldCoordinates); - placeFieldWithLabel(Land.PASTURE, pastureCoordinates); - placeFieldWithLabel(Land.MOUNTAIN, mountainCoordinates); - - + Map resourcePlacement = Config.getStandardLandPlacement(); + Map dicePlacement = Config.getStandardDiceNumberPlacement(); + for (Map.Entry resourceField : resourcePlacement.entrySet()) { + addField(resourceField.getKey(),resourceField.getValue()); + if(dicePlacement.get(resourceField.getKey()) != null){ + String numberAsString = dicePlacement.get(resourceField.getKey()).toString(); + char[] numbersInChar = numberAsString.toCharArray(); + if (numberAsString.length() < 2) { + fields.put(resourceField.getKey(), new Field(resourceField.getValue(), new Label('0', numbersInChar[0]))); + } + else { + fields.put(resourceField.getKey(), new Field(resourceField.getValue(), new Label(numbersInChar[0],numbersInChar[1]))); + } + } + } } private int getDiceNumber(Point field) { - Label label = lowerFieldLabel.get(field); + Label label = fields.get(field).getLabel(); return Integer.parseInt(label.toString()); } public String getTextView () { SiedlerBoardTextView view = new SiedlerBoardTextView(this); - for (Map.Entry e : lowerFieldLabel.entrySet()) { - view.setLowerFieldLabel(e.getKey(), e.getValue()); + for (Map.Entry field : fields.entrySet()) { + view.setLowerFieldLabel(field.getKey(), field.getValue().getLabel()); } return view.toString(); } - private void placeFieldWithoutLabel(Land fieldType, Integer[][] fieldCoordinates) { - for(Integer[] coordinates : fieldCoordinates) { - addField(new Point(coordinates[0], coordinates[1]), fieldType); - } - } - private void placeFieldWithLabel(Land fieldType, Integer[][] fieldInformation) { - for(Integer[] information : fieldInformation) { - addField(new Point(information[0], information[1]), fieldType); - char[] label = information[2].toString().toCharArray(); - if (label.length == 1) { - lowerFieldLabel.put(new Point(information[0], information[1]), new ch.zhaw.hexboard.Label('0', label[0])); - } else { - lowerFieldLabel.put(new Point(information[0], information[1]), new Label(label[0], label[1])); - } - } - } - //TODO: Add fields, constructors and methods as you see fit. Do NOT change the signature // of the methods below. @@ -77,9 +57,8 @@ public class SiedlerBoard extends HexBoard { * @return the fields associated with the dice value */ public List getFieldsForDiceValue(int dice) { - //TODO: Implement. ArrayList fields = new ArrayList<>(); - for(Point field : lowerFieldLabel.keySet()){ + for(Point field : this.fields.keySet()){ if(getDiceNumber(field) == dice){ fields.add(field); } @@ -87,6 +66,21 @@ public class SiedlerBoard extends HexBoard { return fields; } + + public ArrayList getResourcesforFaction(Point point, Config.Faction faction){ + List possibleSettlementField = super.getCornersOfField(point); + ArrayList resourcesToPlayer = new ArrayList<>(); + for (Structure structure : possibleSettlementField) { + if (structure.getFaction() == faction) { + resourcesToPlayer.add(fields.get(point).getResource()); + if (structure instanceof City) { + resourcesToPlayer.add(fields.get(point).getResource()); + } + } + } + return resourcesToPlayer; + } + /** * Returns the {@link Land}s adjacent to the specified corner. * @@ -94,7 +88,22 @@ public class SiedlerBoard extends HexBoard { * @return the list with the adjacent {@link Land}s */ public List getLandsForCorner(Point corner) { - //TODO: Implement. - return Collections.emptyList(); + Point above = new Point(corner.x, corner.y + 2); + Point below = new Point(corner.x, corner.y -2); + Land[] lands = new Land[3]; + if (hasField(above)) { + lands[0] = getField(above); + lands[1] = getField(new Point(corner.x + 1, corner.y - 1)); + lands[2] = getField(new Point(corner.x - 1, corner.y - 1)); + } + else if (hasField(below)) { + lands[0] = getField(below); + lands[1] = getField(new Point(corner.x + 1, corner.y + 1)); + lands[2] = getField(new Point(corner.x - 1, corner.y + 1)); + } + else { + return Collections.emptyList(); + } + return List.of(lands); } } diff --git a/src/ch/zhaw/catan/SiedlerBoardTextView.java b/src/ch/zhaw/catan/SiedlerBoardTextView.java index 68836b1..ce2ca66 100644 --- a/src/ch/zhaw/catan/SiedlerBoardTextView.java +++ b/src/ch/zhaw/catan/SiedlerBoardTextView.java @@ -5,8 +5,9 @@ import ch.zhaw.hexboard.HexBoardTextView; import ch.zhaw.hexboard.Label; import java.awt.*; +import java.util.Set; -public class SiedlerBoardTextView extends HexBoardTextView { +public class SiedlerBoardTextView extends HexBoardTextView { public SiedlerBoardTextView(SiedlerBoard board) { super(board); diff --git a/src/ch/zhaw/catan/SiedlerGame.java b/src/ch/zhaw/catan/SiedlerGame.java index 64f6632..2b8b00c 100644 --- a/src/ch/zhaw/catan/SiedlerGame.java +++ b/src/ch/zhaw/catan/SiedlerGame.java @@ -2,268 +2,458 @@ package ch.zhaw.catan; import ch.zhaw.catan.Config.Faction; import ch.zhaw.catan.Config.Resource; -import org.beryx.textio.TextIO; -import org.beryx.textio.TextIoFactory; -import org.beryx.textio.TextTerminal; -import java.awt.Point; -import java.util.Collections; +import java.awt.*; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; /** - * This class performs all actions related to modifying the game state. - * + * This class performs all actions related to modifying the game state. + *

* TODO: (your documentation) * * @author TODO - * */ public class SiedlerGame { - static final int FOUR_TO_ONE_TRADE_OFFER = 4; - static final int FOUR_TO_ONE_TRADE_WANT = 1; + static final int FOUR_TO_ONE_TRADE_OFFER = 4; + static final int FOUR_TO_ONE_TRADE_WANT = 1; - SiedlerBoard board; + private SiedlerBoard board; + private ArrayList allPlayers; + private int winPointsForWin; + private Bank bank; + private int activePlayer; - /** - * Constructs a SiedlerGame game state object. - * - * @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 - */ - public SiedlerGame(int winPoints, int numberOfPlayers) { - board = new SiedlerBoard(); - board.createFixGamefield(); - } - - /** - * Switches to the next player in the defined sequence of players. - */ - public void switchToNextPlayer() { - // TODO: Implement - } - - /** - * Switches to the previous player in the defined sequence of players. - */ - public void switchToPreviousPlayer() { - // TODO: Implement - } - - /** - * Returns the {@link Faction}s of the active players. - * - *

The order of the player's factions in the list must - * correspond to the oder in which they play. - * Hence, the player that sets the first settlement must be - * at position 0 in the list etc. - * - * Important note: The list must contain the - * factions of active players only.

- * - * @return the list with player's factions - */ - public List getPlayerFactions() { - // TODO: Implement - return Collections.emptyList(); - } - - - /** - * Returns the game board. - * - * @return the game board - */ - public SiedlerBoard getBoard() { - // TODO: Implement - return board; - } - - /** - * Returns the {@link Faction} of the current player. - * - * @return the faction of the current player - */ - public Faction getCurrentPlayerFaction() { - // TODO: Implement - return null; - } - - /** - * Returns how many resource cards of the specified type - * the current player owns. - * - * @param resource the resource type - * @return the number of resource cards of this type - */ - public int getCurrentPlayerResourceStock(Resource resource) { - // TODO: Implement - return 0; - } - - /** - * Places a settlement in the founder's phase (phase II) of the game. - * - *

The placement does not cost any resource cards. If payout is - * set to true, for each adjacent resource-producing field, a resource card of the - * type of the resource produced by the field is taken from the bank (if available) and added to - * the players' stock of resource cards.

- * - * @param position the position of the settlement - * @param payout if true, the player gets one resource card per adjacent resource-producing field - * @return true, if the placement was successful - */ - public boolean placeInitialSettlement(Point position, boolean payout) { - // TODO: Implement - return false; - } - - /** - * Places a road in the founder's phase (phase II) of the game. - * The placement does not cost any resource cards. - * - * @param roadStart position of the start of the road - * @param roadEnd position of the end of the road - * @return true, if the placement was successful - */ - public boolean placeInitialRoad(Point roadStart, Point roadEnd) { - // TODO: Implement - return false; - } - - /** - * This method takes care of actions depending on the dice throw result. - * - * A key action is the payout of the resource cards to the players - * according to the payout rules of the game. This includes the - * "negative payout" in case a 7 is thrown and a player has more than - * {@link Config#MAX_CARDS_IN_HAND_NO_DROP} resource cards. - * - * If a player does not get resource cards, the list for this players' - * {@link Faction} is an empty list (not null)!. - * - *

- * The payout rules of the game take into account factors such as, the number - * of resource cards currently available in the bank, settlement types - * (settlement or city), and the number of players that should get resource - * cards of a certain type (relevant if there are not enough left in the bank). - *

- * - * @param dicethrow the resource cards that have been distributed to the players - * @return the resource cards added to the stock of the different players - */ - public Map> throwDice(int dicethrow) { - // TODO: Implement - return null; - } - - /** - * Builds a settlement at the specified position on the board. - * - *

The settlement can be built if: - *

    - *
  • the player possesses the required resource cards
  • - *
  • a settlement to place on the board
  • - *
  • the specified position meets the build rules for settlements
  • - *
- * - * @param position the position of the settlement - * @return true, if the placement was successful - */ - public boolean buildSettlement(Point position) { - // TODO: Implement - return false; - } - - /** - * Builds a city at the specified position on the board. - * - *

The city can be built if: - *

    - *
  • the player possesses the required resource cards
  • - *
  • a city to place on the board
  • - *
  • the specified position meets the build rules for cities
  • - *
- * - * @param position the position of the city - * @return true, if the placement was successful - */ - public boolean buildCity(Point position) { - // TODO: OPTIONAL task - Implement - return false; - } - - /** - * Builds a road at the specified position on the board. - * - *

The road can be built if: - *

    - *
  • the player possesses the required resource cards
  • - *
  • a road to place on the board
  • - *
  • the specified position meets the build rules for roads
  • - *
- * - * @param roadStart the position of the start of the road - * @param roadEnd the position of the end of the road - * @return true, if the placement was successful - */ - public boolean buildRoad(Point roadStart, Point roadEnd) { - // TODO: Implement - // 0.Is Edge 1. Check if Edge is empty 2. Check if One neighbors Corner is own settlement 3. Set road - boolean validTask = true; - while (validTask) { - validTask = board.hasEdge(roadStart,roadEnd); - validTask = board.getEdge(roadStart,roadEnd) == null; + /** + * Constructs a SiedlerGame game state object. + * + * @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 + */ + public SiedlerGame(int winPoints, int numberOfPlayers) { + if(winPoints < 3 || numberOfPlayers < 2 || numberOfPlayers > 4) { + throw new IllegalArgumentException(); + } + bank = new Bank(); + board = new SiedlerBoard(); + board.createFixGamefield(); + allPlayers = new ArrayList<>(); + createPlayer(numberOfPlayers); + activePlayer = 0; + this.winPointsForWin = winPoints; } - return false; - } + private void createPlayer(int numberOfPlayers) { + for (int i = 0; i < numberOfPlayers; i++) { + allPlayers.add(new Player(Config.Faction.values()[i])); + } + } - - /** - * Trades in {@link #FOUR_TO_ONE_TRADE_OFFER} resource cards of the - * offered type for {@link #FOUR_TO_ONE_TRADE_WANT} resource cards of the wanted type. - * - * The trade only works when bank and player possess the resource cards - * for the trade before the trade is executed. - * - * @param offer offered type - * @param want wanted type - * @return true, if the trade was successful - */ - public boolean tradeWithBankFourToOne(Resource offer, Resource want) { - // TODO: Implement - return false; - } + /** + * Switches to the next player in the defined sequence of players. + */ + public void switchToNextPlayer() { + if (activePlayer < allPlayers.size() -1){ + activePlayer++; + } + else if (activePlayer == allPlayers.size() -1){ + activePlayer = 0; + } + } - /** - * Returns the winner of the game, if any. - * - * @return the winner of the game or null, if there is no winner (yet) - */ - public Faction getWinner() { - // TODO: Implement - return null; - } - - - /** - * Places the thief on the specified field and steals a random resource card (if - * the player has such cards) from a random player with a settlement at that - * field (if there is a settlement) and adds it to the resource cards of the - * current player. - * - * @param field the field on which to place the thief - * @return false, if the specified field is not a field or the thief cannot be - * placed there (e.g., on water) - */ - public boolean placeThiefAndStealCard(Point field) { - //TODO: Implement (or longest road functionality) - return false; - } + /** + * Switches to the previous player in the defined sequence of players. + */ + public void switchToPreviousPlayer() { + if (activePlayer > 0){ + activePlayer--; + } + else if (activePlayer == 0){ + activePlayer = allPlayers.size()-1; + } + } + + /** + * Returns the {@link Faction}s of the active players. + * + *

The order of the player's factions in the list must + * correspond to the oder in which they play. + * Hence, the player that sets the first settlement must be + * at position 0 in the list etc. + * + * Important note: The list must contain the + * factions of active players only.

+ * + * @return the list with player's factions + */ + public List getPlayerFactions() { + List factions = new ArrayList<>(); + for (Player player: allPlayers ) { + factions.add(player.getFaction()); + } + + return factions; + } + + + /** + * Returns the game board. + * + * @return the game board + */ + public SiedlerBoard getBoard() { + return board; + } + + /** + * Returns the {@link Faction} of the current player. + * + * @return the faction of the current player + */ + public Faction getCurrentPlayerFaction() { + return allPlayers.get(activePlayer).getFaction(); + } + + /** + * Returns how many resource cards of the specified type + * the current player owns. + * + * @param resource the resource type + * @return the number of resource cards of this type + */ + public int getCurrentPlayerResourceStock(Resource resource) { + return allPlayers.get(activePlayer).getSpecificResource(resource); + } + + public HashMap getCurruntPlayerResource() { + return allPlayers.get(activePlayer).getResources(); + } + + /** + * Places a settlement in the founder's phase (phase II) of the game. + * + *

The placement does not cost any resource cards. If payout is + * set to true, for each adjacent resource-producing field, a resource card of the + * type of the resource produced by the field is taken from the bank (if available) and added to + * the players' stock of resource cards.

+ * + * @param position the position of the settlement + * @param payout if true, the player gets one resource card per adjacent resource-producing field + * @return true, if the placement was successful + */ + public boolean placeInitialSettlement(Point position, boolean payout) { + // TODO: Implement + if(!validPositionForSettlement(position)){ + return false; + } + board.setCorner(position, new Settlement(allPlayers.get(activePlayer).getFaction())); + List lands = board.getLandsForCorner(position); + for (Config.Land land:lands){ + allPlayers.get(activePlayer).addResource(land.getResource(), 1); + } + return true; + } + + /** + * Places a road in the founder's phase (phase II) of the game. + * The placement does not cost any resource cards. + * + * @param roadStart position of the start of the road + * @param roadEnd position of the end of the road + * @return true, if the placement was successful + */ + public boolean placeInitialRoad(Point roadStart, Point roadEnd) { + // TODO: Implement + if (!validPositionForRoad(roadStart, roadEnd)){ + return false; + } + board.setEdge(roadStart, roadEnd, new Road(allPlayers.get(activePlayer).getFaction())); + return true; + } + + /** + * This method takes care of actions depending on the dice throw result. + *

+ * A key action is the payout of the resource cards to the players + * according to the payout rules of the game. This includes the + * "negative payout" in case a 7 is thrown and a player has more than + * {@link Config#MAX_CARDS_IN_HAND_NO_DROP} resource cards. + *

+ * If a player does not get resource cards, the list for this players' + * {@link Faction} is an empty list (not null)!. + * + *

+ * The payout rules of the game take into account factors such as, the number + * of resource cards currently available in the bank, settlement types + * (settlement or city), and the number of players that should get resource + * cards of a certain type (relevant if there are not enough left in the bank). + *

+ * + * @param dicethrow the resource cards that have been distributed to the players + * @return the resource cards added to the stock of the different players + */ + public Map> throwDice(int dicethrow) { + Map> returnMap= new HashMap<>(); + List diceValueFields = board.getFieldsForDiceValue(dicethrow); + for (Player player : allPlayers) { + returnMap.put(player.getFaction(), new ArrayList()); + for (Point field : diceValueFields) { + List resources= board.getResourcesforFaction(field,player.getFaction()); + for (Config.Resource resource : resources){ + returnMap.get(player.getFaction()).add(resource); + player.addResource(resource,1); + } + } + } + return returnMap; + } + + /** + * Builds a settlement at the specified position on the board. + * + *

The settlement can be built if: + *

    + *
  • the player possesses the required resource cards
  • + *
  • a settlement to place on the board
  • + *
  • the specified position meets the build rules for settlements
  • + *
+ * + * @param position the position of the settlement + * @return true, if the placement was successful + */ + public boolean buildSettlement(Point position) { + //1. Check if position is corner && is empty && neighbour Corners are empty + if(!validPositionForSettlement(position)) { + return false; + } + //2. Check if neighbourEdge are Roads belong to active Player + if(!checkAdjacentEdgesList(position)) { + return false; + } + //3. Can Player build Settlement + if (!allPlayers.get(activePlayer).buildSettlement()) { + return false; + } + //4. Insert Settlement to map + board.setCorner(position, new Settlement(allPlayers.get(activePlayer).getFaction())); + //5. Give Resources to bank + bank.storeResourceToBank(Config.Structure.SETTLEMENT.getCosts()); + return true; + } + + /** + * Builds a city at the specified position on the board. + * + *

The city can be built if: + *

    + *
  • the player possesses the required resource cards
  • + *
  • a city to place on the board
  • + *
  • the specified position meets the build rules for cities
  • + *
+ * + * @param position the position of the city + * @return true, if the placement was successful + */ + public boolean buildCity(Point position) { + // TODO: OPTIONAL task - Implement + //1. Check if Corner. + if (!board.hasCorner(position)){ + return false; + } + //2. Check if Settlement has already been built + Settlement atCurrentPosition = board.getCorner(position); + if (atCurrentPosition == null){ + return false; + } + //3. Can player build a City. + if(!allPlayers.get(activePlayer).buildCity()){ + return false; + } + //4.Insert City into the map. + board.setCorner(position,new City(allPlayers.get(activePlayer).getFaction())); + //5. Give resources to the bank. + bank.storeResourceToBank(Config.Structure.CITY.getCosts()); + return false; + } + + /** + * Builds a road at the specified position on the board. + * + *

The road can be built if: + *

    + *
  • the player possesses the required resource cards
  • + *
  • a road to place on the board
  • + *
  • the specified position meets the build rules for roads
  • + *
+ * + * @param roadStart the position of the start of the road + * @param roadEnd the position of the end of the road + * @return true, if the placement was successful + */ + public boolean buildRoad(Point roadStart, Point roadEnd) { + //1. Check if is edge && is empty && if neighbour Edge or Corners belong to Settlement of active Player + if (!validPositionForRoad(roadStart,roadEnd)){ + return false; + } + //2. Can Player build road + if (!allPlayers.get(activePlayer).buildRoad()) { + // TODO: Error message + return false; + } + //3. Insert Road to map + board.setEdge(roadStart, roadEnd, new Road(allPlayers.get(activePlayer).getFaction())); + //4. Give Resource to bank + bank.storeResourceToBank(Config.Structure.ROAD.getCosts()); + return true; + } + + + /** + * Can be used for both initial Settlement and normal Phase. + * @param roadStart + * @param roadEnd + * @return + */ + private boolean validPositionForRoad(Point roadStart, Point roadEnd){ + //1. Check if Edge + if (!board.hasEdge(roadStart, roadEnd)) { + return false; + } + //2. Check if Edge is empty + if (board.getEdge(roadStart, roadEnd) != null) { + return false; + } + //3. Check if NeighbourEdge are Roads + boolean hasNeighbourRoad = (checkAdjacentEdgesList(roadStart) || checkAdjacentEdgesList(roadEnd)); + //4.Check if roadStart or roadEnd is Settlement of current player or if 3. is valid + if(board.getCorner(roadStart).getFaction() == allPlayers.get(activePlayer).getFaction() + || board.getCorner(roadEnd).getFaction() == allPlayers.get(activePlayer).getFaction() + || hasNeighbourRoad){ + return true; + } + return false; + } + + /** + * Can be used for both initial Settlement and normal Phase. + * @param position + * @return + */ + private boolean validPositionForSettlement(Point position){ + //1. Check if Corner + if (!board.hasCorner(position)) { + return false; + } + //2. Check if Corner is empty + if(board.getCorner(position) != null) { + return false; + } + //3. Check if neighbourCorners are empty + if(!checkAdjacentCornerList(position)) { + return false; + } + return true; + } + + /** + * This method checks if there are Roads build by active Player on adjacent edges + * @param point + * @return + */ + private boolean checkAdjacentEdgesList(Point point) { + List results = board.getAdjacentEdges(point); + for(int i = 0; i < results.size(); i++) { + if(results.get(i).getFaction() == allPlayers.get(activePlayer).getFaction()) { + return true; + } + } + return false; + } + + /** + * Checks if Adjacent Corners are empty + * @param point Corner to check + * @return true if all Neighbour Corners are emtpy + */ + private boolean checkAdjacentCornerList(Point point) { + List results = board.getNeighboursOfCorner(point); + if(results.size() > 0) { + return false; + } + return true; + } + + /** + * Trades in {@link #FOUR_TO_ONE_TRADE_OFFER} resource cards of the + * offered type for {@link #FOUR_TO_ONE_TRADE_WANT} resource cards of the wanted type. + *

+ * The trade only works when bank and player possess the resource cards + * for the trade before the trade is executed. + * + * @param offer offered type + * @param want wanted type + * @return true, if the trade was successful + */ + public boolean tradeWithBankFourToOne(Resource offer, Resource want) { + return bank.tradeWithBank(want, offer, FOUR_TO_ONE_TRADE_WANT, FOUR_TO_ONE_TRADE_OFFER); + } + + /** + * Returns the winner of the game, if any. + * + * @return the winner of the game or null, if there is no winner (yet) + */ + public Faction getWinner() { + if(getCurrentPlayerWinpoints() >= winPointsForWin){ + return getCurrentPlayerFaction(); + } + return null; + } + + public int getCurrentPlayerWinpoints(){ + int winPoints = 0; + List settlements = board.getCorners(); + for(Structure structure : settlements) { + + int newWinPoints = 0; + if(structure instanceof City){ + newWinPoints = 2; + } else if(structure instanceof Settlement) { + newWinPoints = 1; + } + if(structure.getFaction() == getCurrentPlayerFaction()){ + winPoints ++; + } + } + if(getLongestRoadFaction() == getCurrentPlayerFaction()){ + winPoints = winPoints + 2; + } + return winPoints; + } + + private Faction getLongestRoadFaction() { + return null; //todo implement + } + + + /** + * Places the thief on the specified field and steals a random resource card (if + * the player has such cards) from a random player with a settlement at that + * field (if there is a settlement) and adds it to the resource cards of the + * current player. + * + * @param field the field on which to place the thief + * @return false, if the specified field is not a field or the thief cannot be + * placed there (e.g., on water) + */ + public boolean placeThiefAndStealCard(Point field) { + //TODO: Implement (or longest road functionality) + return false; + } } diff --git a/src/ch/zhaw/catan/Structure.java b/src/ch/zhaw/catan/Structure.java new file mode 100644 index 0000000..54e589f --- /dev/null +++ b/src/ch/zhaw/catan/Structure.java @@ -0,0 +1,17 @@ +package ch.zhaw.catan; + +public abstract class Structure { + private Config.Faction faction; + + public Structure(Config.Faction faction) { + this.faction = faction; + } + + public String toString() { + return faction.toString(); + } + + public Config.Faction getFaction() { + return faction; + } +} diff --git a/src/ch/zhaw/hexboard/HexBoardTextView.java b/src/ch/zhaw/hexboard/HexBoardTextView.java index 97c51af..b3eeb98 100644 --- a/src/ch/zhaw/hexboard/HexBoardTextView.java +++ b/src/ch/zhaw/hexboard/HexBoardTextView.java @@ -98,7 +98,7 @@ import java.util.Map; public class HexBoardTextView { private static final String ONE_SPACE = " "; - private static final String TWO_SPACES = " "; + private static final String TWO_SPACES = " "; private static final String FOUR_SPACES = " "; private static final String FIVE_SPACES = " "; private static final String SIX_SPACES = " ";