Exemple #1
0
 def open_spaces_around(self, flag):
     # type: (Flag) -> int
     if 'osa' not in flag.memory:
         osa = 0
         room = self.hive.get_room(flag.pos.roomName)
         for x in range(flag.pos.x - 1, flag.pos.x + 2):
             for y in range(flag.pos.y - 1, flag.pos.y + 2):
                 if room:
                     if movement.is_block_empty(room, x, y):
                         osa += 1
                 else:
                     if Game.map.getTerrainAt(x, y,
                                              flag.pos.roomName) != 'wall':
                         osa += 1
         flag.memory.osa = osa
     return flag.memory.osa
Exemple #2
0
    def run(self):
        destination = cast(
            Flag, self.targets.get_existing_target(self, target_single_flag))
        if not destination:
            if not self.memory.idle_for:
                self.log("WARNING: Scout does not have destination set!")
                self.memory.idle_for = 1
            else:
                self.memory.idle_for += 1
                if self.memory.idle_for >= 10:
                    self.log("Scout idle for 10 ticks, committing suicide.")
                    self.creep.suicide()
            return

        still_exploring = ('explored_at' not in destination.memory) \
                          or positions.serialize_xy_room_pos(destination.pos) != destination.memory.explored_at

        recalc = False

        if still_exploring:
            # recalculate_path
            if self.memory.rp:
                self.log(
                    "Recalculating path due to circumstances in {}.".format(
                        self.memory.rp))
                self.recalc_military_path(self.home.spawn.pos, destination.pos,
                                          {
                                              "ignore_swamp": True,
                                              "use_roads": False,
                                          })
                del self.memory.rp

            if self.memory.last_room != self.pos.roomName:
                self.memory.last_room = self.pos.roomName
                if self.room.enemy and self.pos.roomName != destination.pos.roomName:
                    self.recalc_military_path(self.home.spawn.pos,
                                              destination.pos, {
                                                  "ignore_swamp": True,
                                                  "use_roads": False,
                                              })
                last_updated = stored_data.get_last_updated_tick(
                    self.pos.roomName)
                if not last_updated or Game.time - last_updated > 100:
                    if movement.is_room_inner_circle_of_sector(
                            self.pos.roomName):
                        lair_count = 0
                        # should be a source keeper room
                        for lair in cast(
                                List[Structure],
                                self.room.find(FIND_HOSTILE_STRUCTURES)):
                            if lair.structureType == STRUCTURE_KEEPER_LAIR:
                                lair_count += 1
                        if lair_count > 0:
                            # recalculate_path_next
                            recalc = True
                            self.memory.rp = self.pos.roomName
                        else:
                            self.log(
                                "WARNING: Scout found no lairs in supposed source keeper room {}! Logic error?"
                                .format(self.pos.roomName))
                    stored_data.update_data(self.room.room)
                self.log("scouted room: {}".format(self.pos.roomName))

        if self.pos.isEqualTo(destination) or \
                (self.pos.isNearTo(destination)
                 and not movement.is_block_empty(self.room, destination.pos.x, destination.pos.y)):
            if still_exploring:
                destination.memory.travel_time = CREEP_LIFE_TIME - self.creep.ticksToLive
                self.log("Arrived at {} ({}), traveling from {} in {} ticks.".
                         format(destination, destination.pos, self.home.spawn,
                                destination.memory.travel_time))
                destination.memory.explored_at = positions.serialize_xy_room_pos(
                    destination.pos)
        elif self.pos.isNearTo(destination):
            self.basic_move_to(destination)
        else:
            self.follow_military_path(self.home.spawn.pos, destination.pos, {
                "ignore_swamp": True,
                "use_roads": False,
            })
            if recalc:
                self.log("Recalculating path due.")
                self.recalc_military_path(self.home.spawn.pos, destination.pos,
                                          {
                                              "ignore_swamp": True,
                                              "use_roads": False
                                          })
        if self.pos.roomName == destination.pos.roomName and destination.memory.activate_attack_in:
            if len(self.room.defense.dangerous_hostiles()) and _.sum(
                    self.room.defense.dangerous_hostiles(),
                    lambda h: h.owner.username != INVADER_USERNAME and _.sum(
                        h.body, lambda p: p.type == ATTACK or p.type ==
                        RANGED_ATTACK or p.type == HEAL)) >= 10:
                rooms_newly_activated = []
                for name in destination.memory.activate_attack_in:
                    activate_attack_in = self.hive.get_room(name)
                    if activate_attack_in:
                        activate_attack_in.defense.activate_live_defenses()
                        rooms_newly_activated.push(name)
                    else:
                        self.log(
                            "WARNING: Couldn't find room {} which flag {} is supposed to alert for attack."
                            .format(name, destination.name))
                if len(rooms_newly_activated):
                    with_mining_op_shutdowns = _.filter(
                        rooms_newly_activated, lambda r: not _.get(
                            Memory, ["rooms", r, "remotes_safe"], False))
                    hostiles = self.room.defense.dangerous_hostiles()
                    message = (
                        "\nDANGER: -----"
                        "\nHostile belonging to player {} detected in room {}. Game time: {}"
                        "\n"
                        "\n{}"
                        "\n"
                        "\nThis has triggered active-defense mode in rooms {}{}."
                        "\nDANGER: -----"
                    ).format(
                        hostiles[0].owner.username,
                        self.pos.roomName,
                        Game.time,
                        "\n".join([
                            "Found hostile with hits {}/{}, owner {}, body [{}]"
                            .format(h.hits, h.hitsMax, h.owner.username,
                                    [("{}:{}".format(p.boost, p.type)
                                      if p.boost else p.type) for p in h.body])
                            for h in hostiles
                        ]),
                        rooms_newly_activated,
                        (", and shut down mining operations in rooms {}".
                         format(with_mining_op_shutdowns)
                         if len(with_mining_op_shutdowns) else ""),
                    )
                    print(message)
                    Game.notify(message)
