Want to show your appreciation and help with hosting costs? Support us on Patreon!
Description: TNT Run Controller
Submitted on May 10, 2016 at 03:03 PM

Section 1 (Python)

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