def go_to_xy(self, x, y): d = int_distance(self.x, self.y, x, y) if d > self.radius: # execute action self.o = int_angle(self.x, self.y, x, y) # turn towards the goal self._reach(d) else: return True
def action_reach_and_use(self): target = self.action_target if not self._near_enough_to_use(target): d = int_distance(self.x, self.y, target.x, target.y) self.o = int_angle(self.x, self.y, target.x, target.y) # turn toward the goal self._reach(d - target.collision_range(self)) else: self.walked = [] target.be_used_by(self)
def _shortest_path_to(self, dest): """Returns the next exit to the shortest path from self to dest and the distance of the shortest path from self to dest.""" # TODO: remove the duplicate exits in the graph if dest is self: return None, 0 ## if not dest.exits: # small optimization ## return None, None # no path exists # add start and end to the graph G = self.world.g for v in (self, dest): G[v] = {} for e in v.exits: G[v][e] = G[e][v] = int_distance(v.x, v.y, e.x, e.y) start = self end = dest # apply Dijkstra's algorithm (with priority list) D = {} # dictionary of final distances P = {} # dictionary of predecessors Q = priorityDictionary() # est.dist. of non-final vert. Q[start] = (0, ) for v in Q: D[v] = Q[v][0] if v == end: break for w in G[v]: vwLength = D[v] + G[v][w] if w in D: pass elif w not in Q or vwLength < Q[w][0]: Q[w] = ( vwLength, int(w.id), ) # the additional value makes the result "cross-machine deterministic" P[w] = v # restore the graph for v in (start, end): del G[v] for e in v.exits: del G[e][v] # exploit the results if end not in P: return None, None # no path exists Path = [] while 1: Path.append(end) if end == start: break end = P[end] Path.reverse() return Path[1], D[dest]
def _shortest_path_to(self, dest): """Returns the next exit to the shortest path from self to dest and the distance of the shortest path from self to dest.""" # TODO: remove the duplicate exits in the graph if dest is self: return None, 0 ## if not dest.exits: # small optimization ## return None, None # no path exists # add start and end to the graph G = self.world.g for v in (self, dest): G[v] = {} for e in v.exits: G[v][e] = G[e][v] = int_distance(v.x, v.y, e.x, e.y) start = self end = dest # apply Dijkstra's algorithm (with priority list) D = {} # dictionary of final distances P = {} # dictionary of predecessors Q = priorityDictionary() # est.dist. of non-final vert. Q[start] = (0,) for v in Q: D[v] = Q[v][0] if v == end: break for w in G[v]: vwLength = D[v] + G[v][w] if w in D: pass elif w not in Q or vwLength < Q[w][0]: Q[w] = (vwLength, int(w.id)) # the additional value makes the result "cross-machine deterministic" P[w] = v # restore the graph for v in (start, end): del G[v] for e in v.exits: del G[e][v] # exploit the results if end not in P: return None, None # no path exists Path = [] while 1: Path.append(end) if end == start: break end = P[end] Path.reverse() return Path[1], D[dest]
def action_fly_to_remote_target(self): dmax = int_distance(self.x, self.y, self.action_target.x, self.action_target.y) self.o = int_angle(self.x, self.y, self.action_target.x, self.action_target.y) # turn toward the goal self._d = self.speed * VIRTUAL_TIME_INTERVAL / 1000 # used by _future_coords and _heuristic_value x, y = self._future_coords(0, dmax) if not self.place.contains(x, y): try: new_place = self.world.get_place_from_xy(x, y) self.move_to(new_place, x, y, self.o) except: exception("problem when flying to a new square") else: self.move_to(self.place, x, y)
def _create_passages(self): for t, squares in self.west_east: for i in squares: passage(self._we_places(i), t) for t, squares in self.south_north: for i in squares: passage(self._sn_places(i), t) self.g = {} for z in self.squares: for e in z.exits: self.g[e] = {} for f in z.exits: if f is not e: self.g[e][f] = int_distance(e.x, e.y, f.x, f.y) self.g[e][e.other_side] = 0
def _d(o): # o.id to make sure that the result is the same on any computer return (int_distance(o.x, o.y, unit.x, unit.y), o.id)