Exemple #3
0
    def run(self):
        link = self.home.links.main_link
        storage = self.home.room.storage
        if not link or not storage:
            self.log(
                "ERROR: Link manager can't find main link or storage in {}.".
                format(self.home.name))
            self.go_to_depot()
            return False
        # Note: this does assume storage is directly within one space of the main link.
        if 'station_pos' not in self.memory:
            secondary = self.home.links.secondary_link
            best_priority = 0
            best = None
            for x in range(link.pos.x - 1, link.pos.x + 2):
                for y in range(link.pos.y - 1, link.pos.y + 2):
                    if -1 <= x - storage.pos.x <= 1 and -1 <= y - storage.pos.y <= 1 \
                            and (storage.pos.x != x or storage.pos.y != y) \
                            and (link.pos.x != x or link.pos.y != y):
                        if not movement.is_block_empty(self.home, x, y):
                            continue
                        creeps = cast(List[Creep],
                                      self.home.look_at(LOOK_CREEPS, x, y))
                        if len(creeps) != 0:
                            creep = creeps[0]
                            if creep.memory.role == role_link_manager:
                                if self.creep.ticksToLive > creep.ticksToLive:
                                    creep.suicide()
                                else:
                                    self.creep.suicide()
                                    return False
                        pos = __new__(RoomPosition(x, y, self.home.name))
                        priority = 1
                        if secondary and movement.chebyshev_distance_xy(
                                secondary.pos.x, secondary.pos.y, x, y) <= 1:
                            priority += 20
                        if link.pos.x == storage.pos.x == pos.x:
                            priority += 5
                        elif link.pos.y == storage.pos.y == pos.y:
                            priority += 5
                        if priority >= best_priority:
                            best = pos
                            best_priority = priority
            if best is None:
                self.go_to_depot()
                return False
            self.memory.station_pos = best.x | best.y << 6
        current_pos = (self.pos.x | self.pos.y << 6)
        if current_pos != self.memory.station_pos:
            self.move_to(
                __new__(
                    RoomPosition(self.memory.station_pos & 0x3F,
                                 self.memory.station_pos >> 6 & 0x3F,
                                 self.home.name)))
            return False

        if self.ensure_no_minerals():
            return False

        half_capacity = int(self.creep.carryCapacity / 2)
        if self.creep.carry[RESOURCE_ENERGY] != half_capacity:
            # this is not the norm.
            if self.creep.carry[RESOURCE_ENERGY] > half_capacity:
                target = storage
                result = self.creep.transfer(
                    target, RESOURCE_ENERGY,
                    self.creep.carry[RESOURCE_ENERGY] - half_capacity)
                if result == ERR_FULL:
                    target = self.home.links.main_link
                    result = self.creep.transfer(
                        target, RESOURCE_ENERGY,
                        self.creep.carry[RESOURCE_ENERGY] - half_capacity)
                    if result == ERR_FULL:
                        secondary = self.home.links.secondary_link
                        if secondary:
                            target = secondary
                            result = self.creep.transfer(
                                target, RESOURCE_ENERGY,
                                self.creep.carry[RESOURCE_ENERGY] -
                                half_capacity)

                self.ensure_ok(result, "transfer", target, RESOURCE_ENERGY)

            else:
                target = storage
                result = self.creep.withdraw(
                    target, RESOURCE_ENERGY,
                    half_capacity - self.creep.carry[RESOURCE_ENERGY])
                if result == ERR_NOT_ENOUGH_RESOURCES:
                    target = self.home.links.main_link
                    result = self.creep.withdraw(
                        target, RESOURCE_ENERGY,
                        half_capacity - self.creep.carry[RESOURCE_ENERGY])
                    if result == ERR_NOT_ENOUGH_RESOURCES:
                        secondary = self.home.links.secondary_link
                        if secondary:
                            target = secondary
                            result = self.creep.withdraw(
                                target, RESOURCE_ENERGY, half_capacity -
                                self.creep.carry[RESOURCE_ENERGY])
                self.ensure_ok(result, "withdraw", target, RESOURCE_ENERGY)
            return False

        self.home.links.note_link_manager(self)

        return False
