123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
#! /usr/bin/env python
import os
import subprocess
import copy
import random
import time
world_size = 32
world = [['x' for i in range(world_size)] for i in range(world_size)]
bots = []
new_world = copy.deepcopy(world)
bots_to_delete = []
class Bot(object):
def __init__(self, name, cmdline, x, y):
self.name = name
self.cmdline = cmdline
self.x, self.y = x, y
def move(self):
local_world = copy.deepcopy(world)
for bot in bots:
if bot!=self:
local_world[bot.y][bot.x] = str(bots.index(bot) + 1)
for bot in bots:
if bot==self:
local_world[bot.y][bot.x] = '@'
out = '\n'.join([''.join(i) for i in local_world])
proc = subprocess.Popen(list(self.cmdline) + [out],
stdout=subprocess.PIPE)
result = proc.communicate()[0]
try:
dx, dy = [int(i) for i in result.split()]
if abs(dx) + abs(dy) > 4:
dx, dy = 0, 0
if self.x + dx < 0:
dx = -self.x
if self.y + dy < 0:
dy = -self.y
if self.x + dx >= world_size:
dx = world_size - self.x - 1
if self.y + dy >= world_size:
dy = world_size - self.y - 1
except:
dx, dy = 0, 0
self.x += dx
self.y += dy
if world[self.y][self.x] == 'x':
new_world[self.y][self.x] = ' '
else:
bots_to_delete.append(self)
def turn():
global world
global new_world
global bots_to_delete
new_world = copy.deepcopy(world)
for bot in bots:
bot.move()
world = new_world
for ex_bot in bots_to_delete:
del bots[bots.index(ex_bot)]
bots_to_delete = []
def match(bot_list, max_bots, debug=False):
global world
global bots
global bots_to_delete
world = [['x' for i in range(world_size)] for i in range(world_size)]
bots = []
bots_to_delete = []
try:
competing_bots = random.sample(bot_list, max_bots)
except ValueError:
competing_bots = (bot_list*int(max_bots/len(bot_list)+ 1))[:max_bots]
for bot in competing_bots:
bots.append(Bot(bot[0], bot[1], random.randint(0, world_size-1), random.randint(0, world_size-1)))
current_competitors = [i.name for i in bots]
for i in range(32*32):
turn()
if debug:
local_world = copy.deepcopy(world)
for bot in bots:
local_world[bot.y][bot.x] = '@'
time.sleep(0.25)
print '\n'*20
print '\n'.join([' '.join(i) for i in local_world])
if not bots or len(current_competitors)==1:
winners = current_competitors
return winners
else:
current_competitors = [i.name for i in bots]
if __name__=="__main__":
possibilities = [
('Random Bot', ('python', 'random_bot.py')),
('UpBot', ('python', 'upbot.py')),
('Slow Bot', ('python', 'slowbot.py')),
('LookBot', ('./lookbot',)),
('JumpBot', ('./jumpbot',)),
('Moat Builder', ('python', 'moatbuilder.py')),
]
inp = raw_input("Run tournament? y/N: ")
if inp.lower().startswith('y'):
stats = dict([(i[0], 0) for i in possibilities])
while True:
try:
rounds = int(input("Tournament rounds: "))
break
except:
print "Invalid value. Please enter a number."
for i in xrange(rounds):
result = match(possibilities, 4)
print "Round %i: %s" % (i+1, ", ".join(result))
for bot in result:
stats[bot] += 1
keyfunc = lambda x: x[1]
results = reversed(sorted(stats.items(), key=keyfunc))
for i in results:
print i[0].ljust(25), i[1]
else:
result = match(possibilities, 4, True)
print result