Skip to content

Commit

Permalink
utils/graph: Use precalculated paths
Browse files Browse the repository at this point in the history
Instead of calculating the path all the time it'll use paths already calculated once
a Node with a path is found on the loop
  • Loading branch information
xescugc committed Mar 14, 2024
1 parent 80ebcd7 commit 5284cf9
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 3 deletions.
Binary file modified server/assets/wasm/maze-wars.wasm
Binary file not shown.
25 changes: 22 additions & 3 deletions utils/graph/astar.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,37 @@ func (g *Graph) AStar(sx, sy int, d utils.Direction, tx, ty int, atScale bool) [
current.open = false
current.closed = true

// TODO: Check for end
if current.step.Node.ID == tn.ID {
if current.step.Node.ID == tn.ID || current.step.Node.NextStep != nil {
if current.step.Node.NextStep != nil {
current = &queueItem{
step: *current.step.Node.NextStep,
parent: current,
}
for current.step.Node.NextStep != nil {
current = &queueItem{
step: *current.step.Node.NextStep,
parent: current,
}
}
}
// Found a path to the goal.
p := []Step{}
curr := current
for curr != nil {
s := curr.step
s.X = s.Node.X
s.Y = s.Node.Y
curr = curr.parent
// If it's the first node of the path it has
// no parent so we have to check it
if curr != nil {
curr.step.Node.NextStep = &Step{
Node: s.Node,
Facing: s.Facing,
}
}
s.Node = nil
p = append(p, s)
curr = curr.parent
if atScale {
if curr != nil {
dx := s.X - curr.step.Node.X
Expand Down
95 changes: 95 additions & 0 deletions utils/graph/astar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,32 @@ func TestGraph_AStar(t *testing.T) {
Facing: utils.Left,
},
}
enodes := make([]*graph.Node, 0, 0)
for _, s := range esteps {
enodes = append(enodes, g.GetNode(s.X, s.Y))
}
steps := g.AStar(0, 0, utils.Down, 0, 2, !atScale)
require.NotNil(t, steps)
require.NotEmpty(t, steps)
require.Len(t, steps, len(esteps))
assert.Equal(t, esteps, steps)

for i, n := range enodes {
if i == len(enodes)-1 {
assert.Nil(t, n.NextStep)
continue
}
assert.Equal(t, enodes[i+1], n.NextStep.Node)
assert.Equal(t, esteps[i+1].Facing, n.NextStep.Facing)
}

// There is no way for me to know if the NextStep logic is used
// so I'm gonna force another AStar so it uses it
steps = g.AStar(0, 0, utils.Down, 0, 2, !atScale)
require.NotNil(t, steps)
require.NotEmpty(t, steps)
require.Len(t, steps, len(esteps))
assert.Equal(t, esteps, steps)
})
t.Run("WithScale", func(t *testing.T) {
g, err := graph.New(10, 10, 3, 3, 2, 1, 1, 1)
Expand Down Expand Up @@ -148,5 +169,79 @@ func TestGraph_AStar(t *testing.T) {
require.Len(t, steps, len(esteps))
assert.Equal(t, esteps, steps)
})
t.Run("RemoveNextStepWhenAddTower", func(t *testing.T) {
g, err := graph.New(0, 0, 3, 3, 1, 1, 1, 1)
require.NoError(t, err)

_ = g.AStar(0, 0, utils.Down, 0, 2, !atScale)
g.AddTower("id", 0, 1, 1, 1)
for _, yn := range g.Nodes {
for _, n := range yn {
assert.Nil(t, n.NextStep)
}
}
})
t.Run("RemoveNextStepWhenRemoveTower", func(t *testing.T) {
g, err := graph.New(0, 0, 3, 3, 1, 1, 1, 1)
require.NoError(t, err)

g.AddTower("id", 0, 1, 1, 1)
_ = g.AStar(0, 0, utils.Down, 0, 2, !atScale)
g.RemoveTower("id")
for _, yn := range g.Nodes {
for _, n := range yn {
assert.Nil(t, n.NextStep)
}
}
})
t.Run("NotRemoveNextStepWhenRemoveTower_NotFound", func(t *testing.T) {
g, err := graph.New(0, 0, 3, 3, 1, 1, 1, 1)
require.NoError(t, err)
g.AddTower("id", 0, 1, 1, 1)

esteps := []graph.Step{
{
X: 0, Y: 0,
Facing: utils.Down,
},
{
X: 1, Y: 0,
Facing: utils.Right,
},
{
X: 1, Y: 1,
Facing: utils.Down,
},
{
X: 1, Y: 2,
Facing: utils.Down,
},
{
X: 0, Y: 2,
Facing: utils.Left,
},
}
enodes := make([]*graph.Node, 0, 0)
for _, s := range esteps {
enodes = append(enodes, g.GetNode(s.X, s.Y))
}

steps := g.AStar(0, 0, utils.Down, 0, 2, !atScale)
g.RemoveTower("not-found")

require.NotNil(t, steps)
require.NotEmpty(t, steps)
require.Len(t, steps, len(esteps))
assert.Equal(t, esteps, steps)

for i, n := range enodes {
if i == len(enodes)-1 {
assert.Nil(t, n.NextStep)
continue
}
assert.Equal(t, enodes[i+1], n.NextStep.Node)
assert.Equal(t, esteps[i+1].Facing, n.NextStep.Facing)
}
})
})
}
16 changes: 16 additions & 0 deletions utils/graph/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,14 @@ func (g *Graph) AddTower(id string, x, y, w, h int) error {
n.TowerID = id
}

// When a new tower is added we remove all the
// cached paths by removing the Node.NextStep
for _, ny := range g.Nodes {
for _, n := range ny {
n.NextStep = nil
}
}

return nil
}

Expand Down Expand Up @@ -246,5 +254,13 @@ func (g *Graph) RemoveTower(id string) bool {
}
}

if found {
for _, xn := range g.Nodes {
for _, n := range xn {
n.NextStep = nil
}
}
}

return found
}
2 changes: 2 additions & 0 deletions utils/graph/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ type Node struct {

Neighbors []*Node
NeighborSteps []Step

NextStep *Step
}

// GenerateID will generate the ID concatenating X and Y
Expand Down

0 comments on commit 5284cf9

Please sign in to comment.