#! /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