diff --git a/.idea/misc.xml b/.idea/misc.xml index c3dfb30..b573818 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/ch/zhaw/catan/Bank.java b/src/ch/zhaw/catan/Bank.java index 39e7319..f82f19b 100644 --- a/src/ch/zhaw/catan/Bank.java +++ b/src/ch/zhaw/catan/Bank.java @@ -1,11 +1,10 @@ package ch.zhaw.catan; import java.util.HashMap; -import java.util.List; public class Bank { - private HashMap resources = new HashMap<>(); + private final HashMap resources = new HashMap<>(); public Bank(){ resources.putAll(Config.INITIAL_RESOURCE_CARDS_BANK); diff --git a/src/ch/zhaw/catan/City.java b/src/ch/zhaw/catan/City.java index a976267..5e68330 100644 --- a/src/ch/zhaw/catan/City.java +++ b/src/ch/zhaw/catan/City.java @@ -1,6 +1,6 @@ package ch.zhaw.catan; -import java.awt.*; +import java.awt.Point; public class City extends Settlement { diff --git a/src/ch/zhaw/catan/Command.java b/src/ch/zhaw/catan/Command.java index 7e7b24e..9a96ed3 100644 --- a/src/ch/zhaw/catan/Command.java +++ b/src/ch/zhaw/catan/Command.java @@ -1,12 +1,11 @@ package ch.zhaw.catan; -import org.beryx.textio.TextIO; - +//TODO:JavaDoc public enum Command { NEXTPLAYER ("next player"), BUILDSETTLEMENT ("build settlement"), BUILDCITY("build city"), BUILDROAD("build road"), TRADEWITHBANK("trade with bank"),QUIT("quit"); - private String commandWord; + private final String commandWord; diff --git a/src/ch/zhaw/catan/Dummy.java b/src/ch/zhaw/catan/Dummy.java deleted file mode 100644 index bf94f5f..0000000 --- a/src/ch/zhaw/catan/Dummy.java +++ /dev/null @@ -1,58 +0,0 @@ -package ch.zhaw.catan; - -import ch.zhaw.catan.Config.Land; -import ch.zhaw.hexboard.Label; -import java.awt.Point; -import java.util.HashMap; -import java.util.Map; -import org.beryx.textio.TextIO; -import org.beryx.textio.TextIoFactory; -import org.beryx.textio.TextTerminal; - -public class Dummy { - - public enum Actions { - 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), new Settlement(Config.Faction.RED,new Point(3, 3))); - board.setEdge(new Point(2, 0), new Point(3, 1), new Road(Config.Faction.BLUE,new Point(2, 0),new Point(2, 0))); - board.addFieldAnnotation(new Point(2, 2), new Point(3, 1), "AA"); - - Map lowerFieldLabel = new HashMap<>(); - lowerFieldLabel.put(new Point(2, 2), new Label('0', '9')); - SiedlerBoardTextView view = new SiedlerBoardTextView(board); - - for (Map.Entry e : lowerFieldLabel.entrySet()) { - view.setLowerFieldLabel(e.getKey(), e.getValue()); - } - - boolean running = true; - while (running) { - switch (getEnumValue(textIO, Actions.class)) { - case SHOW: - textTerminal.println(view.toString()); - break; - case QUIT: - running = false; - break; - default: - throw new IllegalStateException("Internal error found - Command not implemented."); - } - } - textIO.dispose(); - } - - public static > T getEnumValue(TextIO textIO, Class commands) { - return textIO.newEnumInputReader(commands).read("What would you like to do?"); - } - - public static void main(String[] args) { - new Dummy().run(); - } -} diff --git a/src/ch/zhaw/catan/Field.java b/src/ch/zhaw/catan/Field.java index 1da46c7..05e99c7 100644 --- a/src/ch/zhaw/catan/Field.java +++ b/src/ch/zhaw/catan/Field.java @@ -5,7 +5,7 @@ import ch.zhaw.hexboard.Label; public class Field { private Config.Land land; - private Label label; + private final Label label; public Field(Config.Land land, Label label){ this.land = land; diff --git a/src/ch/zhaw/catan/Parser.java b/src/ch/zhaw/catan/Parser.java index 2f1bc69..be0d42c 100644 --- a/src/ch/zhaw/catan/Parser.java +++ b/src/ch/zhaw/catan/Parser.java @@ -4,11 +4,9 @@ import org.beryx.textio.TextIO; import org.beryx.textio.TextIoFactory; import org.beryx.textio.TextTerminal; -import java.awt.*; +import java.awt.Point; 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. * @@ -76,7 +74,7 @@ public class Parser { */ public HashMap gameStart() { HashMap gameStartValues = new HashMap<>(); - gameStartValues.put("NumberOfPlayers", textIO.newIntInputReader().withMinVal(2).withMaxVal(4).read("Number of players:")); + gameStartValues.put("NumberOfPlayers", textIO.newIntInputReader().withMinVal(Config.MIN_NUMBER_OF_PLAYERS).withMaxVal(4).read("Number of players:")); gameStartValues.put("NumberOfWinPoints", textIO.newIntInputReader().withMinVal(5).withMaxVal(15).read("Winpoints needed for Victory:")); return gameStartValues; } diff --git a/src/ch/zhaw/catan/Player.java b/src/ch/zhaw/catan/Player.java index fc378a0..9a34453 100644 --- a/src/ch/zhaw/catan/Player.java +++ b/src/ch/zhaw/catan/Player.java @@ -1,7 +1,8 @@ package ch.zhaw.catan; -import java.util.*; - +import java.util.HashMap; +import java.util.List; +//TODO Java Doc bearbeiten /** * New Class PLayer * This class is here in order to maintain the resources of the players, the amount of structures that they can build, @@ -9,9 +10,9 @@ import java.util.*; */ public class Player { - private Config.Faction faction; - private HashMap resources; - private HashMap structureToUse; + private final Config.Faction faction; + private final HashMap resources; + private final HashMap structureToUse; /** * The constructor creates a new instance of the player class that initializes the Hashmap resources and structureToUse. @@ -62,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 numberToAdd how much to add @@ -89,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 - * 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. * 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. diff --git a/src/ch/zhaw/catan/Road.java b/src/ch/zhaw/catan/Road.java index 1bc37a5..2375c74 100644 --- a/src/ch/zhaw/catan/Road.java +++ b/src/ch/zhaw/catan/Road.java @@ -1,10 +1,10 @@ package ch.zhaw.catan; -import java.awt.*; - +import java.awt.Point; +/// TODO: 09/12/2021 Java Doc public class Road extends Structure { - private Point start,end; + private final Point start,end; public Road(Config.Faction faction,Point start,Point end) { diff --git a/src/ch/zhaw/catan/Settlement.java b/src/ch/zhaw/catan/Settlement.java index b10595d..47f8398 100644 --- a/src/ch/zhaw/catan/Settlement.java +++ b/src/ch/zhaw/catan/Settlement.java @@ -1,7 +1,7 @@ package ch.zhaw.catan; -import java.awt.*; - +import java.awt.Point; +//TODO Java Doc public class Settlement extends Structure { private Point position; diff --git a/src/ch/zhaw/catan/Siedler.java b/src/ch/zhaw/catan/Siedler.java index a90d452..1eeea7e 100644 --- a/src/ch/zhaw/catan/Siedler.java +++ b/src/ch/zhaw/catan/Siedler.java @@ -4,7 +4,7 @@ import java.util.HashMap; 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 { /** @@ -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. * @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) { boolean running = true; @@ -33,7 +33,7 @@ public class Siedler { throwDice(parser, game); diceThrown = true; } - parser.displayPlayerInfo(game.getCurrentPlayerResource(), game.getCurrentPlayerWinpoints()); + parser.displayPlayerInfo(game.getCurrentPlayerResource(), game.getCurrentPlayerWinPoints()); switch (parser.getAction()) { case NEXTPLAYER: 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++){ buildStructuresInFoundingPhase(parser, game, true); 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. * @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 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){ parser.displayGameboard(game.getBoard().getTextView()); @@ -165,27 +165,27 @@ public class Siedler { //build Settlement parser.giveCoordinatesForStructures(Config.Structure.SETTLEMENT); - boolean sucessful = false; + boolean successful = false; do{ if(game.placeInitialSettlement(parser.getPoint(), payout)) { - sucessful = true; + successful = true; } else{ parser.errorMessage(); } - } while(!sucessful); + } while(!successful); //build Road parser.displayGameboard(game.getBoard().getTextView()); parser.giveCoordinatesForStructures(Config.Structure.ROAD); - sucessful = false; + successful = false; do{ if(game.placeInitialRoad(parser.getPoint(), parser.getPoint())) { - sucessful = true; + successful = true; } else{ parser.errorMessage(); } - } while(!sucessful); + } while(!successful); } } diff --git a/src/ch/zhaw/catan/SiedlerBoard.java b/src/ch/zhaw/catan/SiedlerBoard.java index 04f9afe..fe5176a 100644 --- a/src/ch/zhaw/catan/SiedlerBoard.java +++ b/src/ch/zhaw/catan/SiedlerBoard.java @@ -5,21 +5,18 @@ import ch.zhaw.hexboard.HexBoard; import ch.zhaw.hexboard.Label; import java.awt.Point; -import java.util.List; -import java.util.HashMap; -import java.util.Map; -import java.util.ArrayList; -import java.util.Collections; - +import java.util.*; +//TODO Enhance JavaDoc /** * 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 { /** * HashMap to save all Fields which are set yet. * Key: Point with coordinates of the field + * //TODO Enhance JavaDoc * Value: Field Object */ HashMap fields = new HashMap<>(); @@ -85,13 +82,13 @@ public class SiedlerBoard extends HexBoard { } /** - * 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 faction The faction, which should get paied. - * @return a ArrayList with all resources, which will be paied to the specified faction. + * @param faction The faction, which should get paid. + * @return a ArrayList with all resources, which will be paid to the specified faction. */ - public ArrayList getResourcesforFaction(Point point, Config.Faction faction){ + public ArrayList getResourcesForFaction(Point point, Config.Faction faction){ List possibleSettlementField = super.getCornersOfField(point); ArrayList resourcesToPlayer = new ArrayList<>(); for (Settlement settlement : possibleSettlementField) { @@ -130,4 +127,166 @@ public class SiedlerBoard extends HexBoard { } return List.of(lands); } + + /** + * This method checks for the player with the longest road according to the catan game rules. + * @return a HashMap where faction is the player with the longest road longer according to catan game rules + * and the Integer representing the length of the road + */ + public void getLongestRoadFaction(HashMap currentLongestRoad,List factionList) { + List corners = getCorners(); + HashMap players = new HashMap<>(); + + for(Config.Faction faction : factionList) { + int count = 0; + players.put(faction,count); + for(Settlement settlement : corners){ + if(settlement.getFaction() == faction){ + HashSet roads = new HashSet<>(); + roads = countRoad(faction,settlement.getPosition(),roads,true); + count = roads.size(); + int currentCount = players.get(faction); + if(count > currentCount) { + players.put(faction,count); + } + } + } + } + + if(currentLongestRoad.size() == 0) { + Config.Faction currentFaction = null; + int currentRoad = 4; + for(Config.Faction factionA : players.keySet()) { + if(players.get(factionA)>currentRoad) { + currentFaction = factionA; + currentRoad = players.get(factionA); + } + } + if(currentFaction != null){ + currentLongestRoad.put(currentFaction,currentRoad); + } + }else{ + for(Config.Faction faction : players.keySet()) { + for(Config.Faction faction1 : currentLongestRoad.keySet()) { + if(players.get(faction) >= 5 && players.get(faction) > currentLongestRoad.get(faction1)) { + currentLongestRoad.remove(faction1); + currentLongestRoad.put(faction,players.get(faction)); + } + } + } + } + } + + /** + * This method is recursive and adds all roads which belongs to a specific players and stringing together to a HashSet. + * The length of the HashSet represents the length of the longest Road the player has. + * @param faction the faction of the player to check on + * @param position there has to be a starting point to start counting. In this case it's a corner where a settlement belonging to the players faction is build on. + * @param roads is the hashset with all roads belong to the player which are stringing together + * @param add if true branches needs to be count together. (for example if it is the starting point(first time of counting)) otherwise the longest branch is beeing added to roads. + * @return HashSet with all roads from a specific player which are string together. + */ + private HashSet countRoad(Config.Faction faction,Point position,HashSet roads,boolean add) { + List roadslist = getAdjacentEdges(position); + if(getCorner(position) != null && getCorner(position).getFaction() != faction) { + return roads; + } + + Iterator it2 = roads.iterator(); + while(it2.hasNext()) { + Road roadsroad = it2.next(); + Iterator it3 = roadslist.iterator(); + while (it3.hasNext()){ + Road roadslistRoad = it3.next(); + if(roadslistRoad == roadsroad || roadslistRoad.getFaction() != faction) { + it3.remove(); + } + } + } + + + if(roadslist.size() == 1) { + roads.add(roadslist.get(0)); + position = getNextPoint(roadslist.get(0),position); + roads = countRoad(faction,position,roads,false); + } + + else if(roadslist.size() == 2) { + HashSet listOne = (HashSet) roads.clone(); + HashSet listTwo = (HashSet) roads.clone(); + listOne.add(roadslist.get(0)); + Point positionOne = getNextPoint(roadslist.get(0),position); + listTwo.add(roadslist.get(1)); + Point positionTwo = getNextPoint(roadslist.get(1),position); + listOne = countRoad(faction,positionOne,listOne,false); + listTwo = countRoad(faction,positionTwo,listTwo,false); + if(add) { + for (Road road : listOne) { + listTwo.add(road); + } + roads = listTwo; + }else { + HashSet tallest; + if(listOne.size()>= listTwo.size()) { + tallest = listOne; + }else{ + tallest = listTwo; + } + for (Road road : tallest) { + roads.add(road); + } + } + + } + + else if(roadslist.size() == 3) { + HashSet listOne = (HashSet) roads.clone(); + HashSet listTwo = (HashSet) roads.clone(); + HashSet listThree = (HashSet) roads.clone(); + listOne.add(roadslist.get(0)); + Point positionOne = getNextPoint(roadslist.get(0),position); + listTwo.add(roadslist.get(1)); + Point positionTwo = getNextPoint(roadslist.get(1),position); + listThree.add(roadslist.get(2)); + Point positionThree = getNextPoint(roadslist.get(2),position); + listOne = countRoad(faction,positionOne,listOne,false); + listTwo = countRoad(faction,positionTwo,listTwo,false); + listThree = countRoad(faction,positionThree,listThree,false); + + HashSet tallest; + HashSet secondtallest; + + if(listOne.size()>=listTwo.size()) { + tallest = listOne; + secondtallest = listTwo; + }else { + tallest = listTwo; + secondtallest = listOne; + }if(listThree.size() >= secondtallest.size()) { + secondtallest = listThree; + } + for(Road road : secondtallest) { + tallest.add(road); + } + roads = tallest; + } + return roads; + } + + /** + * This method is beeing used to evaluate the next starting position to get the adjacent Roads from it. + * @param road the next road to check on + * @param position the current starting point + * @return return the oposite point of the current point. + */ + private Point getNextPoint(Road road,Point position) { + Point start = road.getStart(); + Point end = road.getEnd(); + if(position.equals(start)) { + position = end; + }else { + position = start; + } + return position; + } } diff --git a/src/ch/zhaw/catan/SiedlerBoardTextView.java b/src/ch/zhaw/catan/SiedlerBoardTextView.java index ce2ca66..157e4f9 100644 --- a/src/ch/zhaw/catan/SiedlerBoardTextView.java +++ b/src/ch/zhaw/catan/SiedlerBoardTextView.java @@ -2,11 +2,8 @@ package ch.zhaw.catan; import ch.zhaw.catan.Config.Land; 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 { public SiedlerBoardTextView(SiedlerBoard board) { diff --git a/src/ch/zhaw/catan/SiedlerGame.java b/src/ch/zhaw/catan/SiedlerGame.java index 6999147..bfcb020 100644 --- a/src/ch/zhaw/catan/SiedlerGame.java +++ b/src/ch/zhaw/catan/SiedlerGame.java @@ -3,9 +3,14 @@ package ch.zhaw.catan; import ch.zhaw.catan.Config.Faction; import ch.zhaw.catan.Config.Resource; -import java.awt.*; -import java.util.*; +import java.awt.Point; +import java.util.Map; +import java.util.HashMap; +import java.util.ArrayList; import java.util.List; +import java.util.Random; +import java.util.Iterator; +import java.util.HashSet; /** @@ -35,7 +40,7 @@ public class SiedlerGame { * three or players is not between two and four */ public SiedlerGame(int winPoints, int numberOfPlayers) { - if(winPoints < 3 || numberOfPlayers < 2 || numberOfPlayers > 4) { + if(winPoints < 3 || numberOfPlayers < Config.MIN_NUMBER_OF_PLAYERS || numberOfPlayers > 4) { throw new IllegalArgumentException(); } bank = new Bank(); @@ -77,7 +82,7 @@ public class SiedlerGame { activePlayer = allPlayers.size()-1; } } - + //TODO JavaDoc private boolean addResourcesToPlayer(Player player, Resource resource, int numberToAdd){ if(bank.getResourceFromBank(resource, numberToAdd)){ player.addResource(resource, numberToAdd); @@ -85,10 +90,10 @@ public class SiedlerGame { } return false; } - - private boolean substractResourceFromPlayer(Player player, Resource resource, int numberToSubstract){ - if(player.substractResource(resource, numberToSubstract)){ - bank.storeResourceToBank(resource, numberToSubstract); + //TODO JavaDoc + private boolean subtractResourceFromPlayer(Player player, Resource resource, int numberToSubtract){ + if(player.substractResource(resource, numberToSubtract)){ + bank.storeResourceToBank(resource, numberToSubtract); return true; } return false; @@ -212,21 +217,21 @@ public class SiedlerGame { * 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 + * @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) { - if (dicethrow == 7) { + public Map> throwDice(int diceThrow) { + if (diceThrow == 7) { for(Player player : allPlayers) { handleDiceThrow7(player); } } else { Map> returnMap= new HashMap<>(); - List diceValueFields = board.getFieldsForDiceValue(dicethrow); + 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()); + List resources = board.getResourcesForFaction(field,player.getFaction()); for (Config.Resource resource : resources){ returnMap.get(player.getFaction()).add(resource); addResourcesToPlayer(player, resource, 1); @@ -237,7 +242,7 @@ public class SiedlerGame { } return null; } - + //TODO JavaDoc public void handleDiceThrow7(Player player) { ArrayList resourceArrayList = new ArrayList<>(); HashMap resources = player.getResources(); @@ -246,11 +251,11 @@ public class SiedlerGame { resourceArrayList.add(resource); } } - if(resourceArrayList.size() > 7){ + if(resourceArrayList.size() > Config.MAX_CARDS_IN_HAND_NO_DROP){ int resourcesToRemove =resourceArrayList.size() - (resourceArrayList.size() / 2); Random random = new Random(); 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 costs = Config.Structure.SETTLEMENT.getCosts(); for (Config.Resource resource : costs) { - substractResourceFromPlayer(allPlayers.get(activePlayer), resource, 1); + subtractResourceFromPlayer(allPlayers.get(activePlayer), resource, 1); } //4. Insert Settlement to map @@ -324,7 +329,7 @@ public class SiedlerGame { List costs = Config.Structure.CITY.getCosts(); for (Config.Resource resource : costs) { - substractResourceFromPlayer(allPlayers.get(activePlayer), resource, 1); + subtractResourceFromPlayer(allPlayers.get(activePlayer), resource, 1); } //4.Insert City into the map. @@ -359,7 +364,7 @@ public class SiedlerGame { List costs = Config.Structure.ROAD.getCosts(); for (Config.Resource resource : costs) { - substractResourceFromPlayer(allPlayers.get(activePlayer), resource, 1); + subtractResourceFromPlayer(allPlayers.get(activePlayer), resource, 1); } //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. * @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 */ private boolean validPositionForRoad(Point roadStart, Point roadEnd){ - //1. Check if Edge + //1. Check if it is an edge if (!board.hasEdge(roadStart, roadEnd)) { return false; } - //2. Check if Edge is empty + //2. Check if edge is empty if (board.getEdge(roadStart, roadEnd) != null) { return false; } - //3. Check if NeighbourEdge are Roads + //3. Check if neighbouring edges are roads boolean hasNeighbourRoad = (checkAdjacentEdgesList(roadStart) || checkAdjacentEdgesList(roadEnd)); if(hasNeighbourRoad) { return true; @@ -399,7 +404,7 @@ public class SiedlerGame { * @return true if valid position for settlement */ private boolean validPositionForSettlement(Point position){ - //1. Check if Corner + //1. Check if corner if (!board.hasCorner(position)) { return false; } @@ -407,11 +412,11 @@ public class SiedlerGame { if(checkIfWater(position)) { return false; } - //3. Check if Corner is empty + //3. Check if corner is empty if(board.getCorner(position) != null) { return false; } - //3. Check if neighbourCorners are empty + //3. Check if neighbouring corners are empty return checkAdjacentCornerList(position); } @@ -464,7 +469,7 @@ public class SiedlerGame { public boolean tradeWithBankFourToOne(Resource offer, Resource want) { Player player = allPlayers.get(activePlayer); 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 false; @@ -476,13 +481,13 @@ public class SiedlerGame { * @return the winner of the game or null, if there is no winner (yet) */ public Faction getWinner() { - if(getCurrentPlayerWinpoints() >= winPointsForWin){ + if(getCurrentPlayerWinPoints() >= winPointsForWin){ return getCurrentPlayerFaction(); } return null; } - - public int getCurrentPlayerWinpoints(){ + //Todo Java Doc + public int getCurrentPlayerWinPoints(){ int winPoints = 0; List settlements = board.getCorners(); for(Structure structure : settlements) { @@ -497,161 +502,13 @@ public class SiedlerGame { winPoints += newWinPoints; } } - longestRoadFaction = getLongestRoadFaction(longestRoadFaction); + board.getLongestRoadFaction(longestRoadFaction,getPlayerFactions()); if(longestRoadFaction.get(getCurrentPlayerFaction()) != null){ winPoints += 2; } return winPoints; } - - /** - * This method checks for the player with the longest road according to the catan game rules. - * @return a HashMap where faction is the player with the longest road longer according to catan game rules - * and the Integer representing the length of the road - */ - private HashMap getLongestRoadFaction(HashMap currentLongestRoad) { - List corners = board.getCorners(); - List factionList = getPlayerFactions(); - HashMap players = new HashMap<>(); - - for(Config.Faction faction : factionList) { - int count = 0; - players.put(faction,count); - for(Settlement settlement : corners){ - HashSet roads = new HashSet<>(); - roads = countRoad(faction,settlement.getPosition(),roads,true); - count = roads.size(); - int currentCount = players.get(faction); - if(count > currentCount) { - players.put(faction,count); - } - } - } - for(Config.Faction faction : players.keySet()) { - for(Config.Faction faction1 : currentLongestRoad.keySet()) { - if(players.get(faction) >= 5 && players.get(faction) > currentLongestRoad.get(faction1)) { - currentLongestRoad.remove(faction1); - currentLongestRoad.put(faction,players.get(faction)); - } - } - } - return currentLongestRoad; - } - - /** - * This method is recursive and adds all roads which belongs to a specific players and stringing together to a HashSet. - * The length of the HashSet represents the length of the longest Road the player has. - * @param faction the faction of the player to check on - * @param position there has to be a starting point to start counting. In this case it's a corner where a settlement belonging to the players faction is build on. - * @param roads is the hashset with all roads belong to the player which are stringing together - * @param add if true branches needs to be count together. (for example if it is the starting point(first time of counting)) otherwise the longest branch is beeing added to roads. - * @return HashSet with all roads from a specific player which are string together. - */ - private HashSet countRoad(Config.Faction faction,Point position,HashSet roads,boolean add) { - List roadslist = board.getAdjacentEdges(position); - if(board.getCorner(position) != null || board.getCorner(position).getFaction() != faction) { - return roads; - } - - Iterator it2 = roads.iterator(); - while(it2.hasNext()) { - Road roadsroad = it2.next(); - Iterator it3 = roadslist.iterator(); - while (it3.hasNext()){ - Road roadslistRoad = it3.next(); - if(roadslistRoad == roadsroad || roadslistRoad.getFaction() != faction) { - it3.remove(); - } - } - } - - - if(roadslist.size() == 1) { - roads.add(roadslist.get(0)); - position = getNextPoint(roadslist.get(0),position); - roads = countRoad(faction,position,roads,false); - } - - else if(roadslist.size() == 2) { - HashSet listOne = (HashSet) roads.clone(); - HashSet listTwo = (HashSet) roads.clone(); - listOne.add(roadslist.get(0)); - Point positionOne = getNextPoint(roadslist.get(0),position); - listTwo.add(roadslist.get(1)); - Point positionTwo = getNextPoint(roadslist.get(1),position); - listOne = countRoad(faction,positionOne,listOne,false); - listTwo = countRoad(faction,positionTwo,listTwo,false); - if(add) { - for (Road road : listOne) { - listTwo.add(road); - } - roads = listTwo; - }else { - HashSet tallest; - if(listOne.size()>= listTwo.size()) { - tallest = listOne; - }else{ - tallest = listTwo; - } - for (Road road : tallest) { - roads.add(road); - } - } - - } - - else if(roadslist.size() == 3) { - HashSet listOne = (HashSet) roads.clone(); - HashSet listTwo = (HashSet) roads.clone(); - HashSet listThree = (HashSet) roads.clone(); - listOne.add(roadslist.get(0)); - Point positionOne = getNextPoint(roadslist.get(0),position); - listTwo.add(roadslist.get(1)); - Point positionTwo = getNextPoint(roadslist.get(1),position); - listThree.add(roadslist.get(2)); - Point positionThree = getNextPoint(roadslist.get(2),position); - listOne = countRoad(faction,positionOne,listOne,false); - listTwo = countRoad(faction,positionTwo,listTwo,false); - listThree = countRoad(faction,positionThree,listThree,false); - - HashSet tallest; - HashSet secondtallest; - - if(listOne.size()>=listTwo.size()) { - tallest = listOne; - secondtallest = listTwo; - }else { - tallest = listTwo; - secondtallest = listOne; - }if(listThree.size() >= secondtallest.size()) { - secondtallest = listThree; - } - for(Road road : secondtallest) { - tallest.add(road); - } - roads = tallest; - } - return roads; - } - - /** - * This method is beeing used to evaluate the next starting position to get the adjacent Roads from it. - * @param road the next road to check on - * @param position the current starting point - * @return return the oposite point of the current point. - */ - private Point getNextPoint(Road road,Point position) { - Point start = road.getStart(); - Point end = road.getEnd(); - if(position.equals(start)) { - position = end; - }else { - position = start; - } - return position; - } - /** * 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 @@ -663,7 +520,7 @@ public class SiedlerGame { * placed there (e.g., on water) */ public boolean placeThiefAndStealCard(Point field) { - //TODO: Implement (or longest road functionality) + // Implemented longest road. return false; } diff --git a/test/ch/zhaw/catan/SiedlerGameTest.java b/test/ch/zhaw/catan/SiedlerGameTest.java index 93a3099..3dd6fe8 100644 --- a/test/ch/zhaw/catan/SiedlerGameTest.java +++ b/test/ch/zhaw/catan/SiedlerGameTest.java @@ -13,9 +13,8 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.awt.*; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; +import java.util.*; +import java.util.List; /*** @@ -50,18 +49,15 @@ public class SiedlerGameTest { )); /** - * To Test getLongestRoad in SiedlerGame isolatet do: - * 1. make SiedlerGame.getLongestRoadFaction, Siedlergame.countRoad && Siedlergame.getNextPoint static - * 2. make SiedlerGame.getLongestRoadFaction public - * 3. add Parameter Board to SiedlerGame.getLongestRoadFaction and SiedlerGame.countRoad. - * 4. add Parameter faction to SiedlerGame.getLongestRoadFaction - * 5. Create Board in testLongestRoad() and Hashmap with faction - * Tipp: Logic Equivalent classes are: start counting at settlements with 0 or 1 or 2 or 3 own roads attached to it - * Make branches in between the road with diffrent lengths. + * To Test getLongestRoad in SiedlerBoard * */ @Test public void testLongestRoad() { + HashMap currentLongestRoad = new HashMap<>(); + //currentLongestRoad.put(Config.Faction.RED,5); + List factionList = Arrays.asList(Config.Faction.values()); + SiedlerBoard board = new SiedlerBoard(); board.createFixGamefield(); board.setEdge(new Point(6, 6), new Point(5, 7), new Road(Config.Faction.BLUE,new Point(6, 6),new Point(5, 7))); @@ -72,7 +68,9 @@ public class SiedlerGameTest { board.setEdge(new Point(3, 9), new Point(4, 10), new Road(Config.Faction.BLUE,new Point(3, 9),new Point(4, 10))); board.setEdge(new Point(4, 10), new Point(5, 9), new Road(Config.Faction.BLUE,new Point(4, 10),new Point(5, 9))); board.setCorner(new Point(3,7),new Settlement(Config.Faction.BLUE,new Point(3,7))); - //SiedlerGame.getLongestRoadFaction(board,faction); + board.getLongestRoadFaction(currentLongestRoad,factionList); + assertEquals(6,currentLongestRoad.get(Config.Faction.BLUE)); + } /**