Ejemplo n.º 1
0
 def Update(self):
     "Take one action"
     pc = Global.pc
     #TODO: Generalize this to follow any mob, not just PC.
     if self.state == "wander":
         if self.dir == None:
             self.PickNewDirection()
         if self.mob.can_see_pc:
             self.state = "chase"
             return
         else:
             blocker = self.mob.SquareBlocked(self.mob.x+self.dx, self.mob.y+self.dy)
             if blocker is None:
                 self.mob.Walk(self.dx, self.dy)
                 return
             # The square is blocked; see if it's an openable door:
             if isinstance(blocker, dungeons.Door):
                 if self.mob.can_open_doors:
                     if not blocker.Open(self.mob):
                         # Tried and failed to open the door; waste some time:
                         self.mob.Walk(0, 0)
                     return
             self.PickNewDirection()
             return
     elif self.state == "chase":
         if adjacent(self.mob, pc):
             self.mob.Attack(pc)
             return
         if self.mob.can_see_pc:
             self.tx, self.ty = pc.x, pc.y
         else:
             if (self.mob.x, self.mob.y) == (self.tx, self.ty):
                 # We're at the last place we saw the @, and we still can't see him:
                 log("%s lost sight of its prey." % self.mob.name)
                 self.state = "wander"
                 return
         # We can see the PC, but are not in melee range: use A*:
         path = astar.path(self.mob.x, self.mob.y, self.tx, self.ty, 
                           self.mob.PathfindPass, max_length=10)
         if path:
             dx, dy = path[0][0] - self.mob.x, path[0][1] - self.mob.y
             self.mob.Walk(dx, dy)
             log("%s found a path from (%s, %s) to (%s, %s) %s." % 
                 (self.mob.name, self.mob.x, self.mob.y, self.tx, self.ty, path))
             return
         else:
             log("%s failed pathfinding." % self.mob.name)
             # Pathfinding failed, but we can see the @...just sit there and be mad:
             self.mob.Walk(0, 0)
             return
Ejemplo n.º 2
0
    def get_path(self, start, goal, local=True, unoccupied=False,
            max_path_len=None, max_time=None):
        #log.debug("get_path: g =\n  %s" % str(g))

        if (start, goal) in self.paths:
            log.debug("    returning cached path: %s -> %s" % (start, goal))
            return self.paths[(start, goal)]

        graph_h = self.ants.rows
        graph_w = self.ants.cols
        rmin, rmax = [f(start[0], goal[0]) for f in [min, max]]
        cmin, cmax = [f(start[1], goal[1]) for f in [min, max]]

        in_graph = make_in_graph(rmin, rmax+1, cmin, cmax+1)

        passable = self.ants.passable if not unoccupied else \
            lambda p: self.ants.passable(p) and self.ants.unoccupied(p)

        if local:
            def adjacent(node):
                #log.debug("adjacent: %s" % str(node))
                r, c = node
                return filter(lambda p: in_graph(p) and passable(p),
                        [ (r, c-1), (r, c+1), (r-1, c), (r+1, c) ])
        else:
            def adjacent(node):
                #log.debug("adjacent: %s" % str(node))
                r, c = node
                return filter(passable, [ (r, (c-1) % self.ants.cols),
                                          (r, (c+1) % self.ants.cols),
                                          ((r-1) % self.ants.rows, c),
                                          ((r+1) % self.ants.rows, c) ])

        p = astar.path(self.ants.map, start, goal, adjacent, self.ants.distance,
                astar.h_simple, max_path_len=max_path_len,
                max_time=max_time)
                #astar.h_cross)
        
        #log.debug("get_path: path =\n  %s" % str(p))
        #dump_path("path_%s_%s_%s.dat" % (start, goal, time.time()),
                #graph, start, goal, p, passable=passable)
        return p