예제 #1
0
 def go_to_xy(self, x, y):
     d = int_distance(self.x, self.y, x, y)
     if d > self.radius:
         self.o = int_angle(self.x, self.y, x, y)  # turn toward the goal
         self._reach(d)
     else:
         return True
예제 #2
0
파일: worldunit.py 프로젝트: ctoth/soundrts
 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
예제 #3
0
 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)
예제 #4
0
파일: worldroom.py 프로젝트: ctoth/soundrts
    def _shortest_path_to(self, dest, player):
        """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:
            if hasattr(v, "is_blocked") and v.is_blocked(player, ignore_enemy_walls=True):
                continue
            D[v] = Q[v][0]
            if v == end: break
            
            for w in G[v]:
                if hasattr(w, "is_blocked") and w.is_blocked(player, ignore_enemy_walls=True):
                    continue
                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]
예제 #5
0
 def _ground_graph(self):
     g = {}
     for z in self.squares:
         for e in z.exits:
             g[e] = {}
             for f in z.exits:
                 if f is not e:
                     g[e][f] = int_distance(e.x, e.y, f.x, f.y)
             g[e][e.other_side] = 0
     return g
예제 #6
0
 def action_reach_and_stop(self):
     target = self.action_target
     if not self._near_enough(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 - self._collision_range(target))
     else:
         self.walked = []
         self.target = None
예제 #7
0
 def _ground_graph(self):
     g = {}
     for z in self.squares:
         for e in z.exits:
             g[e] = {}
             for f in z.exits:
                 if f is not e:
                     g[e][f] = int_distance(e.x, e.y, f.x, f.y)
             g[e][e.other_side] = 0
     return g
예제 #8
0
파일: world.py 프로젝트: thgcode/soundrts
 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
예제 #9
0
파일: world.py 프로젝트: ctoth/soundrts
 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
예제 #10
0
 def _water_graph(self):
     g = {}
     for z in self.squares:
         g[z] = {}
         if not z.is_water:
             continue
         # This is not perfect. Some diagonals will be missing.
         if [z2 for z2 in z.strict_neighbors if not z2.is_water]:
             n = z.strict_neighbors
         else:
             n = z.neighbors
         for z2 in n:
             if not z2.is_water:
                 continue
             g[z][z2] = int_distance(z.x, z.y, z2.x, z2.y)
     return g  
예제 #11
0
 def _water_graph(self):
     g = {}
     for z in self.squares:
         g[z] = {}
         if not z.is_water:
             continue
         # This is not perfect. Some diagonals will be missing.
         if [z2 for z2 in z.strict_neighbors if not z2.is_water]:
             n = z.strict_neighbors
         else:
             n = z.neighbors
         for z2 in n:
             if not z2.is_water:
                 continue
             g[z][z2] = int_distance(z.x, z.y, z2.x, z2.y)
     return g
예제 #12
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)
예제 #13
0
    def _shortest_path_to(self, dest, plane, player, places=False, avoid=False):
        """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 avoid:
            avoid = player.is_very_dangerous
        else:
            avoid = lambda x: False
        if dest is self:
            return [self] if places else (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[plane]
        if plane == "ground":
            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:
            if hasattr(v, "is_blocked") and v.is_blocked(player, ignore_enemy_walls=True) or avoid(v):
                continue
            D[v] = Q[v][0]
            if v == end: break
            
            for w in G[v]:
                if hasattr(w, "is_blocked") and w.is_blocked(player, ignore_enemy_walls=True) or avoid(w):
                    continue
                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
        if plane == "ground":
            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:
            # no path exists
            return [] if places else (None, None)
        Path = []
        while 1:
            Path.append(end)
            if end == start: break
            end = P[end]
        Path.reverse()
        if places:
            return [e.place for e in Path if hasattr(e, "other_side")]
        else:
            return Path[1], D[dest]