Ejemplo n.º 1
0
def aStar(tiles, start, goal, cutoff=100):
   if start == goal:
      return (0, 0)

   pq = PriorityQueue()
   pq.put((0, start))

   backtrace = {}
   cost = {start: 0}

   closestPos = start
   closestHeuristic = l1(start, goal)
   closestCost = closestHeuristic

   while not pq.empty():
      # Use approximate solution if budget exhausted
      cutoff -= 1
      if cutoff <= 0:
         if goal not in backtrace:
            goal = closestPos
         break

      priority, cur = pq.get()

      if cur == goal:
         break

      for nxt in adjacentPos(cur):
         if not inBounds(*nxt, tiles.shape):
            continue
         if tiles[nxt].impassible:
            continue

         newCost = cost[cur] + 1
         if nxt not in cost or newCost < cost[nxt]:
            cost[nxt] = newCost
            heuristic = lInfty(goal, nxt)
            priority = newCost + heuristic

            # Compute approximate solution
            if heuristic < closestHeuristic or (
                    heuristic == closestHeuristic and priority < closestCost):
               closestPos = nxt
               closestHeuristic = heuristic
               closestCost = priority

            pq.put((priority, nxt))
            backtrace[nxt] = cur

   while goal in backtrace and backtrace[goal] != start:
      goal = backtrace[goal]

   sr, sc = start
   gr, gc = goal

   return (gr - sr, gc - sc)
Ejemplo n.º 2
0
def forageDijkstra(tiles, entity, cutoff=100):
   start = entity.pos

   queue = Queue()
   queue.put(start)

   backtrace = {start: None}

   reward    = {start: (entity.resources.food.val, entity.resources.water.val)}
   best      = -1000 
   goal      = start

   while not queue.empty():
      cutoff -= 1
      if cutoff <= 0:
         while goal in backtrace and backtrace[goal] != start:
            goal = backtrace[goal]

         sr, sc = start
         gr, gc = goal

         return (gr - sr, gc - sc)

      cur = queue.get()

      for nxt in adjacentPos(cur):
         if nxt in backtrace:
            continue

         if tiles[nxt].occupied:
            continue

         if not inBounds(*nxt, tiles.shape):
            continue

         food, water = reward[cur]
         food  = max(0, food - 1)
         water = max(0, water - 1)

         if tiles[nxt].state.tex == 'forest':
            food = min(food + entity.resources.food.max//2, entity.resources.food.max) 
         for pos in adjacentPos(nxt):
            if tiles[pos].state.tex == 'water':
               water = min(water + entity.resources.water.max//2, entity.resources.water.max) 
               break

         reward[nxt] = (food, water)

         total = min(food, water)
         if total > best or (
                 total == best and max(food, water) > max(reward[goal])):
            best = total
            goal = nxt

         queue.put(nxt)
         backtrace[nxt] = cur
Ejemplo n.º 3
0
 def getPadded(self, mat, pos, sz, key=lambda e: e):
     ret = np.zeros((2 * sz + 1, 2 * sz + 1), dtype=np.int32)
     R, C = pos
     rt, rb = R - sz, R + sz + 1
     cl, cr = C - sz, C + sz + 1
     for r in range(rt, rb):
         for c in range(cl, cr):
             if utils.inBounds(r, c, self.size):
                 ret[r - rt, c - cl] = key(mat[r, c])
             else:
                 ret[r - rt, c - cl] = 0
     return ret
Ejemplo n.º 4
0
    def call(world, entity, rDelta, cDelta):
        r, c = entity.pos
        rNew, cNew = r + rDelta, c + cDelta
        if world.env.tiles[rNew, cNew].state.index in enums.IMPASSIBLE:
            return
        if not utils.inBounds(rNew, cNew, world.shape):
            return
        if entity.freeze > 0:
            return

        entity._pos = rNew, cNew
        entID = entity.entID

        r, c = entity.lastPos
        world.env.tiles[r, c].delEnt(entID)

        r, c = entity.pos
        world.env.tiles[r, c].addEnt(entID, entity)
Ejemplo n.º 5
0
    def call(world, entity, rDelta, cDelta):
        r, c = entity.base.pos
        entity.history._lastPos = (r, c)
        rNew, cNew = r + rDelta, c + cDelta
        if world.env.tiles[rNew, cNew].state.index in enums.IMPASSIBLE:
            return
        if not utils.inBounds(rNew, cNew, world.shape):
            return
        if entity.status.freeze > 0:
            return

        entity.base.r.update(rNew)
        entity.base.c.update(cNew)
        entID = entity.entID

        r, c = entity.history.lastPos
        world.env.tiles[r, c].delEnt(entID)

        r, c = entity.base.pos
        world.env.tiles[r, c].addEnt(entID, entity)
Ejemplo n.º 6
0
def adjacentMats(tiles, pos):
   return [type(tiles[p].state) for p in adjacentPos(pos)
           if inBounds(*p, tiles.shape)]
Ejemplo n.º 7
0
def adjacentTiles(env, pos):
   return [env.tiles[p] for p in adjacentPos(pos)
           if inBounds(*p, env.size)]
Ejemplo n.º 8
0
def adjacentEmptyPos(env, pos):
   return [p for p in adjacentPos(pos)
           if inBounds(*p, env.size)]
Ejemplo n.º 9
0
def adjacentMats(env, pos):
    return [
        type(env.tiles[p].mat) for p in adjacentPos(pos)
        if utils.inBounds(*p, env.shape)
    ]