From 8f5f5364c2cd97ae11d7751f4fd725b22bf0cefc Mon Sep 17 00:00:00 2001 From: id101010 Date: Thu, 16 Jun 2016 20:37:03 +0200 Subject: [PATCH] Implemented pathfinding between two vertices. --- src/ch/bfh/sevennotseven/Game.java | 112 +++++++++++++++++++++++++-- src/ch/bfh/sevennotseven/Vertex.java | 31 ++++++++ 2 files changed, 137 insertions(+), 6 deletions(-) create mode 100644 src/ch/bfh/sevennotseven/Vertex.java diff --git a/src/ch/bfh/sevennotseven/Game.java b/src/ch/bfh/sevennotseven/Game.java index 1fc367f..a4d376b 100644 --- a/src/ch/bfh/sevennotseven/Game.java +++ b/src/ch/bfh/sevennotseven/Game.java @@ -65,16 +65,77 @@ public class Game { } public boolean doMove(Point src, Point dst){ - if(!canMove(src, dst)) return false; //checking if there is a path from src to dest - if(field[src.x][src.y]==0) return false; + + if(!canMove(src, dst)) { + return false; //checking if there is a path from src to dest + } + + if(field[src.x][src.y]==0) { + return false; + } + field[dst.x][dst.y] = field[src.x][src.y]; field[src.x][src.y] = 0; + nextStep(dst); //cleanup rows or add new blocks + return true; } - public List getPath(Point src, Point dst){ - return null; + /* + * Pathfinding of shortest path between src and dst. + */ + public ArrayList getPath(Point src, Point dst){ + + ArrayList vertices = new ArrayList(); // List of vertices + ArrayList path = new ArrayList(); // Output + + Vertex u = new Vertex(0, src); + Vertex v = new Vertex(0, dst); + int tmp, tmp_i = 0; + int alt = 0; + + for(int i = 0; i < size*size; i++){ + vertices.add(new Vertex(Integer.MAX_VALUE, new Point(i%7,i%7))); // Initialize all vertices + } + + vertices.get(src.x * src.y).setDist(0); // Set distance from source to source + + + while(!vertices.isEmpty()){ // As long as there are vertices + tmp = minDistance(u, vertices); // Get the index of v with the least distance to u + u = vertices.get(tmp); + vertices.remove(tmp); // Remove u from the set of vertices + + for(int i = 0; i < 4; i++){ // for each neighbour of u ... + if(i == 0){ + tmp_i = u.getPrev().x * u.getPrev().y - 7; // neighbour above + } + + if(i == 1){ + tmp_i = u.getPrev().x * u.getPrev().y + 7; // neighbour below + } + + if(i == 2){ + tmp_i = u.getPrev().x * u.getPrev().y - 1; // left neighbour + } + + if(i == 3){ + tmp_i = u.getPrev().x * u.getPrev().y + 1; // right neighbour + } + + if(tmp_i >= 0 && tmp_i <= 49){ + alt = u.getDist() + distanceBetween(u,v); + if(alt < v.getDist()){ // A shorter path has been found + v.setDist(alt); + v.setPrev(u.getPrev()); + path.add(v); + } + } + } + } + + return path; } public boolean doUndo(){ @@ -83,11 +144,18 @@ public class Game { public boolean doFreeMove(Point src, Point dst){ //move without path checking - if(getAvailFreeMoves() <= 0 ) return false; - if(field[src.x][src.y]==0) return false; + if(getAvailFreeMoves() <= 0 ) { + return false; + } + + if(field[src.x][src.y]==0) { + return false; + } + field[dst.x][dst.y] = field[src.x][src.y]; field[src.x][src.y] = 0; nextStep(dst); //cleanup rows or add new blocks + return true; @@ -117,6 +185,38 @@ public class Game { this.populateField(); } + /** + * Calculates the minimal distance between a vertex and a set of vertices. + */ + private int minDistance(Vertex v, ArrayList vertices){ + int dist = Integer.MAX_VALUE; + int tmp = 0; + int out = 0; + + for (int i = 0; i < vertices.size(); i++) { + tmp = distanceBetween(v, vertices.get(i)); + + if(tmp < dist){ + dist = tmp; + out = i; + } + } + + return out; + } + + /** + * Calculates the distance between two vertices. + */ + private int distanceBetween(Vertex v1, Vertex v2){ + int dx = 0; + int dy = 0; + + dx = v2.getPrev().x - v2.getPrev().x; + dy = v2.getPrev().x - v2.getPrev().x; + + return (int) Math.sqrt(dx*dx + dy*dy); + } /** * Calculates the next game step. This method will either call populateField, or it will cleanup blocks diff --git a/src/ch/bfh/sevennotseven/Vertex.java b/src/ch/bfh/sevennotseven/Vertex.java new file mode 100644 index 0000000..1a7cabc --- /dev/null +++ b/src/ch/bfh/sevennotseven/Vertex.java @@ -0,0 +1,31 @@ +package ch.bfh.sevennotseven; + +import java.awt.Point; + +public class Vertex { + + private int dist; + private Point prev; + + public Vertex(int dist, Point prev) { + this.dist = dist; + this.prev = prev; + } + + public void setDist(int dist){ + this.dist = dist; + } + + public void setPrev(Point prev){ + this.prev = prev; + } + + public int getDist(){ + return this.dist; + } + + public Point getPrev(){ + return this.prev; + } + +}