Prechádzať zdrojové kódy

levelgraph implemented with jgrapht lib, parsing graph from level data working

mesinger 5 rokov pred
rodič
commit
678af4f056

+ 15 - 1
src/me/hammerle/supersnuvi/Main.java

@@ -1,7 +1,19 @@
 package me.hammerle.supersnuvi;
 
 import me.hammerle.supersnuvi.gamelogic.Level;
+import me.hammerle.supersnuvi.gamelogic.pathfinding.LevelGraph;
 import me.hammerle.supersnuvi.gamelogic.pathfinding.LevelGraphBuilder;
+import me.hammerle.supersnuvi.util.Pair;
+import org.jgrapht.Graph;
+import org.jgrapht.GraphPath;
+import org.jgrapht.alg.shortestpath.ALTAdmissibleHeuristic;
+import org.jgrapht.alg.shortestpath.AStarShortestPath;
+import org.jgrapht.graph.DefaultDirectedGraph;
+import org.jgrapht.graph.DefaultEdge;
+
+import javax.swing.text.DefaultEditorKit;
+import java.util.HashSet;
+import java.util.Set;
 
 public class Main
 {
@@ -12,7 +24,9 @@ public class Main
         Level[] levels = game.getLevels();
 
         LevelGraphBuilder levelGraphBuilder = new LevelGraphBuilder();
-        levelGraphBuilder.getLevelAsGraph(levels[0]);
+        LevelGraph graph = levelGraphBuilder.getLevelAsGraph(levels[0]);
+
+        graph.doo();
 
         game.run();
     }

+ 0 - 14
src/me/hammerle/supersnuvi/gamelogic/pathfinding/IDirectedEdge.java

@@ -1,14 +0,0 @@
-package me.hammerle.supersnuvi.gamelogic.pathfinding;
-
-/**
- * edge with or without direction
- */
-public interface IDirectedEdge {
-
-    // possible directions
-    int DIRECTION_NODE1_TO_NODE2 = 0x01;
-    int DIRECTION_NODE2_TO_NODE1 = 0x02;
-    int DIRECTION_DUPLEX = 0x03;
-
-    int getDirection();
-}

+ 0 - 11
src/me/hammerle/supersnuvi/gamelogic/pathfinding/IEdge.java

@@ -1,11 +0,0 @@
-package me.hammerle.supersnuvi.gamelogic.pathfinding;
-
-/**
- * main interface for a edge in a graph
- */
-public interface IEdge {
-
-    INode getNode1();
-    INode getNode2();
-    double getWeight();
-}

+ 0 - 11
src/me/hammerle/supersnuvi/gamelogic/pathfinding/IGraph.java

@@ -1,11 +0,0 @@
-package me.hammerle.supersnuvi.gamelogic.pathfinding;
-
-import java.util.Set;
-
-/**
- * main interface for a graph
- */
-public interface IGraph {
-
-    Set<LevelGraphNode> getNodes();
-}

+ 0 - 11
src/me/hammerle/supersnuvi/gamelogic/pathfinding/IModifieableGraph.java

@@ -1,11 +0,0 @@
-package me.hammerle.supersnuvi.gamelogic.pathfinding;
-
-/**
- * modifieable graph, to add/remove nodes
- * after object allocation
- */
-public interface IModifieableGraph {
-
-    void addNode(INode node);
-    void removeNode(INode node);
-}

+ 0 - 11
src/me/hammerle/supersnuvi/gamelogic/pathfinding/IModifieableNode.java

@@ -1,11 +0,0 @@
-package me.hammerle.supersnuvi.gamelogic.pathfinding;
-
-/**
- * interface for a modifieable node in a graph
- * allows to change edges after object creation
- */
-interface IModifieableNode {
-
-    void addEdge(IEdge edge);
-    void removeEdge(IEdge edge);
-}

+ 0 - 11
src/me/hammerle/supersnuvi/gamelogic/pathfinding/INode.java

@@ -1,11 +0,0 @@
-package me.hammerle.supersnuvi.gamelogic.pathfinding;
-
-import java.util.Set;
-
-/**
- * main interface for a node for graphs
- */
-public interface INode {
-
-    Set<? extends IEdge> getEdges();
-}

+ 80 - 19
src/me/hammerle/supersnuvi/gamelogic/pathfinding/LevelGraph.java

@@ -1,38 +1,99 @@
 package me.hammerle.supersnuvi.gamelogic.pathfinding;
 
