7b60882ba3
* lint updates for /d2astar * png issue * debug package * load bmp properly * debug draft * Vector float64 (#565) * Fixed nil pointer in Copy() * Position added Added Floor() and String() methods to Vector. Also added Position which declares an embedded Vector2 and returns various forms of it. * d2vector.Vector2 renamed to d2vector.BigFloat * vector.go renamed to big_float.go * Float64 stub and more renaming * Vector value getters * Separate vector types with initial methods. * Divide and lint warnings. * Distance and Length. * Scale, Abs and Negate. * CompareFloat64Fuzzy delta direction reversed. * Refactor vector_test.go. * Renamed Approx methods. * Distance and Length. * Distance and Length. * Removed BigFloat and Vector, renamed Float64 to Vector, simplified tests. * Angle, SignedAngle and other small functions. * Receiver rename. * SingedAngle and test fixed * Rotate. * SetLength. * Cross. * NinetyAnti and NinetyClock. * Lerp and Clamp. * Reflect and ReflectSurface. * Cardinal convenience functions. * Comments. * Panic on NaN and Inf in Position. * Lint warnings and comments. * D2map lint warnings (#566) * Comments and newlines in engine.go * Comments and newlines in object.go * Comments and newlines in animated_entity.go * Comments and newlines in missile.go * Comments and newlines in npc.go * Comments and newlines in player.go * Removed object.go (incorrectly merged it in during rebase). * Comments and newlines in renderer.go. * Comments and newlines in map_entity.go. * Comments and newlines in walk_mesh.go. * Comments and newlines in viewport.go and tile_cache.go. * Comments and newlines in stamp.go and wilderness_tile_types.go. * Comments and newlines in everything else. * removing inventory grid test for now because it causes builds to fail on github (#570) * Refactored d2enum (#567) * Refactored animation mode enum * More d2enum changes * Refactored tile enum * Refactored weapon class enum * Refactored more enums * Refactored item event enum * Fixed init_functions animation mode * Removed string2enum from MonsterAnimationMode * Refactored ItemStatCost description * Last enum lint errors * Regenerated monster stringer file * compressed image * Replaced restruct with StreamReader (#574) * Fixed bug in palette.go (#575) * Javascript console commands (#572) * Allow the execution of JS from the terminal when hosting a local game or playing a single game Signed-off-by: William Claude <w.claude@thebeat.co> * Reorganise imports on edited files Signed-off-by: William Claude <w.claude@thebeat.co> * Remove Reset Signed-off-by: William Claude <w.claude@thebeat.co> * Add inventory.txt loader, use the records (#573) * adding resource entry for inventory.txt * adding loader for inventory.txt * adding call to inventory.txt loader in d2app * d2game now uses the inventory.txt records for making the inventory panel * removed comments * remove unused files * update go.mod * lint updates for /d2astar * png issue * update go.mod Co-authored-by: danhale-git <36298392+danhale-git@users.noreply.github.com> Co-authored-by: dk <dknuth0101@gmail.com> Co-authored-by: Intyre <Intyre@gmail.com> Co-authored-by: William <1004323+aziule@users.noreply.github.com> |
||
---|---|---|
.. | ||
astar.go | ||
doc.go | ||
goreland_example.go | ||
goreland_test.go | ||
path_test.go | ||
pather_test.go | ||
priority_queue.go | ||
README.md |
D2 A*
A* pathfinding implementation for OpenDiablo2
Forked from go-astar
Changes
- Used sync.Pool to reuse objects created during path-finding. This improves performance by roughly 30% by reducing allocations.
- Added a max cost to prevent searching the entire region for a path.
- If there is no path the target within the max cost, the path found that gets closest to target will be returned. This allows the player to click in inaccessible areas causing the character to run along the edge.
TODO
- Evaluate bi-directional A*, specifically if it would more quickly identify if the user clicked an in inaccessible area (such as an island).
The A* pathfinding algorithm is a pathfinding algorithm noted for its performance and accuracy and is commonly used in game development. It can be used to find short paths for any weighted graph.
A fantastic overview of A* can be found at Amit Patel's Stanford website.
Examples
The following crude examples were taken directly from the automated tests. Please see path_test.go
for more examples.
Key
.
- Plain (movement cost 1)~
- River (movement cost 2)M
- Mountain (movement cost 3)X
- Blocker, unable to move throughF
- From / start positionT
- To / goal position●
- Calculated path
Straight line
.....~...... .....~......
.....MM..... .....MM.....
.F........T. -> .●●●●●●●●●●.
....MMM..... ....MMM.....
............ ............
Around a mountain
.....~...... .....~......
.....MM..... .....MM.....
.F..MMMM..T. -> .●●●MMMM●●●.
....MMM..... ...●MMM●●...
............ ...●●●●●....
Blocked path
............
.........XXX
.F.......XTX -> No path
.........XXX
............
Maze
FX.X........ ●X.X●●●●●●..
.X...XXXX.X. ●X●●●XXXX●X.
.X.X.X....X. -> ●X●X.X●●●●X.
...X.X.XXXXX ●●●X.X●XXXXX
.XX..X.....T .XX..X●●●●●●
Mountain climber
..F..M...... ..●●●●●●●●●.
.....MM..... .....MM...●.
....MMMM..T. -> ....MMMM..●.
....MMM..... ....MMM.....
............ ............
River swimmer
.....~...... .....~......
.....~...... ....●●●.....
.F...X...T.. -> .●●●●X●●●●..
.....M...... .....M......
.....M...... .....M......
Usage
Import the package
import "github.com/beefsack/go-astar"
Implement Pather interface
An example implementation is done for the tests in path_test.go
for the Tile type.
The PathNeighbors
method should return a slice of the direct neighbors.
The PathNeighborCost
method should calculate an exact movement cost for direct neighbors.
The PathEstimatedCost
is a heuristic method for estimating the distance between arbitrary tiles. The examples in the test files use Manhattan distance to estimate orthogonal distance between tiles.
type Tile struct{}
func (t *Tile) PathNeighbors() []astar.Pather {
return []astar.Pather{
t.Up(),
t.Right(),
t.Down(),
t.Left(),
}
}
func (t *Tile) PathNeighborCost(to astar.Pather) float64 {
return to.MovementCost
}
func (t *Tile) PathEstimatedCost(to astar.Pather) float64 {
return t.ManhattanDistance(to)
}
Call Path function
// t1 and t2 are *Tile objects from inside the world.
path, distance, found := astar.Path(t1, t2)
if !found {
log.Println("Could not find path")
}
// path is a slice of Pather objects which you can cast back to *Tile.
Authors
Michael Alexander beefsack@gmail.com Robin Ranjit Chauhan robin@pathwayi.com