示例#1
0
    def step(self):
        super().before_step()

        if self.at_base() and self.cargo:
            self.emit_event(0, "ORE_DELIVERY", self.cargo, BASE)
            self.cargo = 0

        if self.full():
            self.state = "MOVE_TO_TARGET"
            self.target = self.base.pos()

        if self.state == 'IDLE':
            # Look for explorers and follow one of the nearest ones.
            # If there are none, go to the base.
            agents = self.box_scan(self.mp.P // 2)
            self.energy -= self.mp.P
            explorers = [a for a in agents if EXPLORER in a.group_ids]
            transporters = [a for a in agents if TRANSPORTER in a.group_ids]
            if explorers:
                self.target = random.choice(explorers).pos()
                if transporters:
                    if random.random() < 1 - 1 / (len(transporters) + 1):
                        v = random.choice(transporters).vec_to(self.pos())
                        v = v.normalize(
                        ) if not v.is_zero_vec() else Vec2D.random_dir()
                        v *= 10
                        self.target = self.world.torus(self.pos() + v.round())
            else:
                self.target = self.base.pos()
            self.target = self.base.pos()  # TODO: temp
            self.state = 'MOVE_TO_TARGET'
        elif self.state == 'MOVE_TO_TARGET':
            if self.reached_target():
                self.state = 'IDLE' if not self.ores else 'COLLECT_ORES'
            else:
                if self.move_towards(self.target) or self.move_in_dir(
                        Vec2D.random_grid_dir()):
                    self.energy -= self.mp.Q
        elif self.state == 'COLLECT_ORES':
            ore_idx, ore_pos = self.ores[0]
            if ore_pos == self.pos():
                self.ores.pop(0)
                if self.try_collect_ore(ore_idx):
                    self.cargo += 1
                else:
                    self.failed_collect_attempts += 1
                    if self.failed_collect_attempts >= 2:  # two failed attempts in a row
                        self.ores = []
                if len(self.ores) == 0:
                    self.state = 'IDLE'
                self.energy -= 1
            else:
                if self.move_towards(ore_pos) or self.move_in_dir(
                        Vec2D.random_grid_dir()):
                    self.energy -= 1
        else:
            assert False, "shouldn't reach unknown state: '{}'".format(
                self.state)

        super().after_step()
示例#2
0
    def step(self):
        super().before_step()

        if self.state == "MOVE_TO_TARGET":
            self.color = Colors.GREEN
            if self.reached_target():
                if self.at_base():
                    self.dir = Vec2D.random_dir()
                if self.ore_data:
                    transporters = (self.box_scan(self.mp.P // 2, TRANSPORTER + str(self.company_id)))[:self.mp.S]
                    self.consume_energy(self.mp.P)
                    self.ore_data = (len(transporters), self.ore_data[1])
                    self.state = "EMIT_EVENT_ORE_POS"
                else:
                    self.state = "SCAN"
            else:
                if not self.move_towards(self.target):
                    self.move_in_dir(Vec2D.random_grid_dir())
                    self.consume_energy(self.mp.Q)

        elif self.state == "SCAN":
            self.color = Colors.GREY25
            agents = self.box_scan(self.mp.P // 2)
            self.consume_energy(self.mp.P)
            ores = [a for a in agents if ORE in a.group_ids]
            explorers = [a for a in agents if EXPLORER in a.group_ids]
            transporters = [a for a in agents if TRANSPORTER in a.group_ids]

            if ores:
                rel_ore_pos = [self.vec_to(o.pos()) for o in ores]
                rel_ore_cog = sum(rel_ore_pos, Vec2D()) / len(ores)
                if rel_ore_cog.magnitude() > self.mp.P / 4:
                    # TODO: set max iterations
                    self.color = Colors.MAGENTA
                    self.target = self.world.torus(self.pos() + rel_ore_cog.round())
                    self.state = "MOVE_TO_TARGET"
                else:
                    rel_ore_pos = [self.vec_to(o.pos()) for o in ores]
                    tsm_idx = tsm.iterative_inf_norm_tsm(rel_ore_pos, n=1000)
                    ores = [ores[i] for i in tsm_idx]
                    ore_data = [(o.idx, o.pos()) for o in ores]
                    self.ore_data = (len(transporters), ore_data)
                    if transporters:
                        self.state = "EMIT_EVENT_ORE_POS"
                    else:
                        self.target = self.base.pos()
                        self.state = "MOVE_TO_TARGET"
            elif explorers:
                other_expl = random.choice(explorers)
                dir = other_expl.vec_to(self.pos())
                dir = dir / dir.magnitude() if not dir.is_zero_vec() else Vec2D.random_dir()
                self.target = self.world.torus(other_expl.pos() + (dir * 20).round())
                self.state = "MOVE_TO_TARGET"
            else:
                self.set_new_random_rel_target()
                self.state = "MOVE_TO_TARGET"

        elif self.state == "EMIT_EVENT_ORE_POS":
            self.color = Colors.WHITE
            self.emit_event(self.mp.I // 2, "ORE_POSITIONS", self.ore_data, TRANSPORTER + str(self.company_id))
            self.consume_energy(1)
            self.ore_data = None
            self.set_new_random_rel_target()
            self.state = "MOVE_TO_TARGET"

        super().after_step()