Exemple #4
0
    def run(self):
        source_flag = cast(
            Flag,
            self.targets.get_existing_target(self, target_support_miner_mine))
        if not source_flag:
            if not self.memory.idle_for:
                self.log("WARNING: Support miner has no target.")
                self.memory.idle_for = 1
            else:
                self.memory.idle_for += 1
                if self.memory.idle_for >= 10:
                    self.log(
                        "Support miner idle for 10 ticks, committing suicide.")
                    self.creep.suicide()
            return

        if self.creep.hits < self.creep.hitsMax:
            if not len(flags.find_flags(self.room.name, RANGED_DEFENSE)) \
                    or not _.some(self.room.find(FIND_CREEPS), lambda creep: creep.hasActiveBodyparts(HEAL)):
                if self.home.defense.healing_capable() and (
                        self.pos.roomName != self.home.name or self.pos.x > 40
                        or self.pos.y > 40 or self.pos.x < 10
                        or self.pos.y < 10):
                    self.follow_energy_path(source_flag, self.home.spawn)
                    return
                elif not self.creep.getActiveBodyparts(WORK):
                    self.creep.suicide()
                    return
        if self.memory.container_pos:
            sitting_target = positions.deserialize_xy_to_pos(
                self.memory.container_pos, source_flag.pos.roomName)
        else:
            sitting_target = source_flag.pos
        distance_away = self.pos.getRangeTo(source_flag)
        if distance_away > 2:
            if self.pos.roomName == source_flag.pos.roomName:
                if distance_away <= 3:
                    total_mass = self.home.mining.get_ideal_miner_workmass_for(
                        source_flag)
                    if self.creep.getActiveBodyparts(WORK) >= total_mass:
                        other_miner = cast(
                            Dict[str, Creep],
                            _.find(
                                self.room.look_for_in_area_around(
                                    LOOK_CREEPS, source_flag.pos,
                                    1), lambda c: c.creep.my and c.creep.memory
                                .role == role_support_miner and c.creep.
                                ticksToLive < self.creep.ticksToLive))
                        if other_miner:
                            other_miner[LOOK_CREEPS].suicide()
                            del self.memory._move
                self.move_to(sitting_target)
            else:
                self.follow_energy_path(self.home.spawn, sitting_target)
            return False
        elif distance_away > 1:
            creep = cast(
                Optional[Creep],
                _.find(self.room.look_at(LOOK_CREEPS, sitting_target),
                       lambda c: c.my))
            if creep and creep.memory.role == role_support_miner and creep.ticksToLive > 100:
                self.memory.container_pos = None
                sitting_target = source_flag.pos
            self.move_to(sitting_target)
            return False
        if 'container_pos' not in self.memory:
            container = _.find(
                self.room.find_in_range(FIND_STRUCTURES, 1, source_flag.pos),
                lambda s: s.structureType == STRUCTURE_CONTAINER)
            if container:
                self.memory.container_pos = container.pos.x | (
                    container.pos.y << 6)
            else:
                biggest_pile = _.max(
                    self.room.find_in_range(FIND_DROPPED_RESOURCES, 1,
                                            source_flag.pos),
                    lambda e: e.amount)
                if biggest_pile != -Infinity:
                    self.memory.container_pos = biggest_pile.pos.x | (
                        biggest_pile.pos.y << 6)
                else:
                    self.memory.container_pos = None
        if Game.time % 10 == 0 and self.memory.container_pos is not None:
            this_pos_to_check = self.pos.x | self.pos.y << 6  # Transcrypt does this incorrectly in an if statement.
            if this_pos_to_check != self.memory.container_pos:
                pos = __new__(
                    RoomPosition(self.memory.container_pos & 0x3F,
                                 self.memory.container_pos >> 6 & 0x3F,
                                 self.pos.roomName))
                if _.find(
                        self.room.look_at(LOOK_CREEPS,
                                          pos), lambda c: c.my and c.memory.
                        role == role_support_miner and c.ticksToLive > 15):
                    self.memory.container_pos = self.pos.x | self.pos.y << 6
                else:
                    self.basic_move_to(pos)

        sources_list = cast(List[Source],
                            source_flag.pos.lookFor(LOOK_SOURCES))
        if not len(sources_list):
            self.log("Remote mining source flag {} has no sources under it!",
                     source_flag.name)
            return False
        source = sources_list[0]

        # if Game.time % 3 == 2:
        #     ideal_work = source.energyCapacity / ENERGY_REGEN_TIME / HARVEST_POWER
        #     current_work = self.creep.getActiveBodyparts(WORK)
        #     extra_work = current_work - ideal_work
        #     if extra_work != 0:
        #         if extra_work < 0:
        #             current_work = _.sum(self.room.find_in_range(FIND_MY_CREEPS, 1, source_flag.pos),
        #                                  lambda c: c.memory.role == role_miner and c.getActiveBodyparts(WORK))
        #         if current_work > source.energy / (source.ticksToRegeneration - 1) / HARVEST_POWER:
        #             return False  # skip a tick, to spread it out
        result = self.creep.harvest(source)
        if result != OK and result != ERR_NOT_ENOUGH_RESOURCES:
            self.log("Unknown result from mining-creep.harvest({}): {}",
                     source, result)

        if self.creep.carryCapacity:
            if 'link' in self.memory:
                if self.memory.link is None:
                    return False
                else:
                    link = cast(StructureLink,
                                Game.getObjectById(self.memory.link))
                    if link is None or not self.pos.isNearTo(link):
                        del self.memory.link
                        return False
            else:
                all_possible_links = cast(
                    List[Union[StructureStorage, StructureLink]],
                    _.filter(
                        self.room.find(FIND_MY_STRUCTURES), lambda s:
                        (s.structureType == STRUCTURE_LINK or s.structureType
                         == STRUCTURE_STORAGE) and abs(
                             s.pos.x - source_flag.pos.x) <= 2 and abs(
                                 s.pos.y - source_flag.pos.y) <= 2))
                best_priority = 0  # 1-3
                best_spot = None
                link = None
                for x in range(source_flag.pos.x - 1, source_flag.pos.x + 2):
                    for y in range(source_flag.pos.y - 1,
                                   source_flag.pos.y + 2):
                        if movement.is_block_empty(self.room, x, y):
                            link_here = _.find(
                                all_possible_links, lambda s: abs(s.pos.x - x)
                                <= 1 and abs(s.pos.y - y) <= 1)
                            if link_here:
                                if not flags.look_for(
                                        self.room,
                                        __new__(
                                            RoomPosition(
                                                x, y, self.pos.roomName)),
                                        UPGRADER_SPOT):
                                    if _.find(
                                            self.room.look_at(
                                                LOOK_STRUCTURES, x,
                                                y), lambda s: s.structureType
                                            == STRUCTURE_RAMPART):
                                        priority_here = 3
                                    else:
                                        priority_here = 2
                                else:
                                    priority_here = 1
                                if priority_here > best_priority:
                                    best_priority = priority_here
                                    best_spot = x | y << 6
                                    link = link_here
                                if best_priority >= 3:
                                    break
                    if best_priority >= 3:
                        break
                if link:
                    self.memory.link = link.id
                    self.memory.container_pos = best_spot
                else:
                    self.memory.link = None
                return False
            if self.creep.carry[
                    RESOURCE_ENERGY] + self.creep.getActiveBodyparts(
                        WORK) > self.creep.carryCapacity:
                if link.structureType == STRUCTURE_LINK:
                    self.home.links.register_target_deposit(
                        link, self, self.creep.carry[RESOURCE_ENERGY], 1)
                self.creep.transfer(link, RESOURCE_ENERGY)

        return False
