Skip to content

Commit 5e3bfbc

Browse files
committed
fix pathfinding with passable borders
1 parent 6fbbe21 commit 5e3bfbc

6 files changed

Lines changed: 40 additions & 12 deletions

File tree

pathfinding/finder/best_first.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ def __init__(self, heuristic=None, weight=1,
3232

3333
self.weighted = False
3434

35-
def apply_heuristic(self, node_a, node_b, heuristic=None):
35+
def apply_heuristic(self, node_a, node_b, heuristic=None, graph=None):
3636
return super(BestFirst, self).apply_heuristic(
37-
node_a, node_b, heuristic) * 1000000
37+
node_a, node_b, heuristic, graph=graph) * 1000000

pathfinding/finder/dijkstra.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def __init__(self, weight=1,
1515
time_limit=time_limit,
1616
max_runs=max_runs)
1717

18-
def apply_heuristic(self, node_a, node_b, heuristic=None):
18+
def apply_heuristic(self, node_a, node_b, heuristic=None, graph=None):
1919
"""
2020
helper function to apply heuristic
2121
"""

pathfinding/finder/finder.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import heapq # used for the so colled "open list" that stores known nodes
22
import time # for time limitation
3+
from ..core.grid import Grid
34
from ..core.diagonal_movement import DiagonalMovement
45
from ..core.heap import SimpleHeap
56

@@ -56,15 +57,24 @@ def __init__(self, heuristic=None, weight=1,
5657
self.start_time = 0 # execution time limitation
5758
self.runs = 0 # count number of iterations
5859

59-
def apply_heuristic(self, node_a, node_b, heuristic=None):
60+
def apply_heuristic(self, node_a, node_b, heuristic=None, graph=None):
6061
"""
6162
helper function to apply heuristic
6263
"""
6364
if not heuristic:
6465
heuristic = self.heuristic
65-
return heuristic(
66-
abs(node_a.x - node_b.x),
67-
abs(node_a.y - node_b.y))
66+
67+
dx = abs(node_a.x - node_b.x)
68+
dy = abs(node_a.y - node_b.y)
69+
70+
if isinstance(graph, Grid):
71+
if graph.passable_left_right_border and dx > graph.width / 2:
72+
dx = graph.width - dx
73+
74+
if graph.passable_up_down_border and dy > graph.height / 2:
75+
dy = graph.height - dy
76+
77+
return heuristic(dx, dy)
6878

6979
def find_neighbors(self, grid, node, diagonal_movement=None):
7080
'''
@@ -110,7 +120,7 @@ def process_node(
110120
if not node.opened or ng < node.g:
111121
old_f = node.f
112122
node.g = ng
113-
node.h = node.h or self.apply_heuristic(node, end)
123+
node.h = node.h or self.apply_heuristic(node, end, graph=graph)
114124
# f is the estimated total cost from start to goal
115125
node.f = node.g + node.h
116126
node.parent = parent

pathfinding/finder/ida_star.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def search(self, node, g, cutoff, path, depth, end, grid):
4747

4848
self.nodes_visited += 1
4949

50-
f = g + self.apply_heuristic(node, end) * self.weight
50+
f = g + self.apply_heuristic(node, end, graph=grid) * self.weight
5151

5252
# We've searched too deep for this iteration.
5353
if f > cutoff:
@@ -104,9 +104,9 @@ def find_path(self, start, end, grid):
104104

105105
self.nodes_visited = 0 # for statistics
106106

107-
# initial search depth, given the typical heuristic contraints,
107+
# initial search depth, given the typical heuristic constraints,
108108
# there should be no cheaper route possible.
109-
cutoff = self.apply_heuristic(start, end)
109+
cutoff = self.apply_heuristic(start, end, graph=grid)
110110

111111
while True:
112112
path = []

test/path_test_scenarios.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,20 @@
8585
"expectedDiagonalLength": 12,
8686
"inverse": false,
8787
"weighted": true
88+
},
89+
{
90+
"name": "s6",
91+
"startX": 3,
92+
"startY": 2,
93+
"endX": 0,
94+
"endY": 0,
95+
"matrix": [[0, 0, 0, 0, 0],
96+
[0, 0, 0, 0, 0],
97+
[0, 0, 0, 0, 0],
98+
[0, 0, 0, 0, 0],
99+
[0, 0, 0, 0, 0]],
100+
"expectedLength": 5,
101+
"expectedDiagonalLength": 3,
102+
"passableLeftRightBorder": true
88103
}
89104
]

test/test_path.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
def grid_from_scenario(scenario):
3030
inverse = scenario['inverse'] if 'inverse' in scenario else True
3131
grid = Grid(matrix=scenario['matrix'], inverse=inverse)
32+
if scenario.get('passableLeftRightBorder'):
33+
grid.set_passable_left_right_border()
34+
if scenario.get('passableUpDownBorder'):
35+
grid.set_passable_up_down_border()
3236
start = grid.node(scenario['startX'], scenario['startY'])
3337
end = grid.node(scenario['endX'], scenario['endY'])
3438
return grid, start, end
@@ -67,7 +71,6 @@ def test_path_diagonal():
6771
weighted = False
6872
if 'weighted' in scenario:
6973
weighted = scenario['weighted']
70-
print(dir(find))
7174
if weighted and not finder.weighted:
7275
continue
7376

0 commit comments

Comments
 (0)