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)
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
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
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)
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)
def adjacentMats(tiles, pos): return [type(tiles[p].state) for p in adjacentPos(pos) if inBounds(*p, tiles.shape)]
def adjacentTiles(env, pos): return [env.tiles[p] for p in adjacentPos(pos) if inBounds(*p, env.size)]
def adjacentEmptyPos(env, pos): return [p for p in adjacentPos(pos) if inBounds(*p, env.size)]
def adjacentMats(env, pos): return [ type(env.tiles[p].mat) for p in adjacentPos(pos) if utils.inBounds(*p, env.shape) ]