Exemple #5
0
    def run(self):
        minerals = cast(List[Mineral], self.home.find(FIND_MINERALS))

        if len(minerals) != 1:
            self.log(
                "MineralMiner's home has an incomprehensible number of minerals: {}! To the depot it is."
                .format(len(minerals)))
            self.go_to_depot()
            return False

        mineral = minerals[0]
        extractor = cast(
            Optional[StructureExtractor],
            _.find(self.home.look_at(LOOK_STRUCTURES, mineral.pos),
                   {'structureType': STRUCTURE_EXTRACTOR}))
        if not extractor or not extractor.my:
            self.log(
                "MineralMiner's mineral at {} does not have an extractor. D:".
                format(mineral.pos))
            self.go_to_depot()
            return False

        if not self.pos.isNearTo(mineral):
            self.move_to(mineral)
            return False

        if extractor.cooldown <= 0 and self.creep.carryCapacity - self.carry_sum() \
                >= 1 * self.creep.getActiveBodyparts(WORK):
            # let's be sure not to drop any on the ground

            result = self.creep.harvest(mineral)
            if result == ERR_NOT_ENOUGH_RESOURCES:
                self.log("Mineral depleted, going to recycle now!")
                self.memory.role = role_recycling
                self.memory.last_role = role_mineral_miner
            elif result != OK:
                self.log("Unknown result from creep.harvest({}): {}".format(
                    mineral, result))

        else:
            if 'container' not in self.memory:
                container = cast(
                    Dict[str, Structure],
                    _.find(
                        self.room.look_for_in_area_around(
                            LOOK_STRUCTURES, mineral.pos, 2), lambda c: c.
                        structure.structureType == STRUCTURE_CONTAINER))
                if container:
                    self.memory.container = container[LOOK_STRUCTURES].id

            if self.memory.container:
                transfer_target = Game.getObjectById(self.memory.container)
                if not self.pos.isNearTo(transfer_target):
                    pos = None
                    for x in range(mineral.pos.x - 1, mineral.pos.x + 2):
                        for y in range(mineral.pos.y - 1, mineral.pos.y + 2):
                            if abs(x - transfer_target.pos.x) <= 1 and abs(y - transfer_target.pos.y) <= 1 \
                                    and movement.is_block_empty(self.room, x, y):
                                pos = __new__(
                                    RoomPosition(x, y, mineral.pos.roomName))
                                break
                        if pos:
                            break
                    if pos:
                        self.basic_move_to(pos)
                        return
            else:
                hauler = _.find(
                    cast(
                        List[Dict[str, Creep]],
                        self.room.look_for_in_area_around(
                            LOOK_CREEPS, self.pos, 1)),
                    lambda c: c.creep.memory.role == role_mineral_hauler)
                if hauler:
                    transfer_target = hauler[LOOK_CREEPS]
                else:
                    return

            resource = _.findKey(self.creep.carry)
            if resource:
                self.creep.transfer(transfer_target, resource)
