def get_smart_move_actions(self, where_pos): creep = self.creep if creep.pos.roomName == where_pos.roomName: # just a regular single-room move return [ScheduledAction.moveTo(creep, where_pos)] limit = 10000 if Game.cpu.tickLimit < limit/1000: print('WARNING:', creep.name, 'cannot pathfind, not enough cpu') return [] result = PathFinder.search( creep.pos, where_pos, { 'plainCost': 2, 'swampCost': 10, 'maxOps': limit, # 1000 ops = 1 CPU #'maxRooms': 16, # max 64 #'maxCost': 123456, } ) # result structure # path An array of RoomPosition objects. # ops Total number of operations performed before this path was calculated. # cost The total cost of the path as derived from plainCost, swampCost and any given CostMatrix instances. # incomplete (flag) if result['ops'] >= 0.1*limit: print('WARNING: get_smart_move_actions() for', creep.name, 'used', result['ops'], 'mCPU to find path to', where_pos, 'in', where_pos.roomName) creep.memory.path = result['path'] return [ScheduledAction.moveByPath(creep, creep.memory.path)]
def _handle_target_roster(self): for type_, filter in self.TARGET_ROSTER: target = creep.pos.findClosestByRange(type_, filter=filter) if target != undefined: if not creep.pos.isNearTo(target): return [ScheduledAction.moveTo(creep, target, priority=20)] return [ScheduledAction.attack(creep, target, priority=19)] return []
def pre_run(self): creep = self.creep if self.debug: creep.say(creep.name[:8] + self.ICON) if creep.memory.path != undefined: return [ScheduledAction.moveByPath(creep, points_to_path(creep.memory.path))] if creep.memory.target_flag != undefined: target_flag_name = creep.memory.target_flag else: target_flag_name = creep.name target = Game.flags[target_flag_name] if target: if creep.pos.isEqualTo(target): if self.REMOVE_FLAG_ON_ARRIVAL: target.remove() else: return [] elif creep.pos.isNearTo(target): structures = target.pos.lookFor(LOOK_STRUCTURES) if len(structures) and structures[0].structureType == STRUCTURE_SPAWN and structures[0].my: structures[0].recycleCreep(creep) target.remove() return [] return self.get_smart_move_actions(target.pos) if creep.memory.room != undefined and creep.memory.room != creep.room.name: target_room = Game.rooms[creep.memory.room] if self.FILL_UP_BEFORE_LEAVING and self.energy(creep) < creep.carryCapacity: pass # don't go anywhere, fill up first elif target_room == undefined or True: # TODO XXX smart actions inhibitor if creep.memory.wp_room != undefined: if creep.room.name == creep.memory.wp_room: del creep.memory.wp_room return [] # just skip a tick else: target_room_name = creep.memory.wp_room elif creep.memory.wp_room2 != undefined: if creep.room.name == creep.memory.wp_room2: del creep.memory.wp_room2 return [] # just skip a tick else: target_room_name = creep.memory.wp_room2 else: target_room_name = creep.memory.room if target_room == undefined: rp = __new__(RoomPosition(23, 23, target_room_name)) else: rp = target_room.controller.pos print(creep, 'is in', creep.room, 'but should be in', target_room_name, 'which we have no eyes on', rp) del creep.memory.source # so that we don't end up getting back to hatchery after using current energy #return self.get_smart_move_actions(rp) return [ScheduledAction.moveTo(creep, rp)] # TODO XXX smart actions inhibitor else: return self.get_smart_move_actions(target_room.controller.pos)
def _run(self): super()._run() creep = self.creep room = creep.room controller = room.controller if controller.my: if creep.pos.isNearTo( controller ) and controller.sign and controller.sign.text != "": creep.signController(controller, "") # TODO: scheduledAction? return [] if not creep.pos.isNearTo(controller): return [ScheduledAction.moveTo(creep, controller)] if controller.owner != undefined or controller.reservation != undefined: # TODO: check if there are any other claimer creeps in this room that we could sync for a bigger bang #find_creeps # filter: creep.my and creep.parts has CLAIM and not creep.pos.isNearTo(controller) return [ScheduledAction.attackController(creep, controller)] return [ScheduledAction.claimController(creep, controller)]
def make_transfer_action(creep, target): amount = min( target.store.getFreeCapacity(RESOURCE_ENERGY), creep.store[RESOURCE_ENERGY], ) if amount >= 1: return ScheduledAction.transfer( creep, target, RESOURCE_ENERGY, amount, )
def _run(self): super()._run() creep = self.creep room = creep.room controller = room.controller actions = [] heals = part_count(creep, 'heal') if heals >= 1 and creep.hitsMax > creep.hits: actions.append(ScheduledAction.heal(creep, creep, priority=1001)) actions.extend(self._handle_target_roster()) return actions
def _get_transfer_to_link_actions(cls, creep, source): link = cls._get_neighboring_nonfull_link(creep) if link and part_count(creep, 'carry') >= 1: #print(creep.name, part_count(creep, 'carry'), creep.store.getFreeCapacity(RESOURCE_ENERGY), link.store.getFreeCapacity(RESOURCE_ENERGY)) if creep.store.getFreeCapacity(RESOURCE_ENERGY) == 0: return [ ScheduledAction.transfer( creep, link, RESOURCE_ENERGY, min( link.store.getFreeCapacity(RESOURCE_ENERGY), creep.store[RESOURCE_ENERGY], )) ] return []
def do_fill(self): creep = self.creep source = self.get_source(creep) def reset_source(): if creep.store.getFreeCapacity( RESOURCE_ENERGY ) < creep.store.getCapacity(RESOURCE_ENERGY) * 0.6: creep.memory.filling = False # XXX HACKS del creep.memory.source if not creep.pos.isNearTo(source): return [ScheduledAction.moveTo(creep, source, reset_source)] if source.amount != None: # dropped resource return [ScheduledAction.pickup(creep, source, reset_source)] elif source.destroyTime != None: # ruin del creep.memory.source # we'll drain it to our capacity all in one tick, lets not try taking it again next tick return [ScheduledAction.withdraw(creep, source, RESOURCE_ENERGY)] elif source.store != undefined and ( source.my == undefined or source.my == True): # container/storage/link/terminal if creep.store.getFreeCapacity( RESOURCE_ENERGY) >= source.store[RESOURCE_ENERGY]: who = creep.room.lookForAt(LOOK_CREEPS, source.pos) if len(who) >= 1: # some creep is currently there if who[0].memory.cls == 'miner': # and it's a miner! # save CPU: don't just stand there and siphon it as it is being filled if Game.time % 10 != 0: # TODO: save even more cpu # but if the room is drained completely, don't wait for the entire pilgrimage # try to unstuck return [] return [ScheduledAction.withdraw(creep, source, RESOURCE_ENERGY) ] # TODO: reset_source doesn't work elif source.my == False and source.store != undefined: # enemy building return [ScheduledAction.withdraw(creep, source, RESOURCE_ENERGY)] else: # a source return [ScheduledAction.harvest(creep, source)]
def _run(self): super()._run() creep = self.creep # If we're full, stop filling up and remove the saved source if creep.memory.filling and self.energy(creep) >= creep.carryCapacity: creep.memory.filling = False del creep.memory.source # If we're empty, start filling again and remove the saved target elif not creep.memory.filling and creep.carry.energy <= 0: creep.memory.filling = True del creep.memory.target if creep.memory.filling: fill_actions = self.do_fill(creep) #if fill_actions[0].method == 'move': # TODO: fill and go move to a new target, but no double transfer return fill_actions # If we have a saved target, use it if creep.memory.target: target = Game.getObjectById(creep.memory.target) if not target: target = self.get_new_target(creep) elif target.energy != undefined and target.energy == target.energyCapacity: # full container, probably someone else filled it last tick or helped filling it target = self.get_new_target(creep) else: target = self.get_new_target(creep) if not target: return [] # If we are targeting a spawn or extension, we need to be directly next to it - otherwise, we can be 3 away. if target.energyCapacity or target.store: is_close = creep.pos.isNearTo(target) else: is_close = creep.pos.inRangeTo(target, 3) def reset_target(): print('WARNING', creep, "reset_target() had to be called on", creep.memory.target) del creep.memory.target if not is_close: actions = [] if target.structureType == STRUCTURE_STORAGE or target.structureType == STRUCTURE_CONTAINER or target.structureType == STRUCTURE_TERMINAL or target.structureType == STRUCTURE_LINK: if not target.store: pass # that's a construction site, not an actual thing #print(creep, 'not gonna repair anything on the way because heading to c-site') #elif target.store[RESOURCE_ENERGY] >= 1000: else: if creep.body[0].type == WORK: # TODO: IN, not body[0] #print(creep, 'gonna try to repair because target >= 1000 and WORK') repair = self._get_nearby_repair_action() if repair: a = ScheduledAction.repair(creep, repair) a.priority = 20 actions.append(a) else: build = self._get_nearby_build_action() if build: actions.append( ScheduledAction.build(creep, build, priority=20)) actions.append( ScheduledAction.moveTo(creep, target, on_error=reset_target)) return actions # If we are targeting a spawn or extension, transfer energy. Otherwise, use upgradeController on it. if target.energyCapacity: actions = [] actions.append( ScheduledAction.transfer(creep, target, RESOURCE_ENERGY, on_error=reset_target)) if target.store.getFreeCapacity(RESOURCE_ENERGY) >= self.energy( creep): actions.extend(self.do_fill(creep)) #print(creep, 'gooooo') # TODO XXX: test it else: # we will fill it to the brim # maybe someone will pull from this container or spawn or something and in the next tick # it would need to be filled again - but in that case we will run self.get_new_target() with # next tick where we know what happened. target = self.get_new_target( creep) # TODO XXX: but this should be a different one! actions.append(ScheduledAction.moveTo(creep, target)) return actions # upgradeController if target.structureType == STRUCTURE_CONTROLLER: actions = [ScheduledAction.upgradeController(creep, target)] if creep.room.controller.ticksToDowngrade < 4000: actions[0].priority = 1000 else: actions[0].priority = 20 fill_actions = self.do_fill(creep) works = part_count(creep, 'work') if works * 1 >= creep.store[ RESOURCE_ENERGY]: # TODO: multiply by upgrade cost per part per tick # there used to be: and fill_actions[0].method == 'withdraw': # here but creeps can move and work in the same tick #actions.append(fill_actions[0]) actions.extend(fill_actions) return actions # build if target.progressTotal: action = ScheduledAction.build(creep, target) action.priority = 200 return [action] if target.store: actions = [ ScheduledAction.transfer(creep, target, RESOURCE_ENERGY, on_error=reset_target) ] #if target.store.getFreeCapacity(RESOURCE_ENERGY) >= self.energy(creep): # #print(creep, 'gooooo2') # TODO XXX: flaps near storage if room really needs refill # actions.extend(self.do_fill(creep)) return actions actions = [] actions.append(ScheduledAction.moveTo(creep, target)) #print('ERROR: not sure what', creep, 'should do with', target) return actions
def _run(self): super()._run() creep = self.creep room = creep.room sources = search_room(room, FIND_SOURCES) containers = search_room( room, FIND_STRUCTURES, lambda x: x.structureType == STRUCTURE_CONTAINER) thing = get_thing_at_coordinates( containers, creep.pos.x, creep.pos.y) # TODO save CPU via lookAt flag = room.lookForAt(LOOK_FLAGS, creep.pos.x, creep.pos.y) if thing or flag != undefined: for source in sources: if creep.pos.isNearTo(source): #print(creep, source.ticksToRegeneration, source.ticksToRegeneration % (works/5) == 0) actions = [] #if creep.store.getCapacity(RESOURCE_ENERGY) > 0 and creep.store[RESOURCE_ENERGY] > 0: # actions.append(ScheduledAction.drop(creep, RESOURCE_ENERGY)) #if creep.store.getCapacity(RESOURCE_ENERGY) > 0 and creep.store.getFreeCapacity(RESOURCE_ENERGY) == 0: # for s in creep.pos.findInRange(FIND_MY_STRUCTURES, 1): # if s.structureType != STRUCTURE_LINK: # continue # if s.store.getFreeCapacity(RESOURCE_ENERGY) > 0: # actions.append( # ScheduledAction.transfer(creep, s, RESOURCE_ENERGY, priority=80) # ) # break # only handle one link dropped = self._get_nearby_dropped_resource(creep) if dropped: dropped = [s for s in dropped if s.pos != creep.pos] if dropped is not None and dropped != undefined: actions.append( ScheduledAction.pickup(creep, dropped[0], lambda: 0)) if self._should_mine(source): miner_container = None structures = room.lookForAt(LOOK_STRUCTURES, creep.pos.x, creep.pos.y) if structures: for structure in structures: if structure.structureType == STRUCTURE_CONTAINER: miner_container = structure if source.energy != 0 and ( creep.store.getFreeCapacity(RESOURCE_ENERGY) >= 1 or creep.store.getCapacity(RESOURCE_ENERGY) == 0 or (miner_container and miner_container.store. getFreeCapacity(RESOURCE_ENERGY) >= 1)): actions.append( ScheduledAction.harvest(creep, source)) # NOTE: this requires EasyCreep if creep.store[ RESOURCE_ENERGY] > 32: # TODO appropriate value repair = self._get_nearby_repair_action() if len(repair) and Game.time % 10 == 0: a = ScheduledAction.repair(creep, repair) a.priority = 20 actions.append(a) else: build = self._get_nearby_build_action() if build: actions.append( ScheduledAction.build(creep, build, priority=20)) if creep.room.controller.pos.inRangeTo( creep.pos.x, creep.pos.y, 3): to_construct = [ s.progressTotal - s.progress for s in room.find(FIND_CONSTRUCTION_SITES) ] if to_construct == 0: actions.append( ScheduledAction.upgradeController( creep, creep.room.controller)) transfer_to_link = self._get_transfer_to_link_actions( creep, source) if len(transfer_to_link) >= 1: actions.extend(transfer_to_link) else: util = self._get_neighboring_nonfull_util(creep) if util: a = make_transfer_action(creep, util) if a: return [a] return actions else: # we are not on a container pass for source in sources: path = creep.room.findPath(source.pos, creep.room.controller.pos, {'ignoreCreeps': True}) if len(path) >= 2: where = path[0] if creep.pos.isEqualTo(where.x, where.y): # mine regardless of whether there is a container or not # other creeps will come and pick it up, use it to build the container actions = [] if self._should_mine(source): actions.append(ScheduledAction.harvest(creep, source)) transfer_to_link = self._get_transfer_to_link_actions( creep, source) if len(transfer_to_link) >= 1: actions.extend(transfer_to_link) return actions else: container = get_close_structure(source.pos, 1, STRUCTURE_CONTAINER) if container != undefined: where = container.pos else: where = path[0] # XXX ? who = room.lookForAt(LOOK_CREEPS, where.x, where.y) actions = [] if len(who) >= 1: # some other creep is currently there if not who[0].my: continue if who[0].memory.cls == 'miner': # and it's a miner! continue # lets try another source elif who[0].pos.isNearTo(creep.pos): actions.append(ScheduledAction.moveTo( who[0], creep.pos, )) #Game.notify( print( 'swapping creeps at a mining station in ' + creep.room.name + ', ' + str(who[0]) + ' for ' + creep.name, 30, ) actions.append( ScheduledAction.moveTo(creep, room.getPositionAt(where.x, where.y))) return actions Game.notify( 'WARNING: ' + creep.name + ' is a miner with no source to mine', 30) return []