From 572926d3c80ff8a505212af638a86dccd33c3845 Mon Sep 17 00:00:00 2001 From: Andrin Fassbind Date: Thu, 9 Dec 2021 16:05:46 +0100 Subject: [PATCH] refactored longestRoad implementation from SiedlerGame to SiedlerBoard and updated Test Method longestRoad --- .idea/misc.xml | 2 +- src/ch/zhaw/catan/SiedlerBoard.java | 168 +++++++++++++++++++++++- src/ch/zhaw/catan/SiedlerGame.java | 150 +-------------------- test/ch/zhaw/catan/SiedlerGameTest.java | 22 ++-- 4 files changed, 175 insertions(+), 167 deletions(-) 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/SiedlerBoard.java b/src/ch/zhaw/catan/SiedlerBoard.java index 04f9afe..96399e9 100644 --- a/src/ch/zhaw/catan/SiedlerBoard.java +++ b/src/ch/zhaw/catan/SiedlerBoard.java @@ -5,11 +5,7 @@ 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.*; /** * Subclass of HexBoard @@ -130,4 +126,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/SiedlerGame.java b/src/ch/zhaw/catan/SiedlerGame.java index 6999147..5e364c8 100644 --- a/src/ch/zhaw/catan/SiedlerGame.java +++ b/src/ch/zhaw/catan/SiedlerGame.java @@ -497,161 +497,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 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)); + } /**