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()
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()