Fix pathfinding

This commit is contained in:
Miroslav Vasilev 2024-05-13 01:01:39 +03:00
parent 28cf513b6d
commit 6396c63d73
6 changed files with 48 additions and 20 deletions

5
.gitignore vendored
View file

@ -1,2 +1,5 @@
last_light
last_light.exe
last_light.exe
*.prof
__debug_bin*

Binary file not shown.

View file

@ -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 }) {

View 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")
}
}

View file

@ -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 {

View file

@ -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