[Pathfinding] AStarSearch now avoids walls

This commit is contained in:
Thibaud Gasser 2018-09-30 16:26:19 +02:00
parent 937e72dfcc
commit 5cd6b6d938
3 changed files with 30 additions and 5 deletions

View File

@ -1,5 +1,7 @@
package fr.uha.gasser.pathfinding.algorithm; package fr.uha.gasser.pathfinding.algorithm;
import fr.uha.gasser.pathfinding.model.Grid;
import java.awt.*; import java.awt.*;
import java.util.*; import java.util.*;
import java.util.List; import java.util.List;
@ -8,10 +10,12 @@ class AStarSearch {
private final Node start; private final Node start;
private final Node goal; private final Node goal;
private final Grid grid;
AStarSearch(Node start, Node goal) { AStarSearch(Node start, Node goal, Grid grid) {
this.start = start; this.start = start;
this.goal = goal; this.goal = goal;
this.grid = grid;
} }
@ -57,15 +61,22 @@ class AStarSearch {
private List<Node> getNeighbors(Node current) { private List<Node> getNeighbors(Node current) {
LinkedList<Node> neighbors = new LinkedList<>(); LinkedList<Node> neighbors = new LinkedList<>();
for (Direction direction : Direction.values()) { for (Direction direction : Direction.values()) {
neighbors.add(getNeighbor(current, direction)); final Node neighbor = getNeighbor(current, direction);
// If neighbor is a wall or off the grid (null), don't add it to the list
if (neighbor != null) neighbors.add(neighbor);
} }
return neighbors; return neighbors;
} }
private Node getNeighbor(Node current, Direction direction) { private Node getNeighbor(Node current, Direction direction) {
Node node = new Node(current); final Dimension gridSize = grid.getSize();
node.setLoc(new Point(current.loc.x + direction.x, current.loc.y + direction.y)); final Node node = new Node(current);
final Point loc = new Point(current.loc.x + direction.x, current.loc.y + direction.y);
if (grid.get(loc).isWall()) return null;
// Don't overflow off the grid
if (loc.x > gridSize.width || loc.y > gridSize.height) return null;
node.setLoc(loc);
return node; return node;
} }

View File

@ -1,12 +1,18 @@
package fr.uha.gasser.pathfinding.algorithm; package fr.uha.gasser.pathfinding.algorithm;
import fr.uha.gasser.pathfinding.model.Grid; import fr.uha.gasser.pathfinding.model.Grid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.util.Collections;
import java.util.List; import java.util.List;
public class AStarWorker extends SwingWorker<List<Node>, List<Node>> { public class AStarWorker extends SwingWorker<List<Node>, List<Node>> {
private static final Logger LOGGER = LoggerFactory.getLogger(AStarWorker.class);
private final Node start; private final Node start;
private final Node goal; private final Node goal;
private final Grid target; private final Grid target;
@ -20,7 +26,7 @@ public class AStarWorker extends SwingWorker<List<Node>, List<Node>> {
@Override @Override
protected List<Node> doInBackground() throws Exception { protected List<Node> doInBackground() throws Exception {
AStarSearch aStar = new AStarSearch(start, goal); AStarSearch aStar = new AStarSearch(start, goal, target);
path = aStar.shortestPath(); path = aStar.shortestPath();
return path; return path;
} }
@ -28,6 +34,10 @@ public class AStarWorker extends SwingWorker<List<Node>, List<Node>> {
@Override @Override
protected void done() { protected void done() {
if (this.isCancelled()) return; if (this.isCancelled()) return;
if (path.equals(Collections.EMPTY_LIST)) {
LOGGER.warn("There is no path between the nodes {} and {}.", start, goal);
return;
}
path.forEach(node -> { path.forEach(node -> {
if (! node.loc.equals(goal.loc)) target.setColor(node.loc, Color.BLUE); if (! node.loc.equals(goal.loc)) target.setColor(node.loc, Color.BLUE);
}); });

View File

@ -49,6 +49,10 @@ public class Grid implements Iterable<Cell> {
return new Cell(INVALID, null); return new Cell(INVALID, null);
} }
public final Dimension getSize() {
return size;
}
public void setColor(Point loc, Color color) { public void setColor(Point loc, Color color) {
final Cell c = cells.get(loc.x + size.width * loc.y); final Cell c = cells.get(loc.x + size.width * loc.y);
final JLabel content = c.getContent(); final JLabel content = c.getContent();