Better graph connection algorithm

This commit is contained in:
joachimschmidt557 2019-03-23 18:29:14 +01:00
parent f6bed8fbda
commit cd62502f37
2 changed files with 65 additions and 7 deletions

View file

@ -19,6 +19,8 @@ import game.map.Castle;
*/ */
public class Graph<T> { public class Graph<T> {
final static boolean DEBUG = true;
private List<Edge<T>> edges; private List<Edge<T>> edges;
private List<Node<T>> nodes; private List<Node<T>> nodes;
@ -166,8 +168,10 @@ public class Graph<T> {
} }
if (DEBUG) {
System.out.println(allVisitedNodes.size()); System.out.println(allVisitedNodes.size());
System.out.println(nodes.size()); System.out.println(nodes.size());
}
return allVisitedNodes.size() == nodes.size(); return allVisitedNodes.size() == nodes.size();

View file

@ -7,7 +7,9 @@ import gui.Resources;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -155,20 +157,32 @@ public class GameMap {
List<Node<Castle>> castleNodes = castleGraph.getNodes(); List<Node<Castle>> castleNodes = castleGraph.getNodes();
if (castleNodes.isEmpty()) if (castleNodes.size() < 2)
return; return;
// Stage 1 // Stage 1
List<Node<Castle>> remainingCastles = new ArrayList<Node<Castle>>(castleNodes); List<Node<Castle>> remainingCastles = new ArrayList<Node<Castle>>(castleNodes);
List<Node<Castle>> connectedCastles = new ArrayList<Node<Castle>>();
Node<Castle> castleToConnect = remainingCastles.remove(0); Node<Castle> castleToConnect = remainingCastles.remove(0);
connectedCastles.add(castleToConnect);
while (!remainingCastles.isEmpty()) { while (!remainingCastles.isEmpty()) {
Node<Castle> nearestCastle = nearestCastle(castleToConnect, remainingCastles); //Node<Castle> nearestCastle = nearestCastle(castleToConnect, remainingCastles);
castleGraph.addEdge(castleToConnect, nearestCastle); //castleGraph.addEdge(castleToConnect, nearestCastle);
castleToConnect = nearestCastle; //castleToConnect = nearestCastle;
remainingCastles.remove(castleToConnect); //remainingCastles.remove(castleToConnect);
Map.Entry<Node<Castle>, Node<Castle>> conn =
nearestCastle(connectedCastles, remainingCastles);
castleGraph.addEdge(conn.getKey(), conn.getValue());
remainingCastles.remove(conn.getValue());
connectedCastles.add(conn.getValue());
} }
@ -182,6 +196,12 @@ public class GameMap {
} }
/**
* Returns the nearest castle
* @param castle The castle
* @param allCastles The castles to choose from
* @return The nearest castle
*/
private Node<Castle> nearestCastle(Node<Castle> castle, List<Node<Castle>> allCastles) { private Node<Castle> nearestCastle(Node<Castle> castle, List<Node<Castle>> allCastles) {
return allCastles.stream() return allCastles.stream()
@ -192,6 +212,40 @@ public class GameMap {
} }
/**
* Returns the nearest castle that we can access from a list (1) of castles
* @param castles (1) The castles which should connect to the castle
* @param allCastles (2) The castles to choose from
* @return An edge from a castle from list (1) to the nearest
* castle from list (2)
*/
private Map.Entry<Node<Castle>, Node<Castle>> nearestCastle(List<Node<Castle>> castles, List<Node<Castle>> allCastles) {
// First get all nearest castles one by one
HashMap<Node<Castle>, Node<Castle>> nearestCastles = new HashMap<Node<Castle>, Node<Castle>>();
for (Node<Castle> castle : castles) {
nearestCastles.put(castle, nearestCastle(castle, allCastles));
}
// Return the pair with the minimal distance
return
nearestCastles.entrySet().stream()
.min((x, y) -> Double.compare(
x.getValue().getValue().distance(x.getKey().getValue()),
y.getValue().getValue().distance(y.getKey().getValue())))
.get();
}
/**
* Returns a list of all castles in a predefined
* radius
* @param castle The castle
* @param allCastles The possible castles
* @param r The radius
* @return All castles in that radius
*/
private List<Node<Castle>> allCastlesInRadius(Node<Castle> castle, List<Node<Castle>> allCastles, double r) { private List<Node<Castle>> allCastlesInRadius(Node<Castle> castle, List<Node<Castle>> allCastles, double r) {
return allCastles.stream() return allCastles.stream()