Class DijkstraMap
java.lang.Object
com.github.tommyettinger.gand.GradientGrid<com.github.yellowstonegames.grid.Coord>
com.github.yellowstonegames.seek.DijkstraMap
public class DijkstraMap
extends com.github.tommyettinger.gand.GradientGrid<com.github.yellowstonegames.grid.Coord>
A group of pathfinding algorithms that explore in all directions equally, and are commonly used when there is more
than one valid goal, or when you want a gradient floodfill to mark each cell in an area with its distance from a
goal. This type of pathfinding is called a Dijkstra Map because it produces the same type of grid of
distances from the nearest goal as Dijkstra's Pathfinding Algorithm can, but the actual algorithm used here is
simpler than Dijkstra's Algorithm, and is more comparable to an optimized breadth-first search that doesn't consider
edge costs. You can set more than one goal with
One unique optimization made possible here is for when only one endpoint of a path can change in some section of a game, such as when you want to draw a path from the (stationary) player's current cell to the cell the mouse is over, and the mouse can move quickly. This can be done very efficiently by setting the player as a goal with
This is similar to
As a bit of introduction, this article on RogueBasin can provide some useful information on how these work and how to visualize the information they can produce, while the original article that introduced Dijkstra Maps is an inspiring list of the various features Dijkstra Maps can enable.
You shouldn't use DijkstraMap for all purposes; it can't handle terrains with a cost to enter, and can't handle directional costs like a one-way ledge. For those tasks,
GradientGrid.setGoal(Point2) or GradientGrid.setGoals(Iterable), unlike A*;
having multiple goals enables such features as pathfinding for creatures that can attack targets between a specified
minimum and maximum distance, and the standard uses of Dijkstra Maps such as finding ideal paths to run away. All
these features have some price; when paths are short or unobstructed, A* tends to be faster, though some convoluted
map shapes can slow down A* more than DijkstraMap.
One unique optimization made possible here is for when only one endpoint of a path can change in some section of a game, such as when you want to draw a path from the (stationary) player's current cell to the cell the mouse is over, and the mouse can move quickly. This can be done very efficiently by setting the player as a goal with
GradientGrid.setGoal(Point2), scanning the map to find distances with GradientGrid.scan(Iterable), and then as long as the
player's position is unchanged (and no obstacles are added/moved), you can get the path by calling
GradientGrid.findPathPreScanned(Point2) and giving it the mouse position as a Point2. If various parts of the path can
change instead of just one (such as other NPCs moving around), then you should set a goal or goals and call
GradientGrid.findPath(int, Collection, Collection, Point2, Collection). The parameters for this are used in various methods
in this class with only slight differences: length is the length of path that can be moved "in one go," so 1 for most
roguelikes and more for most strategy games, impassable used for enemies and solid moving obstacles, onlyPassable can
be null in most roguelikes but in strategy games should contain ally positions that can be moved through as long as
no one stops in them (it can also contain terrain that must be jumped over without falling in, like lava), start is
the pathfinding NPC's starting position, and targets is a Collection of Point2 that the NPC should pathfind
toward (it could be just one Point2, with or without explicitly putting it in an array, or it could be more and the
NPC will pick the closest).
This is similar to
GradientGridI2, and both extend GradientGrid, though
this uses Coord where GradientGridI2 uses PointI2.
As a bit of introduction, this article on RogueBasin can provide some useful information on how these work and how to visualize the information they can produce, while the original article that introduced Dijkstra Maps is an inspiring list of the various features Dijkstra Maps can enable.
You shouldn't use DijkstraMap for all purposes; it can't handle terrains with a cost to enter, and can't handle directional costs like a one-way ledge. For those tasks,
Int2UndirectedGraph
or Int2DirectedGraph will be better fits. Int2DirectedGraph and similar versions of
DirectedGraph can handle even very complicated kinds of map.-
Field Summary
Fields inherited from class com.github.tommyettinger.gand.GradientGrid
blocked, blockingRequirement, cachedFearSources, cachedFleeMap, cachedImpassable, cachedLongerPaths, cutShort, DARK, dirs, FLOOR, fresh, frustration, GOAL, goals, gradientMap, height, initialized, mappedCount, measurement, path, physicalMap, rng, WALL, width, workRay -
Constructor Summary
ConstructorsConstructorDescriptionConstruct a DijkstraMap without a level to actually scan.DijkstraMap(char[][] level) Constructor meant to take a char[][] in a simple, classic-roguelike-ish format, where '#' means a wall and anything else (often '.' or ' ') is a walkable tile.DijkstraMap(char[][] level, char alternateWall) Constructor meant to take a char[][] in a simple, classic-roguelike-ish format, where '#' means a wall and anything else (often '.' or ' ') is a walkable tile.DijkstraMap(char[][] level, char alternateWall, com.github.tommyettinger.gand.utils.GridMetric measurement) Constructor meant to take a char[][] in a simple, classic-roguelike-ish format, where '#' means a wall and anything else (often '.' or ' ') is a walkable tile.DijkstraMap(char[][] level, com.github.tommyettinger.gand.utils.GridMetric measurement) Constructor meant to take a char[][] in a simple, classic-roguelike-ish format, where '#' means a wall and anything else (often '.' or ' ') is a walkable tile.DijkstraMap(float[][] level) Used to construct a DijkstraMap from the output of another.DijkstraMap(float[][] level, com.github.tommyettinger.gand.utils.GridMetric measurement) Used to construct a DijkstraMap from the output of another, specifying a distance calculation. -
Method Summary
Modifier and TypeMethodDescriptionprotected com.github.yellowstonegames.grid.Coordacquire(int x, int y) Methods inherited from class com.github.tommyettinger.gand.GradientGrid
acquire, clearGoals, copy, decode, decode, decodeX, decodeY, encode, encode, equals, findAttackPath, findAttackPath, findAttackPath, findFleePath, findFleePath, findFleePath, findPath, findPath, findPath, findPathPreScanned, findPathPreScanned, floodFill, floodFill, getBlockingRequirement, getGoals, getHeight, getMappedCount, getMeasurement, getWidth, hashCode, initialize, initialize, initialize, isWithin, isWithin, partialScan, partialScan, partialScan, partialScan, partialScan, partialScan, reset, resetCell, resetCell, resetMap, scan, scan, scan, scan, scan, scan, setBlockingRequirement, setFresh, setFresh, setGoal, setGoal, setGoal, setGoals, setGoals, setMeasurement, setOccupied, show, show, shuffleDirs, wallQuery, workingEdit, workingEdit
-
Constructor Details
-
DijkstraMap
public DijkstraMap()Construct a DijkstraMap without a level to actually scan. If you use this constructor, you must call an initialize() method before using this class. -
DijkstraMap
public DijkstraMap(float[][] level) Used to construct a DijkstraMap from the output of another. UsesGridMetric.EUCLIDEAN.- Parameters:
level- a 2D float array that was produced byGradientGrid.scan()
-
DijkstraMap
public DijkstraMap(float[][] level, com.github.tommyettinger.gand.utils.GridMetric measurement) Used to construct a DijkstraMap from the output of another, specifying a distance calculation.- Parameters:
level- a 2D float array that was produced byGradientGrid.scan()measurement- the distance calculation to use
-
DijkstraMap
public DijkstraMap(char[][] level) Constructor meant to take a char[][] in a simple, classic-roguelike-ish format, where '#' means a wall and anything else (often '.' or ' ') is a walkable tile. This usesGridMetric.EUCLIDEAN, allowing 8-way movement but preferring orthogonal directions in case of a tie.- Parameters:
level- a 2D char array where '#' indicates a wall and any other char is walkable
-
DijkstraMap
public DijkstraMap(char[][] level, char alternateWall) Constructor meant to take a char[][] in a simple, classic-roguelike-ish format, where '#' means a wall and anything else (often '.' or ' ') is a walkable tile. This usesGridMetric.EUCLIDEAN, allowing 8-way movement but preferring orthogonal directions in case of a tie. You can specify the character used for walls.- Parameters:
level- a 2D char array wherealternateWallindicates a wall and any other char is walkablealternateWall- the char that indicates a wall inlevel
-
DijkstraMap
public DijkstraMap(char[][] level, com.github.tommyettinger.gand.utils.GridMetric measurement) Constructor meant to take a char[][] in a simple, classic-roguelike-ish format, where '#' means a wall and anything else (often '.' or ' ') is a walkable tile. Also takes a distance measurement, which you may want to set toGridMetric.MANHATTANfor 4-way movement only,GridMetric.CHEBYSHEVfor unpredictable 8-way movement orGridMetric.EUCLIDEANfor more reasonable 8-way movement that prefers straight lines. EUCLIDEAN usually looks the most natural.- Parameters:
level- a char[x][y] map where '#' is a wall, and anything else is walkablemeasurement- how this should measure orthogonal vs. diagonal measurement, such asGridMetric.MANHATTANfor 4-way only movement
-
DijkstraMap
public DijkstraMap(char[][] level, char alternateWall, com.github.tommyettinger.gand.utils.GridMetric measurement) Constructor meant to take a char[][] in a simple, classic-roguelike-ish format, where '#' means a wall and anything else (often '.' or ' ') is a walkable tile. Also takes a distance measurement, which you may want to set toGridMetric.MANHATTANfor 4-way movement only,GridMetric.CHEBYSHEVfor unpredictable 8-way movement orGridMetric.EUCLIDEANfor more reasonable 8-way movement that prefers straight lines. EUCLIDEAN usually looks the most natural. You can specify the character used for walls.- Parameters:
level- a char[x][y] map wherealternateWallis a wall, and anything else is walkablealternateWall- the char that indicates a wall inlevelmeasurement- how this should measure orthogonal vs. diagonal measurement, such asGridMetric.MANHATTANfor 4-way only movement
-
-
Method Details
-
acquire
protected com.github.yellowstonegames.grid.Coord acquire(int x, int y) - Specified by:
acquirein classcom.github.tommyettinger.gand.GradientGrid<com.github.yellowstonegames.grid.Coord>
-