Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'new_rules' of https://github.com/phreeza/cells into new…

…_rules
  • Loading branch information...
commit 57eedadbbbb3e7f47e15f28751883bda3fedfb36 2 parents ac28fdb + b3a534c
@phreeza authored
Showing with 435 additions and 8 deletions.
  1. +30 −8 minds/ben2.py
  2. +405 −0 minds/seken.py
View
38 minds/ben2.py
@@ -121,7 +121,7 @@ def act_scout(self, view, msg):
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)
@@ -163,10 +163,11 @@ def act_scout(self, view, msg):
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, (best+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 > 50 and me.energy < 100:
+ 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))
@@ -196,7 +197,7 @@ def smart_move(self, view, msg):
if self.bumps >= 2:
self.choose_new_direction(view, msg)
self.last_pos = view.me.get_pos()
-
+
offsetx = 0
offsety = 0
if self.search:
@@ -208,6 +209,19 @@ def smart_move(self, view, msg):
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
@@ -215,12 +229,20 @@ def smart_move(self, view, msg):
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]:
@@ -290,7 +312,7 @@ def act_parent(self, view, msg):
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 < 50 : return cells.Action(cells.ACT_EAT)
+ 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
@@ -299,12 +321,12 @@ def act_parent(self, view, msg):
# 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 > 50 + self.time + random.randrange(-10,100):
+ 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 < 50 :
+ 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)
View
405 minds/seken.py
@@ -0,0 +1,405 @@
+'''
+Defines an agent mind that attacks any opponent agents within its view,
+attaches itself to the strongest plant it finds, eats when its hungry,
+'''
+
+import random, cells
+import math, numpy
+
+class AgentType(object):
+ QUEEN = 0
+ WORKER = 1
+ FIGHTER = 2
+ BUILDER = 3
+
+class MessageType(object):
+ FOUND = 0
+ DEFEND = 1
+ CLAIM = 2
+ CLAIMED = 3
+
+def dist(a, b):
+ return int(math.sqrt((a[0]-b[0])**2 + (a[1]-b[1])**2))
+
+def length(xy):
+ return dist(xy, (0, 0))
+
+def offset(i):
+ i = i % 9
+ x = 0
+ y = 0
+ if i < 3:
+ y = -1
+ if i > 5:
+ y = 1
+
+ if i == 0 or i == 5 or i == 6:
+ x = -1
+ if i == 2 or i == 3 or i == 8:
+ x = 1
+
+ return (x, y)
+
+def get_available_space_grid(view, agent):
+ grid = numpy.ones((3,3))
+ for a in view.get_agents():
+ grid[a.x - agent.x + 1, a.y - agent.y + 1] = 0
+ for plant in view.get_plants():
+ grid[plant.x - agent.x + 1, plant.y - agent.y + 1] = 0
+ grid[1,1] = 0
+ return grid
+
+def spawnPos(i, type, view, agent):
+ if type == AgentType.QUEEN:
+ old = offset(i)
+ return (-old[0], -old[1])
+ grid = get_available_space_grid(view, agent)
+ for x in xrange(3):
+ for y in range(3):
+ if grid[x,y]:
+ return (x-1, y-1)
+ return (-1, -1)
+
+class AgentMind(object):
+
+ def __init__(self, data):
+ self.target_range = random.randrange(50, 1000)
+
+ if data == None:
+ self.type = AgentType.QUEEN
+ self.ratios = (1,)
+ else:
+ self.type = data[0]
+ self.ratios = (1, 1, 1, 2)
+
+ if self.type == AgentType.QUEEN:
+ self.plant = None
+ self.claimed = False
+ self.claiming = False
+ self.position = 0
+ self.count = 0
+ self.directionOfAttack = None
+ self.newborn = True
+ self.age = 0
+
+ if self.type == AgentType.WORKER:
+ self.plantList = list()
+ self.startPoint = data[1]
+
+ if self.type == AgentType.BUILDER:
+ self.radius = 10
+ self.height = 4
+ self.openings = 1
+
+ self.skip = True
+
+ if self.type == AgentType.FIGHTER and data[1]:
+ self.direction = data[1]
+ else:
+ self.direction = (random.randrange(0, 300), random.randrange(0, 300))
+
+ 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)
Please sign in to comment.
Something went wrong with that request. Please try again.