Skip to content

Commit

Permalink
#49: Add proper pathfinding taking VBL into account
Browse files Browse the repository at this point in the history
	- Total WIP POC

Task-Url: #49

Signed-off-by: Jamz <[email protected]>
  • Loading branch information
JamzTheMan committed Mar 22, 2018
1 parent a01271d commit 1ac44e1
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 11 deletions.
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ apply plugin: 'com.diffplug.gradle.spotless'
apply plugin: 'javafx-gradle-plugin'

// Current Build version
version = '1.4.4.2'
version = '1.4.4.3'

// Definitions
defaultTasks 'clean', 'build'
Expand All @@ -52,7 +52,7 @@ ext {
branch = git.branch.getCurrent().getName()
gdxVersion = '1.9.6'
box2DLightsVersion = '1.4'
//aiVersion = '1.8.0'
aiVersion = '1.8.1'
}

run {
Expand Down Expand Up @@ -223,7 +223,7 @@ dependencies {
//compile "com.badlogicgames.gdx:gdx-controllers:$gdxVersion"
//compile "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
//compile "com.badlogicgames.ashley:ashley:$ashleyVersion"
//compile "com.badlogicgames.gdx:gdx-ai:$aiVersion"
compile "com.badlogicgames.gdx:gdx-ai:$aiVersion"
//compile "com.badlogicgames.gdx:gdx-bullet:$gdxVersion"

// Declare the dependency for your favourite test framework you want to use in your tests.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public AStarSquareEuclideanWalker(Zone zone, WalkerMetric metric) {
neighborMap = new int[][] { NORTH, EAST, SOUTH, WEST };
break;
case ONE_ONE_ONE:
case ONE_TWO_ONE:
case MANHATTAN:
// promote straight directions to avoid 'only-diagonals' effect
neighborMap = new int[][] { NORTH, EAST, SOUTH, WEST, NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST };
Expand All @@ -57,17 +58,37 @@ public int[][] getNeighborMap(int x, int y) {

@Override
protected double gScore(CellPoint p1, CellPoint p2) {
return metricDistance(p1, p2);
double delta_x = Math.abs(p1.x - p2.x);
double delta_y = Math.abs(p1.y - p2.y);

// if(delta_x > delta_y)
// return 14*delta_y + 10*(delta_x-delta_y);
// else
// return 14*delta_x + 10*(delta_y-delta_x);

return Math.min(delta_x, delta_y) * Math.sqrt(2) + Math.abs(delta_x - delta_y);

// return metricDistance(p1, p2);
}

@Override
protected double hScore(CellPoint p1, CellPoint p2) {
return metricDistance(p1, p2);
double delta_x = Math.abs(p1.x - p2.x);
double delta_y = Math.abs(p1.y - p2.y);

// if(delta_x > delta_y)
// return 14*delta_y + 10*(delta_x-delta_y);
// else
// return 14*delta_x + 10*(delta_y-delta_x);

return Math.min(delta_x, delta_y) * Math.sqrt(2) + Math.abs(delta_x - delta_y);

// return metricDistance(p1, p2);
}

private double metricDistance(CellPoint p1, CellPoint p2) {
int a = p2.x - p1.x;
int b = p2.y - p1.y;
int xDist = p2.x - p1.x;
int yDist = p2.y - p1.y;

final double distance;

Expand All @@ -77,12 +98,14 @@ private double metricDistance(CellPoint p1, CellPoint p2) {
// break;
case MANHATTAN:
case NO_DIAGONALS:
distance = Math.abs(a) + Math.abs(b);
distance = Math.abs(xDist) + Math.abs(yDist);
break;
default:
case ONE_TWO_ONE:
distance = Math.sqrt(xDist * xDist + yDist * yDist);
break;
case ONE_ONE_ONE:
distance = Math.sqrt(a * a + b * b);
distance = Math.sqrt(xDist * xDist + yDist * yDist);
break;
}
return distance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
*/
package net.rptools.maptool.client.walker.astar;

import java.awt.Color;
import java.awt.Rectangle;
import java.awt.geom.Area;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
Expand All @@ -18,11 +22,17 @@
import java.util.Map;
import java.util.Set;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import net.rptools.maptool.client.walker.AbstractZoneWalker;
import net.rptools.maptool.model.CellPoint;
import net.rptools.maptool.model.Label;
import net.rptools.maptool.model.Zone;

public abstract class AbstractAStarWalker extends AbstractZoneWalker {
private static final Logger log = LogManager.getLogger(AbstractAStarWalker.class);

public AbstractAStarWalker(Zone zone) {
super(zone);
}
Expand All @@ -48,24 +58,124 @@ protected List<CellPoint> calculatePath(CellPoint start, CellPoint end) {
openSet.put(openList.get(0), openList.get(0));

AStarCellPoint node = null;
Area vbl = zone.getTopology();

// If end point is in VBL GTFO
//if (vbl.intersects(zone.getGrid().getBounds(end)))
//return null;

long timeOut = System.currentTimeMillis() + 2000;
// log.info("openList size: " + openList.size());

// erase all labels
List<Label> allLabels = zone.getLabels();
for (Label label : allLabels) {
zone.removeLabel(label.getId());
}

while (!openList.isEmpty()) {
if (System.currentTimeMillis() > timeOut) {
log.info("Timing out...");
log.info("openList size now: " + openList.size());
break;
}

node = openList.remove(0);
openSet.remove(node);
if (node.equals(end)) {
break;
}
// int[][] allowedMap = getNeighborMap(node.x, node.y);
int[][] neighborMap = getNeighborMap(node.x, node.y);
// List<int[]> neighborMap = new ArrayList<int[]>();

// Remove any cells that intersect with VBL
// for (int i = 0; i < allowedMap.length; i++) {
// int x = node.x + allowedMap[i][0];
// int y = node.y + allowedMap[i][1];
// AStarCellPoint allowedNode = new AStarCellPoint(x, y);
//
// Rectangle cellBounds = zone.getGrid().getBounds(allowedNode);
// boolean blocksMovement = vbl.intersects(cellBounds);
//
// // System.out.println("Area bonds: " + vbl.getBounds()); // This is in map coords/grid pixels
// System.out.println("x,y:" + x + "," + y + " :: block? " + blocksMovement); // This is in cells, durr
// // System.out.println("cell bounds? " + zone.getGrid().getBounds(neighborNode));
//
// //if (!blocksMovement)
// neighborMap.add(new int[] { x, y });
// }

// System.out.println("Final list size is: " + neighborMap.size());

for (int i = 0; i < neighborMap.length; i++) {
int x = node.x + neighborMap[i][0];
int y = node.y + neighborMap[i][1];
AStarCellPoint neighborNode = new AStarCellPoint(x, y);
if (closedSet.contains(neighborNode)) {
continue;
}

// log.info("isSecondDiag: " + isSecondDiag(node));

neighborNode.parent = node;
neighborNode.gScore = gScore(start, neighborNode);
neighborNode.hScore = hScore(neighborNode, end);
neighborNode.gScore = gScore(node, neighborNode) * 10;
neighborNode.hScore = hScore(neighborNode, end) * 10;

Rectangle cellBounds = zone.getGrid().getBounds(neighborNode);
double perc = 0;

if (vbl.intersects(cellBounds)) {
Area cellArea = new Area(cellBounds);
cellArea.intersect(vbl);
Rectangle overlap = cellArea.getBounds();
perc = 1 + (area(overlap) / area(cellBounds)); // * 100;

neighborNode.gScore = neighborNode.gScore * perc;
neighborNode.hScore = neighborNode.hScore * perc;

// log.debug("overlap % = " + perc);
// if (perc >= 50) {
// neighborNode.gScore = neighborNode.gScore + perc * 1;
// neighborNode.hScore = neighborNode.hScore + perc * 1;
// log.debug("walking around vbl...");
// } else {
// neighborNode.gScore = neighborNode.gScore + perc;
// neighborNode.hScore = neighborNode.hScore + perc;
// }
}

// if(isSecondDiag(node)) {
// Label diag = new Label();
// diag.setLabel("1.5");
// diag.setX(cellBounds.x + 45);
// diag.setY(cellBounds.y + 45);
// diag.setForegroundColor(Color.RED);
// zone.putLabel(diag);
// }

Label gScore = new Label();
Label hScore = new Label();
Label fScore = new Label();

gScore.setLabel("" + Math.round(neighborNode.gScore));
gScore.setX(cellBounds.x + 10);
gScore.setY(cellBounds.y + 10);

hScore.setLabel("" + Math.round(neighborNode.hScore));
hScore.setX(cellBounds.x + 35);
hScore.setY(cellBounds.y + 10);

fScore.setLabel("" + Math.round(neighborNode.gScore + neighborNode.hScore));
fScore.setX(cellBounds.x + 25);
fScore.setY(cellBounds.y + 35);
fScore.setForegroundColor(Color.RED);

// zone.putLabel(gScore);
// zone.putLabel(hScore);
hScore.setLabel("" + perc);
zone.putLabel(hScore);
zone.putLabel(fScore);

if (openSet.containsKey(neighborNode)) {
AStarCellPoint oldNode = openSet.get(neighborNode);
Expand All @@ -91,9 +201,15 @@ protected List<CellPoint> calculatePath(CellPoint start, CellPoint end) {
}
distance = -1;
Collections.reverse(ret);
// log.info(ret);

return ret;
}

private double area(Rectangle r) {
return r.getWidth() * r.getHeight();
}

private void pushNode(List<AStarCellPoint> list, AStarCellPoint node) {
if (list.isEmpty()) {
list.add(node);
Expand Down Expand Up @@ -129,4 +245,41 @@ public int getDistance() {
}
return distance;
}

protected boolean isSecondDiag(AStarCellPoint node) {
List<CellPoint> path = new LinkedList<CellPoint>();
while (node != null) {
path.add(node);
node = node.parent;
}

if (path == null || path.size() == 0)
return false;

int numDiag = 0;

CellPoint previousPoint = null;
for (CellPoint point : path) {
if (previousPoint != null) {
int change = Math.abs(previousPoint.x - point.x) + Math.abs(previousPoint.y - point.y);

switch (change) {
case 1:
break;
case 2:
numDiag++;
break;
default:
assert false : String.format("Illegal path, cells are not contiguous; change=%d", change);
return false;
}
}
previousPoint = point;
}

if ((numDiag % 2) == 0)
return false;
else
return true;
}
}

0 comments on commit 1ac44e1

Please sign in to comment.