mirror of
https://github.com/mvvasilev/last_light.git
synced 2025-04-18 20:29:52 +03:00
Fix pathfinding
This commit is contained in:
parent
28cf513b6d
commit
6396c63d73
6 changed files with 48 additions and 20 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1,2 +1,5 @@
|
|||
last_light
|
||||
last_light.exe
|
||||
last_light.exe
|
||||
|
||||
*.prof
|
||||
__debug_bin*
|
Binary file not shown.
|
@ -1,7 +1,6 @@
|
|||
package engine
|
||||
|
||||
import (
|
||||
"math"
|
||||
"slices"
|
||||
)
|
||||
|
||||
|
@ -10,14 +9,12 @@ type pathNode struct {
|
|||
|
||||
parent *pathNode
|
||||
|
||||
g float64 // distance between current node and start node
|
||||
h float64 // heuristic - squared distance from current node to end node
|
||||
f float64 // total cost of this node
|
||||
g int // distance between current node and start node
|
||||
h int // heuristic - squared distance from current node to end node
|
||||
f int // total cost of this node
|
||||
}
|
||||
|
||||
func FindPath(from Position, to Position, maxDistance int, isPassable func(x, y int) bool) *Path {
|
||||
maxDistanceSquared := math.Pow(float64(maxDistance), 2)
|
||||
|
||||
func FindPath(from Position, to Position, isPassable func(x, y int) bool) *Path {
|
||||
var openList = make([]*pathNode, 0)
|
||||
var closedList = make([]*pathNode, 0)
|
||||
|
||||
|
@ -32,6 +29,7 @@ func FindPath(from Position, to Position, maxDistance int, isPassable func(x, y
|
|||
var lastNode *pathNode
|
||||
|
||||
for {
|
||||
|
||||
if len(openList) == 0 {
|
||||
break
|
||||
}
|
||||
|
@ -87,13 +85,8 @@ func FindPath(from Position, to Position, maxDistance int, isPassable func(x, y
|
|||
}
|
||||
|
||||
child.g = currentNode.g + 1
|
||||
|
||||
if child.g > maxDistanceSquared {
|
||||
continue
|
||||
}
|
||||
|
||||
child.h = to.DistanceSquared(child.pos)
|
||||
child.f = float64(child.g) + child.f
|
||||
child.f = child.g + child.h
|
||||
|
||||
// If child is already contained in openList, and has lower g
|
||||
if slices.ContainsFunc(openList, func(el *pathNode) bool { return el.pos.Equals(child.pos) && child.g > el.g }) {
|
||||
|
|
32
engine/pathfinding_test.go
Normal file
32
engine/pathfinding_test.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
package engine
|
||||
|
||||
import (
|
||||
"log"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkPathfinding(b *testing.B) {
|
||||
path := FindPath(
|
||||
PositionAt(0, 0),
|
||||
PositionAt(16, 16),
|
||||
func(x, y int) bool {
|
||||
if x > 6 && x <= 16 && y == 10 {
|
||||
return false
|
||||
}
|
||||
|
||||
if x < 0 || y < 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if x > 16 || y > 16 {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
)
|
||||
|
||||
if path == nil {
|
||||
log.Fatalf("No path could be found")
|
||||
}
|
||||
}
|
|
@ -44,12 +44,12 @@ func (p Position) XY() (int, int) {
|
|||
return p.x, p.y
|
||||
}
|
||||
|
||||
func (p Position) DistanceSquared(pos Position) float64 {
|
||||
return float64((pos.x-p.x)*(pos.x-p.x) + (pos.y-p.y)*(pos.y-p.y))
|
||||
func (p Position) DistanceSquared(pos Position) int {
|
||||
return (pos.x-p.x)*(pos.x-p.x) + (pos.y-p.y)*(pos.y-p.y)
|
||||
}
|
||||
|
||||
func (p Position) Distance(pos Position) float64 {
|
||||
return math.Sqrt(p.DistanceSquared(pos))
|
||||
func (p Position) Distance(pos Position) int {
|
||||
return int(math.Floor(math.Sqrt(float64(p.DistanceSquared(pos)))))
|
||||
}
|
||||
|
||||
func (p Position) Equals(other Position) bool {
|
||||
|
|
|
@ -181,14 +181,14 @@ func (ps *PlayingState) PickUpItemUnderPlayer() {
|
|||
|
||||
func (ps *PlayingState) CalcPathToPlayerAndMove() {
|
||||
distanceToPlayer := ps.someNPC.Position().Distance(ps.player.Position())
|
||||
if distanceToPlayer > 16 {
|
||||
|
||||
if distanceToPlayer > 20 {
|
||||
return
|
||||
}
|
||||
|
||||
pathToPlayer := engine.FindPath(
|
||||
ps.someNPC.Position(),
|
||||
ps.player.Position(),
|
||||
16,
|
||||
func(x, y int) bool {
|
||||
if x == ps.player.Position().X() && y == ps.player.Position().Y() {
|
||||
return true
|
||||
|
|
Loading…
Add table
Reference in a new issue