Exemple #6
0
    def move_to_stage_2(self, target):
        # type: (RoomPosition) -> None
        """
        Stage 2 movement, where we're near the enemy base and we need to keep tight formation.

        The default method is a tight line, recommended to replace this with something more intricate.
        """
        ordered_members = self.members_movement_order()

        self.log("Members {} moving to {} - stage 2.",
                 _.pluck(ordered_members, 'name'), target)

        movement_opts = self.new_movement_opts()

        for i in range(len(ordered_members) - 1, -1, -1):
            if i == 0:
                if not ordered_members[i].pos.isEqualTo(target):
                    if target == self.location:
                        ordered_members[i].follow_military_path(
                            self.find_origin(), target, movement_opts)
                    else:
                        ordered_members[i].move_to(target, movement_opts)
            else:
                next_drone = ordered_members[i - 1]
                this_drone = ordered_members[i]
                if this_drone.pos.isNearTo(
                        next_drone.pos) or movement.is_edge_position(
                            next_drone.pos):
                    if this_drone.creep.fatigue and not movement.is_edge_position(
                            next_drone.pos):
                        self.log("drone {} at {},{} breaking due to fatigue",
                                 i, this_drone.pos.x, this_drone.pos.y)
                        break
                    direction = movement.diff_as_direction(
                        this_drone.pos, next_drone.pos)
                    this_drone.creep.move(direction)
                    this_drone.creep.__direction_moved = direction
                elif movement.is_edge_position(this_drone.pos):
                    this_drone.move_to(next_drone)
                elif movement.chebyshev_distance_room_pos(
                        this_drone.pos, next_drone.pos) > 3 or (
                            movement.chebyshev_distance_room_pos(
                                this_drone.pos, next_drone.pos) > 1
                            and not movement.is_edge_position(next_drone.pos)):
                    this_drone.move_to(next_drone)
                    self.log("drone {} at {},{} breaking due to distance", i,
                             this_drone.pos.x, this_drone.pos.y)
                    break
                else:
                    # for j in range(len(ordered_members) - 1, i, -1):
                    #     ordered_members[j].creep.move(
                    #         movement.diff_as_direction(ordered_members[j], ordered_members[j - 1]))
                    moved = False

                    if movement.chebyshev_distance_room_pos(
                            this_drone.pos, next_drone.pos) == 2:
                        # Note: we are guaranteed not to be in an edge position because if we were, the above
                        # if would be triggered instead! This allows us to ignore the room name of the next pos.
                        next_pos = movement.next_pos_in_direction_to(
                            this_drone.pos, next_drone.pos)
                        if movement.is_block_empty(this_drone.room, next_pos.x,
                                                   next_pos.y):
                            other_creeps_there = cast(
                                List[Creep],
                                this_drone.room.look_at(LOOK_CREEPS, next_pos))
                            other_drone = _.find(other_creeps_there, 'my')
                            if other_drone:
                                other_drone.move(
                                    movement.diff_as_direction(
                                        other_drone.pos, this_drone.pos))
                                this_drone.creep.move(
                                    movement.diff_as_direction(
                                        this_drone.pos, next_drone.pos))
                                moved = True
                            elif not len(other_creeps_there):
                                direction = movement.diff_as_direction(
                                    this_drone.pos, next_drone.pos)
                                this_drone.creep.move(direction)
                                this_drone.creep.__direction_moved = direction
                                moved = True
                    if not moved:
                        this_drone.move_to(next_drone)