def act(self, view, msg): me = view.get_me() my_pos = (mx, my) = me.get_pos() # first cell only store home plant and work out direction to symmetric team # TODO: handle view.get_plants() somehow not working for the first cell if (self.home == None): self.home = (view.get_plants()[0].x, view.get_plants()[0].y) self.breeder = True # eat if (view.get_energy().get(mx, my) > 0): if (me.energy < 50): return cells.Action(cells.ACT_EAT) # breed if designated if (self.breeder): return cells.Action(cells.ACT_SPAWN, (mx + random.randrange(-1, 2), my + random.randrange(-1, 2), self.home)) # fight if drunk nearby = view.get_agents() for a in nearby: if (a.team != me.team): return cells.Action(cells.ACT_ATTACK, a.get_pos()) # leave home return cells.Action(cells.ACT_MOVE, self.symmetricPos(self.home)) # die pass
def should_attack(self, view, msg): me = view.get_me() count = 0 for a in view.get_agents(): if a.get_team() != me.get_team(): count += 1 if count > 0: currentEnergy = view.get_energy().get(me.x, me.y) if currentEnergy > 20: return cells.Action(cells.ACT_EAT) if self.plant: count = 10 msg.send_message((MessageType.ATTACK, count, self.id, me.x, me.y)) return cells.Action(cells.ACT_ATTACK, a.get_pos()) return None
def act(self,view,msg): x_sum = 0 y_sum = 0 dir = 1 n = len(view.get_plants()) me = view.get_me() mp = (mx,my)= me.get_pos() for a in view.get_agents(): if (a.get_team()!=me.get_team()): msg.send_message(mp) return cells.Action(cells.ACT_ATTACK,a.get_pos()) for m in msg.get_messages(): r = random.random() if ((self.my_plant and random.random()>0.6) or (not self.my_plant and random.random() > 0.5)): self.mode = 5 (tx,ty) = m self.target = (tx+random.randrange(-3,4),ty+random.randrange(-3,4)) if n: best_plant = max(view.get_plants(), key=lambda x: x.eff) if not self.my_plant or self.my_plant.eff < best_plant.eff: self.my_plant = view.get_plants()[0] self.mode = 0 if self.mode == 5: dist = max(abs(mx-self.target[0]),abs(my-self.target[1])) self.target_range = max(dist,self.target_range) if me.energy > dist*1.5: self.mode = 6 if self.mode == 6: dist = max(abs(mx-self.target[0]),abs(my-self.target[1])) if dist > 4: return cells.Action(cells.ACT_MOVE,self.target) else: self.my_plant = None self.mode = 0 if (me.energy < self.target_range) and (view.get_energy().get(mx, my) > 0): return cells.Action(cells.ACT_EAT) if self.my_plant: dist = max(abs(mx-self.my_plant.get_pos()[0]),abs(my-self.my_plant.get_pos()[1])) if me.energy < dist*1.5: (mx,my) = self.my_plant.get_pos() return cells.Action(cells.ACT_MOVE,(mx+random.randrange(-1,2),my+random.randrange(-1,2))) if (random.random()>0.9999): (mx,my) = self.my_plant.get_pos() dtheta = random.random() * 2 * math.pi dr = random.randrange(100) curr_r, curr_theta = cmath.polar(mx + my*1j) m = cmath.rect(curr_r + dr, curr_theta + dtheta) msg.send_message((m.real, m.imag)) if (random.random()>0.9 and me.energy >= 50): return cells.Action(cells.ACT_SPAWN,(mx+random.randrange(-1,2),my+random.randrange(-1,2))) else: return cells.Action(cells.ACT_MOVE,(mx+random.randrange(-1,2),my+random.randrange(-1,2)))
def act(self, view, msg): # x_sum = 0 # y_sum = 0 dir = 1 me = view.get_me() (mx, my) = me.get_pos() # Attack any opponents. for a in view.get_agents(): if a.get_team() != me.get_team(): return cells.Action(cells.ACT_ATTACK, a.get_pos()) # Attach to the strongest plant found. if view.get_plants(): plant = view.get_plants()[0] if not self.my_plant: self.my_plant = plant elif self.my_plant.eff < plant.eff: self.my_plant = plant # Eat if hungry or if this is an exceptionally energy-rich spot. hungry = (me.energy < self.target_range) energy_here = view.get_energy().get(mx, my) food = (energy_here > 0) if hungry and food or energy_here > 100: return cells.Action(cells.ACT_EAT) if self.my_plant: plant_pos = self.my_plant.get_pos() plant_dist = self.length(abs(mx - plant_pos[0]), abs(my - plant_pos[1])) if (not me.loaded and (plant_dist % 5 or abs(mx - plant_pos[0]) < 2) and random.random() > 0.5): return cells.Action(cells.ACT_LIFT) if me.loaded and plant_dist % 5 == 0 and abs(mx - plant_pos[0]) >= 2: return cells.Action(cells.ACT_DROP) if me.energy < plant_dist * 1.5: (mx, my) = plant_pos pos = (mx + random.randrange(-1, 2), my + random.randrange(-1, 2)) return cells.Action(cells.ACT_MOVE, pos) pos = (mx + random.randrange(-1, 2), my + random.randrange(-1, 2)) action = cells.ACT_SPAWN if random.random() > 0.9 else cells.ACT_MOVE return cells.Action(action, pos)
def act_scout(self, view, msg): me = view.get_me() if self.x is None: self.choose_new_direction(view, msg) currentEnergy = view.get_energy().get(me.x, me.y) # Grabbing a plant is the most important thing, we get this we win plants = view.get_plants() if plants: plant = (plants[0]).get_pos() if plant != self.plant: if self.plants.count(plant) == 0: #print "Found a new plant, resetting time: " + str(len(self.plants)) msg.send_message( (MessageType.FOUNDPLANT, 0, self.id, me.x, me.y)) self.plants.append(plant) self.time = 0 self.plant = plant self.type = Type.PARENT self.search = None #print str(len(self.plants)) + " " + str(me.get_team()) return self.act_parent(view, msg) else: # Don't let this go to waste if currentEnergy >= 3: return cells.Action(cells.ACT_EAT) if self.search: if me.energy > 100: spawn_x, spawn_y = self.smart_spawn(me, view) return cells.Action(cells.ACT_SPAWN, (me.x + spawn_x, me.y + spawn_y, self)) if (currentEnergy > 3): return cells.Action(cells.ACT_EAT) # Make sure we wont die if (me.energy < 25 and currentEnergy > 1): return cells.Action(cells.ACT_EAT) # hit world wall, bounce back map_size = view.energy_map.width if me.x <= 0 or me.x >= map_size - 1 or me.y <= 0 or me.y >= map_size - 1: self.choose_new_direction(view, msg) # If I get the message of help go and rescue! if self.step == 0 and (not self.search) and (random.random() > 0.2): ax = 0 ay = 0 best = 300 + self.time / 2 message_count = len(msg.get_messages()) for m in msg.get_messages(): (type, count, id, ox, oy) = m if (id == self.id and type == MessageType.ATTACK): dist = abs(me.x - ax) + abs(me.y - ay) if count >= 2: dist /= count if dist < best and dist > 1: ax = ox ay = oy best = dist if (ax != 0 and ay != 0): dir = ax - me.x + (ay - me.y) * 1j r, theta = cmath.polar(dir) theta += 0.1 * random.random() - 0.5 dir = cmath.rect(r, theta) self.x = dir.real self.y = dir.imag # if (message_count > 1) : # # Attack the base, not the front # agent_scale = 1 + random.random() # self.x *= agent_scale # self.y *= agent_scale # don't stand still once we get there if (self.x == 0 and self.y == 0): self.x = random.randrange(-2, 2) self.y = random.randrange(-2, 2) self.step = random.randrange( 1, min(30, max(2, int((best + 2) / 2)))) self.rescue = True if not self.rescue and me.energy > cells.SPAWN_MIN_ENERGY and me.energy < 100: spawn_x, spawn_y = self.smart_spawn(me, view) return cells.Action(cells.ACT_SPAWN, (me.x + spawn_x, me.y + spawn_y, self)) # Back to step 0 we can change direction at the next attack. if self.step: self.step -= 1 return self.smart_move(view, msg)
def act_parent(self, view, msg): me = view.get_me() plant_pos = (px, py) = self.plant # Make sure the plant is always populated grid = self.get_available_space_grid(me, view) xoffset = -2 yoffset = -2 if self.check(1, 0, view): xoffset = 1 yoffset = 0 # right if self.check(-1, 0, view): xoffset = -1 yoffset = 0 # left if self.check(0, 1, view): xoffset = 0 yoffset = 1 # down if self.check(0, -1, view): xoffset = 0 yoffset = -1 # up if self.check(-1, -1, view): xoffset = -1 yoffset = -1 # diag left if self.check(-1, 1, view): xoffset = -1 yoffset = 1 # diag right if self.check(1, -1, view): xoffset = 1 yoffset = -1 # diag left if self.check(1, 1, view): xoffset = 1 yoffset = 1 # diag right if xoffset != -2: if me.energy < cells.SPAWN_MIN_ENERGY: return cells.Action(cells.ACT_EAT) # When we are populating plant cells we must spawn some children in case we are being attacked # When we are all alone we don't spawn any cheap children and only do high quality cells self.children += 1 return cells.Action(cells.ACT_SPAWN, (me.x + xoffset, me.y + yoffset, self)) # When there are more then two plants always charge up and then leave # when there are less then two plants only half of the cells should charge up and then leave if self.children <= 0: if me.energy >= cells.ENERGY_CAP or me.energy > cells.SPAWN_MIN_ENERGY + self.time + random.randrange( -10, 100): self.type = Type.SCOUT return self.act_scout(view, msg) return cells.Action(cells.ACT_EAT) if me.energy < cells.SPAWN_MIN_ENERGY: return cells.Action(cells.ACT_EAT) self.children -= 1 spawn_x, spawn_y = self.smart_spawn(me, view) return cells.Action(cells.ACT_SPAWN, (me.x + spawn_x, me.y + spawn_y, self))
def smart_move(self, view, msg): me = view.get_me() # make sure we can actually move if me.get_pos() == self.last_pos: self.bumps += 1 else: self.bumps = 0 if self.bumps >= 2: self.choose_new_direction(view, msg) self.last_pos = view.me.get_pos() offsetx = 0 offsety = 0 if self.search: offsetx = random.randrange(-1, 1) offsety = random.randrange(-1, 1) wx = me.x + self.x + offsetx wy = me.y + self.y + offsety grid = self.get_available_space_grid(me, view) bestEnergy = 2 bestEnergyX = -1 bestEnergyY = -1 for x in xrange(3): for y in range(3): if grid[x, y]: e = view.get_energy().get(me.x + x - 1, me.y + y - 1) if e > bestEnergy: bestEnergy = e bestEnergyX = x bestEnergyY = y # Check the desired location first if (wx < me.x): bx = 0 if (wx == me.x): bx = 1 if (wx > me.x): bx = 2 if (wy < me.y): by = 0 if (wy == me.y): by = 1 if (wy > me.y): by = 2 if bx == bestEnergyX and bestEnergy > 1: return cells.Action( cells.ACT_MOVE, (me.x + bestEnergyX - 1, me.y + bestEnergyY - 1)) if by == bestEnergyY and bestEnergy > 1: return cells.Action( cells.ACT_MOVE, (me.x + bestEnergyX - 1, me.y + bestEnergyY - 1)) if grid[bx, by]: return cells.Action(cells.ACT_MOVE, (wx, wy)) if bestEnergy > 1: return cells.Action( cells.ACT_MOVE, (me.x + bestEnergyX - 1, me.y + bestEnergyY - 1)) if grid[2, 0] and random.random() > 0.5: return cells.Action(cells.ACT_MOVE, (me.x + 1, me.y - 1)) for x in xrange(3): for y in range(3): if grid[x, y]: return cells.Action(cells.ACT_MOVE, (x - 1, y - 1)) return cells.Action(cells.ACT_MOVE, (wx, wy))
def Spawn(self, x, y): return cells.Action( cells.ACT_SPAWN, (x + random.randrange(-1, 2), y + random.randrange(-1, 2)))
def act(self, view, msg): if not self.x: self.choose_new_direction(view) me = view.get_me() my_pos = (mx, my) = me.get_pos() # Attack anyone next to me, but first send out the distress message with my position for a in view.get_agents(): if (a.get_team() != me.get_team()): msg.send_message((MessageType.ATTACK, mx, my)) if (me.energy > 2000): spawn_x, spawn_y = self.smart_spawn(me, view) return cells.Action(cells.ACT_SPAWN, (mx + spawn_x, my + spawn_y, self)) return cells.Action(cells.ACT_ATTACK, a.get_pos()) # Eat any energy I find until I am 'full' if (view.get_energy().get(mx, my) > 0): if (me.energy < 50): return cells.Action(cells.ACT_EAT) if (me.energy < self.defense and (random.random() > 0.3)): return cells.Action(cells.ACT_EAT) if (self.scout and me.energy > 1000 and random.random() > 0.5): spawn_x, spawn_y = self.smart_spawn(me, view) return cells.Action(cells.ACT_SPAWN, (mx + spawn_x, my + spawn_y, self)) # If there is a plant near by go to it and spawn all I can if (not self.my_plant): plants = view.get_plants() if (len(plants) > 0): self.my_plant = plants[0] if (self.my_plant and (self.children < 50 or random.random() > 0.9)): self.children += 1 spawn_x, spawn_y = self.smart_spawn(me, view) return cells.Action(cells.ACT_SPAWN, (mx + spawn_x, my + spawn_y, self)) # If I get the message of help go and rescue! map_size = view.energy_map.width if (self.step == 0 and True != self.scout and (random.random() > 0.2)): ax = 0 ay = 0 best = view.energy_map.width + view.energy_map.height message_count = len(msg.get_messages()) for m in msg.get_messages(): (type, ox, oy) = m if (type == MessageType.ATTACK): dist = max(abs(mx - ax), abs(my - ay)) if dist < best: ax = ox ay = oy best = dist if (ax != 0 and ay != 0): self.defense = 2000 self.x = ax - mx self.y = ay - my if (message_count > 1): # Attack the base, not the front agent_offset = random.randrange(1, 50) if (self.x > 0): self.x += agent_offset else: self.x -= agent_offset if (self.y > 0): self.y += agent_offset else: self.y -= agent_offset # Don't stand still once we get there if (self.x == 0 and self.y == 0): self.choose_new_direction(view) self.step = random.randrange(3, 10) # hit world wall if mx <= 0 or mx >= map_size - 1 or my <= 0 or my >= map_size - 1: self.choose_new_direction(view) # Back to step 0 we can change direction at the next attack if (self.step > 0): self.step -= 1 # Move quickly randomly in my birth direction return cells.Action(cells.ACT_MOVE, (mx + self.x + random.randrange(-1, 1), my + self.y + random.randrange(-1, 1)))
def act(self, view, msg): x_sum = 0 y_sum = 0 dir = 1 n = len(view.get_plants()) me = view.get_me() mp = (mx, my) = me.get_pos() for a in view.get_agents(): if (a.get_team() != me.get_team()): return cells.Action(cells.ACT_ATTACK, a.get_pos()) for m in msg.get_messages(): if (random.random() > 0.6) and self.my_plant: self.mode = 5 (tx, ty) = m self.target = (tx + random.randrange(-3, 4), ty + random.randrange(-3, 4)) if (n > 0): if (not self.my_plant): self.my_plant = view.get_plants()[0] elif self.my_plant.get_eff() < view.get_plants()[0].get_eff(): self.my_plant = view.get_plants()[0] if self.mode == 5: dist = max(abs(mx - self.target[0]), abs(my - self.target[1])) self.target_range = max(dist, self.target_range) if me.energy > dist * 1.5: self.mode = 6 if self.mode == 6: dist = max(abs(mx - self.target[0]), abs(my - self.target[1])) if dist > 4: return cells.Action(cells.ACT_MOVE, self.target) else: self.my_plant = None self.mode = 0 if (me.energy < self.target_range) and (view.get_energy().get(mx, my) > 0): return cells.Action(cells.ACT_EAT) if self.my_plant: dist = max(abs(mx - self.my_plant.get_pos()[0]), abs(my - self.my_plant.get_pos()[1])) if me.energy < dist * 1.5: (mx, my) = self.my_plant.get_pos() return cells.Action(cells.ACT_MOVE, (mx + random.randrange(-1, 2), my + random.randrange(-1, 2))) if (random.random() > 0.9999): (mx, my) = self.my_plant.get_pos() msg.send_message((my, mx)) if (random.random() > 0.9): return cells.Action( cells.ACT_SPAWN, (mx + random.randrange(-1, 2), my + random.randrange(-1, 2))) else: return cells.Action( cells.ACT_MOVE, (mx + random.randrange(-1, 2), my + random.randrange(-1, 2)))
def act(self, view, msg): debug = "off" me = view.get_me() pos = (mx, my) = me.get_pos() radius = self.radius gate = self.gate self.get_plant(view) terrain = view.get_terr().values helper = self.helper # Eat if hungry or if this is an exceptionally energy-rich spot. full = me.energy >= (cells.ENERGY_CAP / 2) hungry = (me.energy < self.target_range) energy_here = view.get_energy().get(mx, my) food = (energy_here > 0) if not full and ((hungry and food) or energy_here > 100): debug = "eat1" action = cells.ACT_EAT elif hungry: (dx, dy) = AStar.a_star_search(pos, self.my_plant.get_pos(), SquareGrid(view.get_terr(), me.loaded))[1] #(dx, dy) = helper.dir_to(pos, self.my_plant.get_pos()) pos = (dx, dy) debug = "move1" action = cells.ACT_MOVE while not helper.can_move(view, pos): pos = self.hungry_move(view) debug = "move1.1" elif self.my_plant: plant_pos = (px, py) = self.my_plant.get_pos() plant_terrain = terrain[px][py] plant_dist = helper.length( abs(pos[0] - plant_pos[0]), abs(pos[1] - plant_pos[1])) if (not me.loaded and (plant_dist > radius or (plant_dist < radius and plant_dist < terrain[mx][my])) and #(plant_dist > radius or (plant_dist < radius and plant_dist + plant_terrain < terrain[mx][my])) and #(plant_dist > radius or (plant_dist < radius and plant_dist + terrain[mx][my]) > radius) and helper.can_lift(view)): # always lift towards the plant # Check that the lift won't take too much dirt debug = "lift1" action = cells.ACT_LIFT elif (me.loaded and ((plant_dist == radius and abs(mx - plant_pos[0]) >= gate) or terrain[mx][my] < plant_dist < radius)): #(plant_dist < radius and plant_dist + plant_terrain > terrain[mx][my]))): #terrain[mx][my] + plant_dist < radius)): # always drop away from the plant # Make sure that the drop won't leave it stranded on the wall (may be done as another check elsewhere) debug = "drop1" action = cells.ACT_DROP else: plant_pos = self.my_plant.get_pos() (dx, dy) = (random.randrange(-1, 2), random.randrange(-1, 2)) plant_dist = helper.length( abs(pos[0] + dx - plant_pos[0]), abs(pos[1] + dy - plant_pos[1])) if plant_dist > (1.5 * radius): # Move back towards the plant if too far away (dx, dy) = (dx * -1, dy * -1) pos = (mx + dx, my + dy) action = cells.ACT_MOVE debug = "move2" while not helper.can_move(view, pos): debug = "move2.1" (dx, dy) = (random.randrange(-1, 2), random.randrange(-1, 2)) pos = (mx + dx, my + dy) else: (dx, dy) = (random.randrange(-1, 2), random.randrange(-1, 2)) pos = (mx + dx, my + dy) action = cells.ACT_MOVE debug = "move3" while not helper.can_move(view, pos): debug = "move3.1" (dx, dy) = (random.randrange(-1, 2), random.randrange(-1, 2)) pos = (mx + dx, my + dy) print(helper.display(view, action, pos, self)) print(debug) print(self.test_astar(view)) return cells.Action(action, pos)
def act(self, view, msg): x_sum = 0 y_sum = 0 dir = 1 n = len(view.get_plants()) me = view.get_me() mp = (mx, my) = me.get_pos() #If I don't have an id yet, get one. if (self.uniqueid == 0): self.uniqueid = self.GetID() for a in view.get_agents(): if (a.get_team() != me.get_team()): #If I see an enemy, broadcast it, then attack it. sentence = [self.uniqueid, 3, a] self.outmemory.append(sentence) if sentence not in self.outmemory: msg.send_message(sentence) return self.Attack(a) #Go through my messages, then memorize them for m in msg.get_messages(): self.memory.append(m) #Choosing a plant if (n > 0): #If I see a plant, broadcast it. sentence = [self.uniqueid, 2, view.get_plants()[0]] self.outmemory.append(sentence) if sentence not in self.outmemory: msg.send_message(sentence) if (not self.my_plant): #If I don't have a plant, get one. self.my_plant = view.get_plants()[0] elif self.my_plant.get_eff() < view.get_plants()[0].get_eff(): #If I see a plant that is better than my current one, get it. self.my_plant = view.get_plants()[0] else: #Otherwise, check my memory to see if someone else has found a plant for mem in self.memory: if (mem[1] == 2): #Ok, go to the plant that I have in memory self.my_plant = mem[2] break if self.mode == 5: dist = max(abs(mx - self.target[0]), abs(my - self.target[1])) self.target_range = max(dist, self.target_range) if view.get_me().energy > dist * 1.5: self.mode = 6 if self.mode == 6: dist = max(abs(mx - self.target[0]), abs(my - self.target[1])) if dist > 4: return cells.Action(cells.ACT_MOVE, self.target) else: self.my_plant = None self.mode = 0 if (view.get_me().energy < self.target_range) and (view.get_energy().get(mx, my) > 0): return self.Eat() #If I have a plant, move towards it if i need to. if self.my_plant: dist = max(abs(mx - self.my_plant.get_pos()[0]), abs(my - self.my_plant.get_pos()[1])) if view.get_me().energy < dist * 1.5: (mx, my) = self.my_plant.get_pos() return self.Move(mx, my) #Spawn near my plant, or just move near it. if (random.random() > 0.9): return self.Spawn(mx, my) else: return self.Move(mx, my)
def Eat(self): return cells.Action(cells.ACT_EAT)
def Attack(self, a): return cells.Action(cells.ACT_ATTACK, a.get_pos())
def Move(self, x, y): return cells.Action( cells.ACT_MOVE, (x + random.randrange(-1, 2), y + random.randrange(-1, 2)))
def act(self,view,msg): me = view.get_me() pos = me.get_pos() (mx, my) = pos if len(view.get_plants()): self.soldier = False self.spawner = True self.spawnRequirement = 55 # respond to nearby battles if self.soldier and len(msg.get_messages()): newPos = (0, 0) nCloseBy = 0 for message in msg.get_messages(): enemyPos = message.pos cartesian = (enemyPos[0] - mx, enemyPos[1] - my) distance = max(abs(cartesian[0]), abs(cartesian[1])) if distance < 30: nCloseBy+=1 newPos = (newPos[0] + enemyPos[0], newPos[1] + enemyPos[1]) # does the soldier have orders? any battle call will do if not self.soldierDirected: direction = math.atan2(cartesian[1], cartesian[0]) self.setDirection(direction) self.soldierDirected = True if nCloseBy: # find average of all close-by battle calls self.avgEnemyPos = ((self.avgEnemyPos[0] * float(self.weight) + newPos[0]) / float(self.weight + nCloseBy), (self.avgEnemyPos[1] * float(self.weight) + newPos[1]) / float(self.weight + nCloseBy)) self.weight = min(25, self.weight+nCloseBy) cartesian = (self.avgEnemyPos[0] - mx, self.avgEnemyPos[1] - my) direction = math.atan2(cartesian[1], cartesian[0]) self.setDirection(direction) self.distanceToFight = max(abs(cartesian[0]), abs(cartesian[1])) self.spawnRequirement = 50 + self.distanceToFight + 10 # are we stuck? if self.moved and self.prevPos == pos: self.setDirection() self.soldierDirected = False self.moved = 0 self.prevPos = None #attack? for a in view.get_agents(): if (a.get_team()!=me.get_team()): msg.send_message(Message(a.get_pos())) return cells.Action(cells.ACT_ATTACK,a.get_pos()) # freeSpots = where we can move/spawn freeSpots = diffs[:] for a in view.get_agents(): apos = a.get_pos() dpos = (apos[0] - pos[0], apos[1] - pos[1]) if dpos in freeSpots: freeSpots.remove(dpos) # see a ton of food nearby? if not self.spawner: for diff in diffs: target = (mx+diff[0], my+diff[1]) if view.get_energy().get(target[0], target[1]) > 50 and target in freeSpots: return cells.Action(cells.ACT_MOVE, (mx+diff[0], my+diff[1])) # spawn? if me.energy > self.spawnRequirement: if len(freeSpots): random.shuffle(freeSpots) spawn = freeSpots[0] spawnSoldier = None if self.distanceToFight and self.distanceToFight < 20: spawnSoldier = True else: spawnSoldier = False return cells.Action(cells.ACT_SPAWN, (mx+spawn[0], my+spawn[1], spawnSoldier)) # eat? if self.spawner or view.get_energy().get(mx, my) > 1 and (me.energy < self.energyNeeded): self.prevEnergy = me.energy return cells.Action(cells.ACT_EAT) # move as directed elif not self.spawner: dx = dy = 0 while not self.moved: if random.random() < abs(self.cos): dx += self.dx if random.random() < abs(self.sin): dy += self.dy self.moved = dx or dy self.prevPos = pos return cells.Action(cells.ACT_MOVE, (mx+dx, my+dy))
def act(self, view, msg): x_sum = 0 y_sum = 0 dir = 1 me = view.me mp = (mx, my) = (me.x, me.y) map_size = view.energy_map.width cfh_val = self.call_for_help.val for a in view.agent_views: if (a.team != me.team): if random() > cfh_val: msg.send_message((self.call_type.val, MODE_ATTACK, mp)) return cells.Action(cells.ACT_ATTACK, (a.x, a.y)) my_call_type = self.call_type.val my_plant = self.my_plant for message in msg.get_messages(): call_type, move_mode, m = message if call_type != my_call_type: continue if my_plant: my_team = me.team num_nearby = sum(1 for x in view.agent_views if x.team == my_team) if num_nearby > 1 and random() > self.draft_dodger.val: tx, ty = m self._set_target(move_mode, tx, ty, map_size) elif random() < self.call_of_duty.val: tx, ty = m self._set_target(move_mode, tx, ty, map_size) del my_plant # Might change later, don't confuse myself by caching it. if view.plant_views: best_plant = max(view.plant_views, key=lambda x: x.eff) self.my_plant = best_plant self.mode = MODE_NORMAL if self.mode == MODE_PREP: dist = max(abs(mx - self.target[0]), abs(my - self.target[1])) self.target_range = max(dist, self.target_range) if me.energy > dist * 1.5: self.mode = self.next_mode if self.mode == MODE_COLONIZE or self.mode == MODE_ATTACK: dist = abs(mx - self.target[0]) + abs(my - self.target[1]) my_team = me.team if (dist < 2 or (self.mode == MODE_COLONIZE and dist < 8 and sum(1 for a in view.agent_views if a.team == my_team) > 7)): self.my_plant = None self.mode = MODE_NORMAL else: return cells.Action(cells.ACT_MOVE, self.target) if me.energy < self.target_range: if view.energy_map.get(mx, my) > 0: return cells.Action(cells.ACT_EAT) elif self.my_plant is not None: mp = self.my_plant self._set_target(MODE_ATTACK, mp.x, mp.y, map_size) else: self._colonize_from(mx, my, map_size) my_plant = self.my_plant if my_plant is not None: dist = max(abs(mx - self.my_plant.get_pos()[0]), abs(my - self.my_plant.get_pos()[1])) if me.energy < dist * 1.5: return cells.Action( cells.ACT_MOVE, (fuzz_coord(my_plant.x), fuzz_coord(my_plant.y))) if (random() < self.colonize_prob.val): self._colonize_from(my_plant.x, my_plant.y, map_size) if (random() < self.spawn_prob.val and me.energy >= self.spawn_energy.val): return cells.Action(cells.ACT_SPAWN, (fuzz_coord(mx), fuzz_coord(my), self)) else: return cells.Action(cells.ACT_MOVE, (fuzz_coord(mx), fuzz_coord(my)))
def act(self, view, msg): me = view.get_me() mp = (mx, my) = me.get_pos() # If I think it's time to go to war, sound out a message if self.mytime > self.goto_war_at and not (self.war_time > 0): msg.send_message(("war", self.mytime)) # personal time counter self.mytime += 1 # Interpret war-related messages for m in msg.get_messages(): if m[0] == "war" and not self.am_warrior: self.am_warrior = True self.war_time = self.mytime if m[0] == "attack": self.lastattack = (m[1], m[2], self.mytime) # Attack nearby enemies. This always gets done first for a in view.get_agents(): if (a.get_team() != me.get_team()): msg.send_message(("attack", mx, my)) return cells.Action(cells.ACT_ATTACK, a.get_pos()) # Move if at war if self.am_warrior and (self.lastattack[2] > self.war_time - 50): go = True for plant in view.get_plants(): if (mx == plant.x and abs(my - plant.y) < 2) or ( my == plant.y and abs(mx - plant.x) < 2): go = False if go: tx, ty = (self.lastattack[0], self.lastattack[1]) if mx != self.lastattack[0]: tx += random.randrange( 15, 40) * (self.lastattack[0] - mx) / abs( (self.lastattack[0] - mx)) if my != self.lastattack[1]: ty += random.randrange( 15, 40) * (self.lastattack[1] - my) / abs( (self.lastattack[1] - my)) tx += random.randrange(-4, 5) ty += random.randrange(-4, 5) return cells.Action(cells.ACT_MOVE, (tx, ty)) # If very hungry, eat if ((me.energy < self.target_range) and (view.get_energy().get(mx, my) > 0)): return cells.Action(cells.ACT_EAT) # If on a quest, move. Stop for nearby goodies or if I couldn't move last time. if self.mygoaldir != (0, 0): self.questtime += 1 highenergy = False for diff in self.diffs: tx, ty = mx + diff[0], my + diff[1] if (view.get_energy().get(tx, ty) > 200): highenergy = True if ((len(view.get_plants()) > 0 or highenergy) and self.questtime > 5) or (mx == self.last_x and my == self.last_y): self.mygoaldir = (0, 0) else: self.last_x = mx self.last_y = my for a in view.get_agents(): if a.x == mx + self.mygoaldir[ 0] and a.y == my + self.mygoaldir[1]: self.mygoaldir = random.choice( self.diffs) # change destination if blocked if random.random() < 0.9: return cells.Action( cells.ACT_MOVE, (mx + self.mygoaldir[0], my + self.mygoaldir[1])) else: return cells.Action( cells.ACT_MOVE, (mx + self.mygoaldir[0] + random.randrange(-1, 2), my + self.mygoaldir[1] + random.randrange(-1, 2))) # Spawn if I have the energy if me.energy > self.spawn_min: random.shuffle(self.diffs) for diff in self.diffs: sx, sy = (mx + diff[0], my + diff[1]) occupied = False for a in view.get_agents(): if a.x == sx and a.y == sy: occupied = True break if not occupied: return cells.Action( cells.ACT_SPAWN, (sx, sy, self.gen + 1, self.war_time, diff)) # Start a quest if I have the energy and there's no war if me.energy > self.migrate_min and not self.am_warrior: self.mygoaldir = random.choice(self.diffs) self.questtime = 0 self.last_x = -999 self.last_y = -999 return cells.Action( cells.ACT_MOVE, (mx + self.mygoaldir[0], my + self.mygoaldir[1])) # Find the highest energy square I can see. If I'm there, eat it. Otherwise move there. maxenergy = view.get_energy().get(mx, my) fx, fy = (mx, my) random.shuffle(self.diffs) for diff in self.diffs: tx, ty = (mx + diff[0], my + diff[1]) occupied = False for a in view.get_agents(): if a.x == tx and a.y == ty: occupied = True break if view.get_energy().get(tx, ty) > maxenergy and not occupied: maxenergy = view.get_energy().get(tx, ty) fx, fy = (tx, ty) if (mx, my) == (fx, fy): return cells.Action(cells.ACT_EAT) return cells.Action(cells.ACT_MOVE, (fx, fy))
def act_wrapper(self, view, msg): global armageddon_declared me = view.get_me() my_pos = (mx, my) = me.get_pos() # after a while, armageddon! self.age += 1 self.game_age += 1 bored = (view.energy_map.width + view.energy_map.height) if self.game_age > bored and self.game_age <= bored * 2 or self.game_age > bored * 2.5: self.scout = False if not armageddon_declared: print "Mark declares armageddon!" armageddon_declared = True if self.game_age > bored * 2 and self.game_age < bored * 2.5 and armageddon_declared: print "Mark calls armageddon off..." armageddon_declared = False # Attack anyone next to me, but first send out the distress message with my position target = next( (a for a in view.get_agents() if a.get_team() != me.get_team()), None) if target: msg.send_message((MessageType.ATTACK, mx, my)) return cells.Action(cells.ACT_ATTACK, target.get_pos()) # Eat any energy I find until I am 'full' if view.get_energy().get(mx, my) > 0: if (me.energy < 50): return cells.Action(cells.ACT_EAT) if (me.energy < self.defense): # and (random.random()>0.1)): return cells.Action(cells.ACT_EAT) # If there is a plant near by go to it and spawn all I can if not self.my_plant and len(view.get_plants()) > 0: self.my_plant = view.get_plants()[0] if self.my_plant: pos = self.smart_spawn(me, view) if pos: return cells.Action(cells.ACT_SPAWN, (me.x + pos[0], me.y + pos[1], self)) if me.energy > 50 or (armageddon_declared and me.energy > 400): pos = self.smart_spawn(me, view) if pos: return cells.Action(cells.ACT_SPAWN, (me.x + pos[0], me.y + pos[1], self)) # If I get the message of help go and rescue! if (self.step == 0 and (random.random() > 0.2)): calls_to_arms = [((mx - ox)**2 + (my - oy)**2, ox, oy) for t, ox, oy in msg.get_messages() if t == MessageType.ATTACK] if len(calls_to_arms) > 0: best, ox, oy = min(calls_to_arms) if not self.scout or best < min( self.game_age, (view.energy_map.width / 8)**2): self.defense = 2000 self.x = ox - mx self.y = oy - my if (len(calls_to_arms) > 1): # Attack the base, not the front agent_offset = random.randrange( 1, view.energy_map.width / 6) if (self.x > 0): self.x += agent_offset else: self.x -= agent_offset if (self.y > 0): self.y += agent_offset else: self.y -= agent_offset # don't all aim directly at the target roam = int(sqrt(best)) if roam > 1: self.x += random.randrange(-roam, roam + 1) self.y += random.randrange(-roam, roam + 1) # Don't stand still once we get there if (self.x == 0 and self.y == 0): self.x = random.randrange(-3, 4) self.y = random.randrange(-3, 4) self.step = random.randrange(3, 30) # don't get stuck and die if self.bumps >= 2: self.x = random.randrange(-3, 4) self.y = random.randrange(-3, 4) self.bumps = 0 # hit world wall if (mx == 0 or mx == view.energy_map.width - 1): self.scout = False self.x *= -1 self.bumps = 0 if (my == 0 or my == view.energy_map.height - 1): self.scout = False self.y *= -1 self.bumps = 0 # Back to step 0 we can change direction at the next attack if (self.step > 0): self.step -= 1 # Move quickly randomly in my birth direction return cells.Action(cells.ACT_MOVE, (mx + self.x + random.randrange(-1, 2), my + self.y + random.randrange(-1, 2)))
def act_wrapper(self, view, msg): me = view.get_me() my_pos = (mx, my) = me.get_pos() if my_pos == self.last_pos: self.bumps += 1 else: self.bumps = 0 if self.x is None: self.x = random.randrange(view.energy_map.width) - me.x self.y = random.randrange(view.energy_map.height) - me.y # Attack anyone next to me, but first send out the distress message with my position for a in view.get_agents(): if (a.get_team() != me.get_team()): msg.send_message((self.strain, MessageType.ATTACK, mx, my)) return cells.Action(cells.ACT_ATTACK, a.get_pos()) # Eat any energy I find until I am 'full'. The cost of eating # is 1, so don't eat just 1 energy. if view.get_energy().get(mx, my) > 1: if (me.energy <= 50): return cells.Action(cells.ACT_EAT) if (me.energy < self.defense and (random.random() > 0.3)): return cells.Action(cells.ACT_EAT) # If there is a plant near by go to it and spawn all I can if self.my_plant is None: plants = view.get_plants() if plants: self.my_plant = plants[0] self.x = self.y = 0 self.strain = self.my_plant.x * 41 + self.my_plant.y # Current rules don't make carrying around excess energy # worthwhile. Generates a very nice "They eat their # wounded?!" effect. Also burns extra energy so the enemy # can't use it. # Spawning takes 25 of the energy and gives it # to the child and reserves the other 25 for the child's death # drop. In addition, the action costs 1 unit. Therefore, we # can't create energy by spawning... if me.energy >= 51: spawn_x, spawn_y = self.smart_spawn(me, view) return cells.Action(cells.ACT_SPAWN, (me.x + spawn_x, me.y + spawn_y, self)) # If I get the message of help go and rescue! if not self.step and not self.scout and random.random() > 0.1: ax = 0 ay = 0 best = 500 message_count = len(msg.get_messages()) for m in msg.get_messages(): (strain, type, ox, oy) = m if strain != self.strain: continue if (type == MessageType.ATTACK): dist = max(abs(mx - ax), abs(my - ay)) if dist < best: ax = ox ay = oy best = dist if ax and ay: self.defense = 200 dir = ax - mx + (ay - my) * 1j r, theta = cmath.polar(dir) theta += 0.02 * random.random() - 0.5 dir = cmath.rect(r, theta) self.x = dir.real self.y = dir.imag # if (message_count > 1) : # # Attack the base, not the front # agent_scale = 1 + random.random() # self.x *= agent_scale # self.y *= agent_scale # don't stand still once we get there if (self.x == 0 and self.y == 0): self.x = random.randrange(-1, 2) self.y = random.randrange(-1, 2) self.step = random.randrange(20, 100) if self.bumps >= 2: self.x = random.randrange(-3, 4) self.y = random.randrange(-3, 4) self.bumps = 0 # hit world wall map_size = view.energy_map.width if (mx == 0 or mx == map_size - 1): self.x = random.randrange(-1, 2) if (my == 0 or my == map_size - 1): self.y = random.randrange(-1, 2) # Back to step 0 we can change direction at the next attack. if self.step: self.step -= 1 return cells.Action(cells.ACT_MOVE, (mx + self.x, my + self.y))
def act(self, view, msg): agent = view.get_me() position = (x, y) = agent.get_pos() if dist(self.direction, position) < 2: self.direction = (random.randrange(0, view.energy_map.width), random.randrange(0, view.energy_map.height)) # Attack any opponents. for a in view.get_agents(): if a.get_team() != agent.get_team(): if self.type == AgentType.QUEEN: msg.send_message((MessageType.DEFEND, (x, y))) self.ratios = [0, 2, 2, 2] else: msg.send_message((MessageType.FOUND, a.get_pos())) return cells.Action(cells.ACT_ATTACK, a.get_pos()) # Process messages alreadyClaimed = 0 distance = 1000000 for message in msg.get_messages(): # Queen message behavior if message[0] == MessageType.CLAIM and self.type == AgentType.QUEEN: if self.plant != None and self.plant.get_pos() == message[1]: if self.claimed: self.newborn = False msg.send_message((MessageType.CLAIMED, message[1])) if message[ 0] == MessageType.CLAIMED and self.type == AgentType.QUEEN: if self.plant != None and self.plant.get_pos() == message[1]: if not self.claimed: alreadyClaimed += 1 if message[0] == MessageType.FOUND and self.type == AgentType.QUEEN: if dist(message[1], position) < distance: self.directionOfAttack = message[1] distance = dist(message[1], position) # Worker message behavior if self.type == AgentType.WORKER: if message[0] == MessageType.CLAIM: found = False for p in self.plantList: if p == message[1]: found = True break if not found: self.plantList.append(message[1]) if message[0] == MessageType.DEFEND or message[ 0] == MessageType.FOUND: aDistance = dist(position, message[1]) if aDistance < 20 and aDistance < distance: self.type = AgentType.FIGHTER self.direction = message[1] distance = aDistance # Fighter message behavior if self.type == AgentType.FIGHTER: if message[0] == MessageType.DEFEND or message[ 0] == MessageType.FOUND: if distance > dist(position, message[1]): self.direction = message[1] distance = dist(position, message[1]) if self.type == AgentType.WORKER: if dist(position, self.startPoint) > 2: plants = view.get_plants() if plants: found = False for p in self.plantList: if p == plants[0].get_pos(): found = True break if not found: self.type = AgentType.QUEEN self.ratios = (1, 1, 1, 2) self.newborn = True self.plant = None self.claimed = False self.claiming = False self.position = 0 self.count = 0 self.directionOfAttack = None self.age = 0 del self.plantList # Eat if hungry. hungry = (agent.energy < 50) energy_here = view.get_energy().get(x, y) food = (energy_here > 0) if hungry and food: return cells.Action(cells.ACT_EAT) if agent.energy > 500: sp = spawnPos(0, AgentType.WORKER, view, agent) sp = (sp[0] + x, sp[1] + y, AgentType.WORKER, (x, y)) return cells.Action(cells.ACT_SPAWN, sp) if random.random() < 0.65: if random.random() < 0.4: if view.get_energy().get(x, y) > 0: return cells.Action(cells.ACT_EAT) direction = [self.direction[0] - x, self.direction[1] - y] if direction[0] > 0: direction[0] = 1 elif direction[0] == 0: direction[0] = 0 else: direction[0] = -1 if direction[1] > 0: direction[1] = 1 elif direction[1] == 0: direction[1] = 0 else: direction[1] = -1 position = (position[0] + direction[0], position[1] + direction[1]) else: position = (x + random.randrange(-1, 2), y + random.randrange(-1, 2)) return cells.Action(cells.ACT_MOVE, position) if self.type == AgentType.FIGHTER: # Eat if hungry. hungry = (agent.energy < 100) energy_here = view.get_energy().get(x, y) food = (energy_here > 0) if hungry and food: return cells.Action(cells.ACT_EAT) if agent.energy > 1000: sp = spawnPos(0, AgentType.FIGHTER, view, agent) sp = (sp[0] + x, sp[1] + y, AgentType.FIGHTER, (x, y)) return cells.Action(cells.ACT_SPAWN, sp) if random.random() < 0.85 or dist(position, self.direction) < 8: direction = [self.direction[0] - x, self.direction[1] - y] if direction[0] > 0: direction[0] = 1 elif direction[0] == 0: direction[0] = 0 else: direction[0] = -1 if direction[1] > 0: direction[1] = 1 elif direction[1] == 0: direction[1] = 0 else: direction[1] = -1 position = (position[0] + direction[0], position[1] + direction[1]) else: position = (x + random.randrange(-1, 2), y + random.randrange(-1, 2)) return cells.Action(cells.ACT_MOVE, position) # Queen Stuff if self.type == AgentType.QUEEN: # Check claim if self.claiming: if self.skip: self.skip = False else: if alreadyClaimed > 39: # Try again self.plant = None self.claiming = False else: # We have a throne self.claimed = True self.claiming = False self.position = alreadyClaimed print alreadyClaimed self.skip = True # Get a plant if self.plant == None and view.get_plants(): self.age += 1 if self.age > 5: self.type = AgentType.WORKER self.plantList = list() if view.get_plants(): plants = view.get_plants() bestPlant = plants[0] distance = dist(position, bestPlant.get_pos()) for plant in plants: if distance > dist(position, bestPlant.get_pos()): distance = dist(position, bestPlant.get_pos()) bestPlant = plant self.plant = bestPlant self.claiming = True msg.send_message((MessageType.CLAIM, self.plant.get_pos())) # Check position if self.claimed == False and self.claiming == False: # Move randomly if random.random() > 0.75: direction = [self.direction[0] - x, self.direction[1] - y] if direction[0] > 0: direction[0] = 1 elif direction[0] == 0: direction[0] = 0 else: direction[0] = -1 if direction[1] > 0: direction[1] = 1 elif direction[1] == 0: direction[1] = 0 else: direction[1] = -1 position = (position[0] + direction[0], position[1] + direction[1]) else: position = (x + random.randrange(-1, 2), y + random.randrange(-1, 2)) return cells.Action(cells.ACT_MOVE, position) if self.claimed: # Move towards off = offset(self.position) pos = self.plant.get_pos() pos = (pos[0] + off[0], pos[1] + off[1]) distance = dist(pos, position) if distance > 0: if agent.energy > distance * 1.1: if random.random() > 0.6: pos = (x + random.randrange(-1, 2), y + random.randrange(-1, 2)) return cells.Action(cells.ACT_MOVE, pos) else: # Cannot move in one go eat if pos or move a bit if view.get_energy().get(x, y) > 0: return cells.Action(cells.ACT_EAT) mxy = [0, 0] if self.plant.get_pos()[0] > x: mxy[0] = 1 elif self.plant.get_pos()[0] < x: mxy[0] = -1 if self.plant.get_pos()[1] > y: mxy[1] = 1 elif self.plant.get_pos()[1] < y: mxy[1] = -1 mxy = (mxy[0] + x, mxy[1] + y) return cells.Action(cells.ACT_MOVE, mxy) # Breed or Eat nxt = self.ratios[self.count % len(self.ratios)] spawn = [x, y, nxt] spawning = False if self.newborn and agent.energy > 100: spawn = [x, y, AgentType.QUEEN] spawnOff = spawnPos(self.position, AgentType.QUEEN, view, agent) spawning = True if nxt == AgentType.QUEEN and agent.energy > 100: # Spawn new queen spawnOff = spawnPos(self.position, nxt, view, agent) spawning = True if nxt == AgentType.WORKER and agent.energy > 100: # Spawn new worker spawnOff = spawnPos(self.position, nxt, view, agent) spawn.append(position) spawning = True if nxt == AgentType.FIGHTER and agent.energy > 100: # Spawn new fighter spawnOff = spawnPos(self.position, nxt, view, agent) spawn.append(self.directionOfAttack) spawning = True if nxt == AgentType.BUILDER and agent.energy > 100: # Spawn new builder spawnOff = spawnPos(self.position, nxt, view, agent) spawning = True if spawning: spawn[0] += spawnOff[0] spawn[1] += spawnOff[1] self.count = self.count + 1 return cells.Action(cells.ACT_SPAWN, spawn) # Must eat return cells.Action(cells.ACT_EAT) if random.random() > 0.75: direction = (self.direction[0] - x, self.direction[1] - y) if direction[0] > 0: direction[0] = 1 elif direction[0] == 0: direction[0] = 0 else: direction[0] = -1 if direction[1] > 0: direction[1] = 1 elif direction[1] == 0: direction[1] = 0 else: direction[1] = -1 position = (position[0] + direction[0], position[1] + direction[1]) else: position = (x + random.randrange(-1, 2), y + random.randrange(-1, 2)) return cells.Action(cells.ACT_MOVE, position)