def isDiagonalJumpPoint( self: JPS, i: int, j: int, dx: int, dy: int, grid: Map, ) -> bool: down = grid.traversable(i, j, -dx, +dy) and not grid.traversable(i, j, -dx, 0) up = grid.traversable(i, j, +dx, -dy) and not grid.traversable(i, j, 0, -dy) return up or down
def isHorisontalJumpPoint( self: JPS, i: int, j: int, dx: int, dy: int, grid: Map, ) -> bool: up = grid.traversable(i, j, +1, dy) and not grid.traversable(i, j, +1, 0) down = grid.traversable(i, j, -1, dy) and not grid.traversable(i, j, -1, 0) return up or down
def isVerticalJumpPoint( self: JPS, i: int, j: int, dx: int, dy: int, grid: Map, ) -> bool: up = grid.traversable(i, j, dx, +1) and not grid.traversable(i, j, 0, +1) down = grid.traversable(i, j, dx, -1) and not grid.traversable(i, j, 0, -1) return up or down
def getSuccessors( self: JPS, state: Node, goal: Node, grid: Map, k: int, ) -> list: disallowed = self.getDisallowedDirections(state) successors = [ self.getJumpPoint(state.i, state.j, delta[0], delta[1], goal, grid) for delta in grid.getAllowedMovements(state.i, state.j) if delta not in disallowed ] nodes = [ Node( i = successor[0], j = successor[1], h = self.h_func(successor[0], successor[1], goal.i, goal.j), parent = state, k = k, ) for successor in successors if successor is not None ] return nodes
def simpleTest( searcher: BaseSolver, engine, task: str, height: int, width: int, iStart: int, jStart: int, iGoal: int, jGoal: int, open_list: OpenBase, closed_list: ClosedBase, visualise: bool = True, ) -> dict: taskMap = Map().readFromString(task, width, height) start = (iStart, jStart) goal = (iGoal, jGoal) stats = { 'time': None, 'found': False, 'length': None, 'created': 0, } start_time = time.time() found, last_node, closed_list, open_list = engine( searcher, taskMap, start, goal, open_list, closed_list, ) stats['time'] = time.time() - start_time stats['found'] = found stats['created'] = len(closed_list) + len(open_list) if found: path, length = makePath(last_node) stats['length'] = length if visualise: drawResult(taskMap, start, goal, path, closed_list, open_list) return stats
def getSuccessors( self: AStar, state: Node, goal: Node, grid: Map, k: int, ) -> list: nodes = [ Node( i=state.i + dx, j=state.j + dy, h=self.h_func(state.i + dx, state.j + dy, goal.i, goal.j), parent=state, k=k, ) for (dx, dy) in grid.getAllowedMovements(state.i, state.j) ] return nodes
def getJumpPoint( self: JPS, i: int, j: int, dx: int, dy: int, goal: Node, grid: Map, ) -> tuple: if not grid.traversable(i, j, dx, dy): return None base_x, base_y = i + dx, j + dy if (base_x, base_y) == goal: return (base_x, base_y) x, y = base_x, base_y #diag if dx != 0 and dy != 0: while True: if self.isDiagonalJumpPoint(x, y, dx, dy, grid): return (x, y) if self.getJumpPoint(x, y, dx, 0, goal, grid) is not None or \ self.getJumpPoint(x, y, 0, dy, goal, grid) is not None : return (x, y) if not grid.traversable(x, y, dx, dy): return None x += dx y += dy if (x, y) == goal: return (x, y) #horisontal elif dx == 0: while True: if self.isHorisontalJumpPoint(base_x, y, dx, dy, grid): return (base_x, y) if not grid.traversable(base_x, y, dx, dy): return None y += dy if (base_x, y) == goal: return (base_x, y) #vertical else: while True: if self.isVerticalJumpPoint(x, base_y, dx, dy, grid): return (x, base_y) if not grid.traversable(x, base_y, dx, dy): return None x += dx if (x, base_y) == goal: return (x, base_y)
def drawResult( gridMap: Map, start: tuple = None, goal: tuple = None, path: list = None, nodesExpanded=None, nodesOpened=None, ) -> None: def getRectangle( i: int, j: int, k: int, ) -> list: return [j * k, i * k, (j + 1) * k - 1, (i + 1) * k - 1] k = 20 hIm = gridMap.height * k wIm = gridMap.width * k im = Image.new('RGB', (wIm, hIm), color='white') draw = ImageDraw.Draw(im) for i in range(gridMap.height): for j in range(gridMap.width): if gridMap.isObstacle(i, j): draw.rectangle( xy=getRectangle(i, j, k), fill=(70, 80, 80), ) for container, color in zip((nodesOpened, nodesExpanded), ((213, 219, 219), (131, 145, 146))): if container is not None: for node in container: draw.rectangle( xy=getRectangle(node.i, node.j, k), fill=color, width=0, ) if path is not None: for node in filter(None, path): draw.rectangle( xy=getRectangle(node.i, node.j, k), fill=(52, 152, 219) if not gridMap.isObstacle(node.i, node.j) else (230, 126, 34), width=0, ) for keypoint, color in zip((start, goal), ((40, 180, 99), (231, 76, 60))): if keypoint is not None and not gridMap.isObstacle( keypoint[0], keypoint[1]): draw.rectangle( xy=getRectangle(keypoint[0], keypoint[1], k), fill=color, width=0, ) display(im)