+import org.jgrapht.Graph;
+import org.jgrapht.GraphPath;
+import org.jgrapht.alg.shortestpath.ALTAdmissibleHeuristic;
+import org.jgrapht.alg.shortestpath.AStarShortestPath;
+import org.jgrapht.graph.DefaultUndirectedWeightedGraph;
+import org.jgrapht.graph.DefaultWeightedEdge;
+
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 
-/**
- * level representation as graph
- * used to apply path finding for entities
- */
-public class LevelGraph implements IGraph, IModifieableGraph {
+public class LevelGraph {
+
+    protected Map<String, LevelGraphVertex> vertices;
+    protected Graph<LevelGraphVertex, DefaultWeightedEdge> graph;
+
+    private LevelGraphVertexCalculator vertexCalculator;
+
+    public LevelGraph() {
+
+        vertices = new HashMap<>();
+        graph = new DefaultUndirectedWeightedGraph<>(DefaultWeightedEdge.class);
+
+        vertexCalculator = new LevelGraphVertexCalculator();
+    }
+
+    public void addVertex(int x, int y){
+
+        String key = generateKeyForVertex(x, y);
+
+        if(!vertices.containsKey(key)){
+
+            LevelGraphVertex vertex = new LevelGraphVertex(x, y);
+
+            vertices.put(key, vertex);
 
-    private Set<LevelGraphNode> nodes;
+            graph.addVertex(vertex);
+        }
+    }
+
+//    public void removeVertex(int x, int y){
+//
+//        String key = generateKeyForVertex(x, y);
+//
+//        if(vertices.containsKey(key)){
+//
+//            graph.removeVertex(vertices.get(key));
+//            vertices.remove(key);
+//        }
+//    }
+
+    private LevelGraphVertex getVertexAt(int x, int y){
 
-    public LevelGraph(){
+        String key = generateKeyForVertex(x, y);
 
-        nodes = new HashSet<>();
+        return vertices.getOrDefault(key, null);
     }
 
+    public void addEdge(int startX, int startY, int endX, int endY){
 
-    @Override
-    public Set<LevelGraphNode> getNodes() {
-        return nodes;
+        LevelGraphVertex start = getVertexAt(startX, startY);
+        LevelGraphVertex end = getVertexAt(endX, endY);
+
+        if(start != null && end != null){
+
+            DefaultWeightedEdge edge = graph.addEdge(start, end);
+            graph.setEdgeWeight(edge, vertexCalculator.calculateWeightBetween(start, end));
+        }
     }
 
-    @Override
-    public void addNode(INode node) {
+    public Object doo() {
+
 
-        if(node instanceof LevelGraphNode)
-            nodes.add((LevelGraphNode) node);
+        Set<LevelGraphVertex> landmarks = new HashSet<>();
+
+        for(LevelGraphVertex vertex : vertices.values()){
+
+            landmarks.add(vertex);
+        }
+
+        ALTAdmissibleHeuristic<LevelGraphVertex, DefaultWeightedEdge> heuristic = new ALTAdmissibleHeuristic<>(graph, landmarks);
+        AStarShortestPath<LevelGraphVertex, DefaultWeightedEdge> astar = new AStarShortestPath<>(graph, heuristic);
+
+        GraphPath<LevelGraphVertex, DefaultWeightedEdge> path = astar.getPath(getVertexAt(36, 10), getVertexAt(32,13));
+
+        return path;
     }
 
-    @Override
-    public void removeNode(INode node) {
+    private String generateKeyForVertex(int x, int y){
+        return x + ":" + y;
+    }
 
-        if(node instanceof LevelGraphNode)
-            nodes.remove(node);
+    Graph<LevelGraphVertex, DefaultWeightedEdge> getGraph() {
+        return graph;
     }
 }

+ 8 - 13
src/me/hammerle/supersnuvi/gamelogic/pathfinding/LevelGraphBuilder.java

@@ -37,32 +37,27 @@ public class LevelGraphBuilder {
 
         if(graphCoordinates.size() == 0) return null;
 
+        graphCoordinates.higherKey(39);
+
         LevelGraph graph = new LevelGraph();
 
         for(final int x : graphCoordinates.keySet()){
 
             for(final int y : graphCoordinates.get(x)){
 
-                LevelGraphNode curr = new LevelGraphNode(x, y);
-                graph.addNode(curr);
-
-                int next_x = graphCoordinates.higherKey(x);
+                graph.addVertex(x, y);
 
-                for(final int next_y : graphCoordinates.getOrDefault(next_x, new ArrayList<Integer>())){
+                Integer next_x = graphCoordinates.higherKey(x);
 
-                    LevelGraphNode next = new LevelGraphNode(next_x, next_y);
+                if(next_x == null) break;
 
-                    IEdge edge = new LevelGraphEdge((LevelGraphNode)curr, (LevelGraphNode)next, 1.0, IDirectedEdge.DIRECTION_DUPLEX);
+                for(final int next_y : graphCoordinates.getOrDefault(next_x, new ArrayList<Integer>())){
 
-                    curr.addEdge(edge);
-                    next.addEdge(edge);
+                    graph.addVertex(next_x, next_y);
 
-                    graph.addNode(next);
+                    graph.addEdge(x, y, next_x, next_y);
                 }
             }
-
-            System.out.println(x);
-            System.out.println(graphCoordinates.get(x));
         }
 
         return graph;

+ 0 - 22
src/me/hammerle/supersnuvi/gamelogic/pathfinding/LevelGraphEdge.java

@@ -1,22 +0,0 @@
-package me.hammerle.supersnuvi.gamelogic.pathfinding;
-
-/**
- * edge of the graph, which represents the level layout
- * used for pathfinding
- */
-public class LevelGraphEdge extends SimpleEdge implements IDirectedEdge {
-
-    protected int direction;
-
-    public LevelGraphEdge(LevelGraphNode node1, LevelGraphNode node2, double weight, int direction) {
-        super(node1, node2, weight);
-
-        this.direction = direction;
-    }
-
-
-    @Override
-    public int getDirection() {
-        return direction;
-    }
-}

+ 0 - 52
src/me/hammerle/supersnuvi/gamelogic/pathfinding/LevelGraphNode.java

@@ -1,52 +0,0 @@
-package me.hammerle.supersnuvi.gamelogic.pathfinding;
-
-import me.hammerle.supersnuvi.util.Pair;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * node of the graph, which represents the level layout
- * used for pathfinding
- */
-public class LevelGraphNode implements INode, IModifieableNode{
-
-    private Pair<Integer, Integer> levelCoordinates;
-    private Set<LevelGraphEdge> edges;
-
-    public LevelGraphNode(int x, int y) {
-
-        levelCoordinates = new Pair<>(x, y);
-        edges = new HashSet<>();
-    }
-
-    public LevelGraphNode(Pair<Integer, Integer> levelCoordinates){
-        this.levelCoordinates = levelCoordinates;
-        edges = new HashSet<>();
-    }
-
-    @Override
-    public void addEdge(IEdge edge) {
-
-        if(edge instanceof LevelGraphEdge)
-            edges.add((LevelGraphEdge) edge);
-    }
-
-    @Override
-    public void removeEdge(IEdge edge) {
-
-        if(edge instanceof LevelGraphEdge)
-            edges.remove(edge);
-    }
-
-    @Override
-    public Set<LevelGraphEdge> getEdges() {
-
-        return edges;
-    }
-
-    @Override
-    public String toString() {
-        return "(" + Integer.toString(levelCoordinates.getLhs()) + ", " + Integer.toString(levelCoordinates.getRhs()) + ")";
-    }
-}

+ 25 - 0
src/me/hammerle/supersnuvi/gamelogic/pathfinding/LevelGraphVertex.java

@@ -0,0 +1,25 @@
+package me.hammerle.supersnuvi.gamelogic.pathfinding;
+
+public class LevelGraphVertex {
+
+    private int x;
+    private int y;
+
+    public LevelGraphVertex(int x, int y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    public int getX() {
+        return x;
+    }
+
+    public int getY() {
+        return y;
+    }
+
+    @Override
+    public String toString() {
+        return "(" + x + ", " + y + ")";
+    }
+}

+ 13 - 0
src/me/hammerle/supersnuvi/gamelogic/pathfinding/LevelGraphVertexCalculator.java

@@ -0,0 +1,13 @@
+package me.hammerle.supersnuvi.gamelogic.pathfinding;
+
+final class LevelGraphVertexCalculator {
+
+    public double calculateWeightBetween(LevelGraphVertex a, LevelGraphVertex b){
+
+        double weight;
+
+        weight = Math.sqrt(Math.pow(a.getX() - b.getX(), 2) + Math.pow(a.getY() - b.getY(), 2));
+
+        return weight;
+    }
+}

+ 0 - 34
src/me/hammerle/supersnuvi/gamelogic/pathfinding/SimpleEdge.java

@@ -1,34 +0,0 @@
-package me.hammerle.supersnuvi.gamelogic.pathfinding;
-
-/**
-* edge of a graph, without direction
-* edge of the graph, which represents the level layout
-* used for pathfinding
-*/
-public class SimpleEdge implements IEdge {
-
-    protected LevelGraphNode node1;
-    protected LevelGraphNode node2;
-    protected double weight;
-
-    public SimpleEdge(LevelGraphNode node1, LevelGraphNode node2, double weight) {
-        this.node1 = node1;
-        this.node2 = node2;
-        this.weight = weight;
-    }
-
-    @Override
-    public INode getNode1() {
-        return node1;
-    }
-
-    @Override
-    public INode getNode2() {
-        return node2;
-    }
-
-    @Override
-    public double getWeight() {
-        return weight;
-    }
-}