I thought this was a neat formation for my little army.
The circle is incomplete because more soldiers from across the arena had just spawned, so spots in the circle were saved for them.
Click here for the code (python)
patrolCenter = {'x': 80, 'y': 45}
#patrolCenter = hero.pos # here, they have a hard time keeping up whenever you move
patrolTimeScale = 0.25 # set to 0.0 if you don't want the soldiers to walk around while in the circle
while True:
#...summon soldiers, collect coins, etc...
friends = hero.findFriends()
soldiers = (friend for friend in friends if friend.type == "soldier")
radius = 2 + 2.5 * Math.log1p(len(soldiers)) #or use Math.log(len(soldiers) + 1)
angleStep = Math.PI * 2 / len(soldiers)
for index, soldier in enumerate(soldiers):
enemy = soldier.findNearestEnemy()
if enemy:
hero.command(soldier, "attack", enemy)
else:
hero.command(soldier, "move",
{'x': patrolCenter.x + radius * Math.cos(angleStep * index - hero.time * patrolTimeScale),
'y': patrolCenter.y + radius * Math.sin(angleStep * index - hero.time * patrolTimeScale)})
#...etc...
You pass the array of units you want to command. You can also optionally pass a position that you want the units to circle around.
Example
def commandGriffins(griffins):
idleGriffins = []
for griffin in griffins:
enemy = griffin.findNearestEnemy()
if enemy:
if griffin.distanceTo(enemy) < 30:
griffin.attack(enemy)
else:
idleGriffins.append(griffin) # griffin does not attack enemy; it is idle
else:
idleGriffins.append(griffin) # no enemies; griffin is idle
# done iterating through all griffins and idleGriffins is ready to be used
circularPatrol(idleGriffins, {"x": 50, "y": 38})
#circularPatrol(idleGriffins) # idleGriffins will circle around the hero if no position is provided