Optimize search even further
This commit is contained in:
parent
5fac1d9c25
commit
4680fb6090
62
world.py
62
world.py
|
@ -83,6 +83,13 @@ class World:
|
|||
_diag: int
|
||||
"Real world distance represented by a diagonal movement, in millimeters"
|
||||
|
||||
_lon_scale2: int
|
||||
"Longitudinal scale squared"
|
||||
_lat_scale2: int
|
||||
"Latitudinal scale squared"
|
||||
_diag2: int
|
||||
"Diagonal scale squared"
|
||||
|
||||
def __init__(self,
|
||||
tiles: Sequence[Tuple[Terrain, int]],
|
||||
width: int = 395,
|
||||
|
@ -93,7 +100,11 @@ class World:
|
|||
self.width = width
|
||||
self.lon_scale = lon_scale
|
||||
self.lat_scale = lat_scale
|
||||
self._diag = isqrt(lon_scale * lon_scale + lat_scale * lat_scale)
|
||||
|
||||
self._lon_scale2 = lon_scale * lon_scale
|
||||
self._lat_scale2 = lat_scale * lat_scale
|
||||
self._diag2 = self._lon_scale2 + self._lat_scale2
|
||||
self._diag = isqrt(self._diag2)
|
||||
|
||||
def _adjacency(self, p: Point) -> List[Tuple[Point, int]]:
|
||||
"""
|
||||
|
@ -101,31 +112,31 @@ class World:
|
|||
|
||||
In addition to each point, a number is returned representing the distance as the
|
||||
crow flies between the center of the original point and the center of the adjacent
|
||||
point, in millimeters.
|
||||
point, in millimeters **AND SQUARED**.
|
||||
|
||||
This does not take into account the presence, value, or elevation of tiles
|
||||
represented on these points.
|
||||
|
||||
>>> world = World([], lon_scale=10_290, lat_scale=7_550)
|
||||
>>> world = World([], lon_scale=3, lat_scale=4)
|
||||
>>> world._adjacency(Point(13, 12)) #doctest: +NORMALIZE_WHITESPACE
|
||||
[((12, 11), 12762),
|
||||
((13, 11), 7550),
|
||||
((14, 11), 12762),
|
||||
((12, 12), 10290),
|
||||
((14, 12), 10290),
|
||||
((12, 13), 12762),
|
||||
((13, 13), 7550),
|
||||
((14, 13), 12762)]
|
||||
[((12, 11), 25),
|
||||
((13, 11), 16),
|
||||
((14, 11), 25),
|
||||
((12, 12), 9),
|
||||
((14, 12), 9),
|
||||
((12, 13), 25),
|
||||
((13, 13), 16),
|
||||
((14, 13), 25)]
|
||||
"""
|
||||
return [
|
||||
(Point(p.x - 1, p.y - 1), self._diag ),
|
||||
(Point(p.x , p.y - 1), self.lat_scale),
|
||||
(Point(p.x + 1, p.y - 1), self._diag ),
|
||||
(Point(p.x - 1, p.y ), self.lon_scale),
|
||||
(Point(p.x + 1, p.y ), self.lon_scale),
|
||||
(Point(p.x - 1, p.y + 1), self._diag ),
|
||||
(Point(p.x , p.y + 1), self.lat_scale),
|
||||
(Point(p.x + 1, p.y + 1), self._diag )
|
||||
(Point(p.x - 1, p.y - 1), self._diag2 ),
|
||||
(Point(p.x , p.y - 1), self._lat_scale2),
|
||||
(Point(p.x + 1, p.y - 1), self._diag2 ),
|
||||
(Point(p.x - 1, p.y ), self._lon_scale2),
|
||||
(Point(p.x + 1, p.y ), self._lon_scale2),
|
||||
(Point(p.x - 1, p.y + 1), self._diag2 ),
|
||||
(Point(p.x , p.y + 1), self._lat_scale2),
|
||||
(Point(p.x + 1, p.y + 1), self._diag2 )
|
||||
]
|
||||
|
||||
def __getitem__(self, loc: Point) -> Tuple[Terrain, int]:
|
||||
|
@ -228,33 +239,36 @@ class World:
|
|||
|
||||
And there it is! The travel time returned by the `.neighbors` function!
|
||||
"""
|
||||
loc_terrain, loc_elevation = self[loc]
|
||||
return [
|
||||
(
|
||||
adj_point,
|
||||
(
|
||||
# 2 * Movement speed (seconds / km = microseconds / millimeter)
|
||||
(
|
||||
self[loc][0] +
|
||||
self[adj_point][0]
|
||||
loc_terrain +
|
||||
adj_terrain
|
||||
)
|
||||
|
||||
# * Distance travelled (millimeters) = 2 * Time cost (microseconds)
|
||||
* isqrt(
|
||||
# Crow Distance Squared
|
||||
(crow_distance * crow_distance)
|
||||
crow_distance2
|
||||
# + Elevation Change Squared = 3D distance squared
|
||||
+ self.elevation_difference(loc, adj_point) ** 2
|
||||
+ (loc_elevation - adj_elevation) ** 2
|
||||
)
|
||||
|
||||
# / 2 = Time cost (microseconds)
|
||||
// 2
|
||||
)
|
||||
)
|
||||
for (adj_point, crow_distance) in self._adjacency(loc)
|
||||
for (adj_point, crow_distance2) in self._adjacency(loc)
|
||||
for (adj_terrain, adj_elevation) in (self[adj_point],)
|
||||
if adj_point.x >= 0
|
||||
and adj_point.y >= 0
|
||||
and adj_point.x < self.width
|
||||
and adj_point.y < len(self.tiles) // self.width
|
||||
and adj_terrain < 4294967296
|
||||
]
|
||||
|
||||
def heuristic(self, a: Point, b: Point) -> int:
|
||||
|
|
Loading…
Reference in a new issue