Implemented longest Road logic in SiedlerGame

-adjusted Road and Settlement to return position
This commit is contained in:
Andrin Fassbind 2021-12-05 13:53:36 +01:00
parent 51e61a8e00
commit a79e1eefe3
6 changed files with 212 additions and 17 deletions

View File

@ -1,9 +1,11 @@
package ch.zhaw.catan; package ch.zhaw.catan;
import java.awt.*;
public class City extends Settlement { public class City extends Settlement {
public City(Config.Faction faction) { public City(Config.Faction faction, Point position) {
super(faction); super(faction,position);
} }
public String toString() { public String toString() {

View File

@ -20,8 +20,8 @@ public class Dummy {
TextTerminal<?> textTerminal = textIO.getTextTerminal(); TextTerminal<?> textTerminal = textIO.getTextTerminal();
SiedlerBoard board = new SiedlerBoard(); SiedlerBoard board = new SiedlerBoard();
board.addField(new Point(2, 2), Land.FOREST); board.addField(new Point(2, 2), Land.FOREST);
board.setCorner(new Point(3, 3), new Settlement(Config.Faction.RED)); 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)); 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"); board.addFieldAnnotation(new Point(2, 2), new Point(3, 1), "AA");
Map<Point, Label> lowerFieldLabel = new HashMap<>(); Map<Point, Label> lowerFieldLabel = new HashMap<>();

View File

@ -1,8 +1,23 @@
package ch.zhaw.catan; package ch.zhaw.catan;
import java.awt.*;
public class Road extends Structure { public class Road extends Structure {
public Road(Config.Faction faction) { private Point start,end;
public Road(Config.Faction faction,Point start,Point end) {
super(faction); super(faction);
this.start = start;
this.end = end;
}
public Point getStart() {
return start;
}
public Point getEnd() {
return end;
} }
} }

View File

@ -1,8 +1,17 @@
package ch.zhaw.catan; package ch.zhaw.catan;
import java.awt.*;
public class Settlement extends Structure { public class Settlement extends Structure {
public Settlement(Config.Faction faction) { private Point position;
public Settlement(Config.Faction faction,Point position) {
super(faction); super(faction);
this.position = position;
}
public Point getPosition() {
return position;
} }
} }

View File

@ -4,10 +4,8 @@ import ch.zhaw.catan.Config.Faction;
import ch.zhaw.catan.Config.Resource; import ch.zhaw.catan.Config.Resource;
import java.awt.*; import java.awt.*;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
@ -151,7 +149,7 @@ public class SiedlerGame {
if(!validPositionForSettlement(position)){ if(!validPositionForSettlement(position)){
return false; return false;
} }
board.setCorner(position, new Settlement(allPlayers.get(activePlayer).getFaction())); board.setCorner(position, new Settlement(allPlayers.get(activePlayer).getFaction(),position));
if(payout) { if(payout) {
List<Config.Land> lands = board.getLandsForCorner(position); List<Config.Land> lands = board.getLandsForCorner(position);
for (Config.Land land : lands) { for (Config.Land land : lands) {
@ -176,7 +174,7 @@ public class SiedlerGame {
if (!validPositionForRoad(roadStart, roadEnd)){ if (!validPositionForRoad(roadStart, roadEnd)){
return false; return false;
} }
board.setEdge(roadStart, roadEnd, new Road(allPlayers.get(activePlayer).getFaction())); board.setEdge(roadStart, roadEnd, new Road(allPlayers.get(activePlayer).getFaction(),roadStart,roadEnd));
return true; return true;
} }
@ -254,7 +252,7 @@ public class SiedlerGame {
return false; return false;
} }
//4. Insert Settlement to map //4. Insert Settlement to map
board.setCorner(position, new Settlement(allPlayers.get(activePlayer).getFaction())); board.setCorner(position, new Settlement(allPlayers.get(activePlayer).getFaction(),position));
return true; return true;
} }
@ -279,7 +277,7 @@ public class SiedlerGame {
} }
//2. Check if Settlement has already been built //2. Check if Settlement has already been built
Settlement atCurrentPosition = board.getCorner(position); //todo prüfen ob Siedlung von richtiger Faction und nicht Stadt Settlement atCurrentPosition = board.getCorner(position); //todo prüfen ob Siedlung von richtiger Faction und nicht Stadt
if (atCurrentPosition == null){ if (atCurrentPosition == null || atCurrentPosition.getFaction() != allPlayers.get(activePlayer).getFaction()){
return false; return false;
} }
//3. Can player build a City. //3. Can player build a City.
@ -287,7 +285,7 @@ public class SiedlerGame {
return false; return false;
} }
//4.Insert City into the map. //4.Insert City into the map.
board.setCorner(position,new City(allPlayers.get(activePlayer).getFaction())); board.setCorner(position,new City(allPlayers.get(activePlayer).getFaction(),position));
return true; return true;
} }
@ -317,7 +315,7 @@ public class SiedlerGame {
return false; return false;
} }
//3. Insert Road to map //3. Insert Road to map
board.setEdge(roadStart, roadEnd, new Road(allPlayers.get(activePlayer).getFaction())); board.setEdge(roadStart, roadEnd, new Road(allPlayers.get(activePlayer).getFaction(),roadStart,roadEnd));
return true; return true;
} }
@ -466,10 +464,148 @@ public class SiedlerGame {
return winPoints; return winPoints;
} }
private Faction getLongestRoadFaction() {
return null; //todo implement /**
* This method returns the faction of the player with the longest road longer than 5.
* @return null if there is no player with a road longer than 5 otherwise it returns the faction of the specific player
*/
private Faction getLongestRoadFaction() {
List<Settlement> corners = board.getCorners();
List<Config.Faction> factionList = getPlayerFactions();
HashMap<Config.Faction,Integer> players = new HashMap<>();
int highest = 0;
Config.Faction longestRoad = null;
for(Config.Faction faction : factionList) {
int count = 0;
players.put(faction,count);
for(Settlement settlement : corners){
HashSet<Road> 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()) {
if(players.get(faction) >= 5 && players.get(faction)>highest) {
highest = players.get(faction);
longestRoad = faction;
}
}
return longestRoad;
} }
/**
* 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<Road> countRoad(Config.Faction faction,Point position,HashSet<Road> roads,boolean add) {
List<Road> roadslist = board.getAdjacentEdges(position);
Iterator it2 = roads.iterator();
while(it2.hasNext()) {
Road roadsroad = (Road) it2.next();
Iterator it3 = roadslist.iterator();
while (it3.hasNext()){
Road roadslistRoad = (Road) 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<Road> listOne = (HashSet<Road>) roads.clone();
HashSet<Road> listTwo = (HashSet<Road>) 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<Road> tallest;
if(listOne.size()>= listTwo.size()) {
tallest = listOne;
}else{
tallest = listTwo;
}
for (Road road : tallest) {
roads.add(road);
}
}
}
else if(roadslist.size() == 3) {
HashSet<Road> listOne = (HashSet<Road>) roads.clone();
HashSet<Road> listTwo = (HashSet<Road>) roads.clone();
HashSet<Road> listThree = (HashSet<Road>) 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<Road> tallest;
HashSet<Road> 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 * Places the thief on the specified field and steals a random resource card (if

View File

@ -1,8 +1,14 @@
package ch.zhaw.catan; package ch.zhaw.catan;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import org.beryx.textio.TextIO;
import org.beryx.textio.TextIoFactory;
import org.beryx.textio.TextTerminal;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.awt.*;
/*** /***
* TODO Write your own tests in this class. * TODO Write your own tests in this class.
@ -18,4 +24,31 @@ public class SiedlerGameTest {
assertTrue(false); assertTrue(false);
} }
/**
* 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.
*
*/
@Test
public void testLongestRoad() {
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)));
board.setEdge(new Point(4, 6), new Point(5, 7), new Road(Config.Faction.BLUE,new Point(4, 6),new Point(5, 7)));
board.setEdge(new Point(4, 6), new Point(4, 4), new Road(Config.Faction.BLUE,new Point(4, 6),new Point(4, 4)));
board.setEdge(new Point(4, 6), new Point(3, 7), new Road(Config.Faction.BLUE,new Point(4, 6),new Point(3, 7)));
board.setEdge(new Point(3, 7), new Point(3, 9), new Road(Config.Faction.BLUE,new Point(3, 7),new Point(3, 9)));
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);
}
} }