Add timeout to pathfinding, optimize
This commit is contained in:
parent
948dd64221
commit
ccdd51aad3
|
@ -183,12 +183,12 @@ NON_SOLID = [
|
||||||
]
|
]
|
||||||
SINGLE_SNOW = 3919
|
SINGLE_SNOW = 3919
|
||||||
|
|
||||||
NON_SOLID_IDS = [SINGLE_SNOW]
|
NON_SOLID_IDS = set([SINGLE_SNOW])
|
||||||
for block_name in NON_SOLID:
|
for block_name in NON_SOLID:
|
||||||
for state in BLOCKS[block_name]['states']:
|
for state in BLOCKS[block_name]['states']:
|
||||||
NON_SOLID_IDS.append(state['id'])
|
NON_SOLID_IDS.add(state['id'])
|
||||||
|
|
||||||
AVOID_IDS = []
|
AVOID_IDS = set()
|
||||||
for block_name in AVOID:
|
for block_name in AVOID:
|
||||||
for state in BLOCKS[block_name]['states']:
|
for state in BLOCKS[block_name]['states']:
|
||||||
AVOID_IDS.append(state['id'])
|
AVOID_IDS.add(state['id'])
|
||||||
|
|
50
bot.py
50
bot.py
|
@ -1,5 +1,6 @@
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
import functools
|
||||||
from math import ceil, floor, hypot
|
from math import ceil, floor, hypot
|
||||||
|
|
||||||
import blocks
|
import blocks
|
||||||
|
@ -11,6 +12,9 @@ from minecraft.networking.packets import Packet, clientbound, serverbound
|
||||||
from minecraft.compat import input
|
from minecraft.compat import input
|
||||||
from minecraft.managers import ChunksManager
|
from minecraft.managers import ChunksManager
|
||||||
|
|
||||||
|
class AStarTimeout(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
class DataManager:
|
class DataManager:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.blocks_states = {}
|
self.blocks_states = {}
|
||||||
|
@ -107,19 +111,41 @@ PARKOUR = [
|
||||||
PARKOUR_WEST,
|
PARKOUR_WEST,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
HYPOT_LUT = {
|
||||||
|
(0, -1): 1.0,
|
||||||
|
(0, 1): 1.0,
|
||||||
|
(1, 0): 1.0,
|
||||||
|
(-1, 0): 1.0,
|
||||||
|
(1, -1): 1.414,
|
||||||
|
(-1, -1): 1.414,
|
||||||
|
(1, 1): 1.414,
|
||||||
|
(-1, 1): 1.414,
|
||||||
|
(0, 2): 2.0,
|
||||||
|
(-2, 0): 2.0,
|
||||||
|
(2, 0): 2.0,
|
||||||
|
(0, -2): 2.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def padd(p1, p2):
|
def padd(p1, p2):
|
||||||
return (p1[0] + p2[0], p1[1] + p2[1], p1[2] + p2[2])
|
return (p1[0] + p2[0], p1[1] + p2[1], p1[2] + p2[2])
|
||||||
|
|
||||||
def pint(p):
|
def pint(p):
|
||||||
return (int(p[0]), int(p[1]), int(p[2]))
|
return (int(p[0]), int(p[1]), int(p[2]))
|
||||||
|
|
||||||
|
# larger started being slower
|
||||||
|
BLOCK_CACHE_SIZE = 2**14
|
||||||
|
|
||||||
class MazeSolver(AStar):
|
class MazeSolver(AStar):
|
||||||
def __init__(self, chunks):
|
def __init__(self, chunks):
|
||||||
self.chunks = chunks
|
self.chunks = chunks
|
||||||
|
self.start_time = time.time()
|
||||||
|
|
||||||
|
@functools.lru_cache(maxsize=BLOCK_CACHE_SIZE)
|
||||||
def bair(self, p):
|
def bair(self, p):
|
||||||
return self.chunks.get_block_at(*p) in blocks.NON_SOLID_IDS
|
return self.chunks.get_block_at(*p) in blocks.NON_SOLID_IDS
|
||||||
|
|
||||||
|
@functools.lru_cache(maxsize=BLOCK_CACHE_SIZE)
|
||||||
def bavoid(self, p):
|
def bavoid(self, p):
|
||||||
return self.chunks.get_block_at(*p) in blocks.AVOID_IDS
|
return self.chunks.get_block_at(*p) in blocks.AVOID_IDS
|
||||||
|
|
||||||
|
@ -225,18 +251,19 @@ class MazeSolver(AStar):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def check_parkour(self, node, offset):
|
def check_parkour(self, node, offset):
|
||||||
if not self.check_ascend(node, offset):
|
|
||||||
return False
|
|
||||||
|
|
||||||
dest = padd(node, offset)
|
dest = padd(node, offset)
|
||||||
half_offset = tuple(int(0.5*x) for x in offset)
|
half_offset = (int(offset[0]/2), offset[1], int(offset[2]/2))
|
||||||
middle = padd(node, half_offset)
|
middle = padd(node, half_offset)
|
||||||
middle_head = padd(middle, BLOCK_ABOVE)
|
|
||||||
|
|
||||||
# dont jump if we can walk instead
|
# dont jump if we can walk instead
|
||||||
if not self.bair(padd(middle, BLOCK_BELOW)):
|
if not self.bair(padd(middle, BLOCK_BELOW)):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if not self.check_ascend(node, offset):
|
||||||
|
return False
|
||||||
|
|
||||||
|
middle_head = padd(middle, BLOCK_ABOVE)
|
||||||
|
|
||||||
if not self.bair(middle_head):
|
if not self.bair(middle_head):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -270,12 +297,16 @@ class MazeSolver(AStar):
|
||||||
if self.check_parkour(node, offset):
|
if self.check_parkour(node, offset):
|
||||||
results.append(padd(node, offset))
|
results.append(padd(node, offset))
|
||||||
|
|
||||||
|
if not results:
|
||||||
|
if time.time() - self.start_time > 2.0:
|
||||||
|
raise(AStarTimeout)
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
def distance_between(self, n1, n2):
|
def distance_between(self, n1, n2):
|
||||||
(x1, y1, z1) = n1
|
(x1, y1, z1) = n1
|
||||||
(x2, y2, z2) = n2
|
(x2, y2, z2) = n2
|
||||||
return hypot(x2 - x1, z2 - z1)
|
return HYPOT_LUT[x2 - x1, z2 - z1]
|
||||||
|
|
||||||
def heuristic_cost_estimate(self, n1, n2):
|
def heuristic_cost_estimate(self, n1, n2):
|
||||||
(x1, y1, z1) = n1
|
(x1, y1, z1) = n1
|
||||||
|
@ -407,10 +438,13 @@ def main(connection, player_info):
|
||||||
s['goal'] = LPoint3f(x=p.location[0], y=p.location[1], z=p.location[2])
|
s['goal'] = LPoint3f(x=p.location[0], y=p.location[1], z=p.location[2])
|
||||||
print('new waypoint:', s['goal'])
|
print('new waypoint:', s['goal'])
|
||||||
|
|
||||||
|
start = time.time()
|
||||||
solution = MazeSolver(player_info.chunks).astar(pint(player_info.pos), pint(s['goal']))
|
solution = MazeSolver(player_info.chunks).astar(pint(player_info.pos), pint(s['goal']))
|
||||||
if solution:
|
if solution:
|
||||||
s['path'] = list(solution)
|
solution = list(solution)
|
||||||
print(s['path'])
|
s['path'] = solution
|
||||||
|
print(len(solution))
|
||||||
|
print(round(time.time() - start, 3), 'seconds')
|
||||||
else:
|
else:
|
||||||
packet = serverbound.play.ChatPacket()
|
packet = serverbound.play.ChatPacket()
|
||||||
packet.message = 'No path found'
|
packet.message = 'No path found'
|
||||||
|
|
Loading…
Reference in New Issue
Block a user