import random class Arena: """ Arena where the matches take place """ debug_flag = True bots = [] # Collection of BotHolders bot_count = 0 # How many bots are in the arena? bot_id = 1000 # Uniq bot id counter game = None # Class to use for indididual matches prune_thresh = None # When bot score gets below this, it's killed birth_thresh = None # Bot gives birth when score goes above this birth_children = None # How many children to have def __init__(self, field, game, prune, birth, birth_children): self.game = game(field()) self.prune_thresh = prune self.birth_thresh = birth self.birth_children = birth_children def get_id(self): """ Return a new bot id """ self.bot_id += 1 return self.bot_id def get_bot(self, i): return self.bots[i] def add_bots(self, *bots): for bot in bots: self.add_bot(BotHolder(bot, 0)) def add_bot(self, botholder): """ Add a BotHolder to the BotHolder collection """ botholder.id = self.get_id() self.bots.append(botholder) self.bot_count += 1 #self.debug("add_bot(%i %s.%i)" % (self.bot_count, botholder.get_name(), botholder.id)) def kill_bot(self, i): """ Remove this bot from the arena """ #self.debug("kill_bot(%s.%i)" % (self.get_bot(i).get_name(), self.get_bot(i).id)) del self.bots[i] self.bot_count -= 1 def clone_bot(self, i): """ Ask this bot's BotHolder to give us a clone of the bot """ self.add_bot(self.get_bot(i).clone()) def go(self, i): """ Run a simulation of "i" matches in this arena """ for r in range(0, i): self.birth() if self.bot_count < 2: return self.prune() (a, b) = self.get_players() (choice_a, choice_b) = self.game.get_answers(self.get_bot(a), self.get_bot(b)) (score_a, score_b)= self.game.get_scores(choice_a, choice_b) self.debug("-- R%i" % r) self.debug(" %s.%i (%i,%i)" % (self.get_bot(a).get_name(), self.get_bot(a).id, choice_a, score_a)) self.debug(" %s.%i (%i,%i)" % (self.get_bot(b).get_name(), self.get_bot(b).id, choice_b, score_b)) """ winner = "Nobody" score = score_a if score_a > score_b: winner = self.get_bot(a).get_name() elif score_b > score_a: winner = self.get_bot(b).get_name() score = score_b else: winner = "Tie" self.debug("-- \t %s [%i]" % (winner, score)) """ self.get_bot(a).inc_score(score_a) self.get_bot(b).inc_score(score_b) def prune(self): """ Check which bots need to be pruned """ if self.prune_thresh == None: return for i in range(0, self.bot_count-1): if self.get_bot(i).get_score() < self.prune_thresh: self.debug("prune: %s.%i (score=%i)" % (self.get_bot(i).get_name(), self.get_bot(i).id, self.get_bot(i).get_score())) del self.bots[i] self.bot_count -= 1 def birth(self): """ Check which bots should give birth """ if self.birth_thresh == None: return for i in range(0, self.bot_count-1): #print self.get_bot(i).get_score() if self.get_bot(i).get_score() > self.birth_thresh: self.debug("birth: %s.%i (score=%i)" % (self.get_bot(i).get_name(), self.get_bot(i).id, self.get_bot(i).get_score())) for n in range(0, self.birth_children+1): self.clone_bot(i) # Kill off the parent self.kill_bot(i) def get_players(self): """ Return two random integers of bots to use """ a = b = random.randrange(0, self.bot_count) while a == b: b = random.randrange(0, self.bot_count) return (a, b) def print_scores(self): """ Print scores out for all bots in the arena """ for bot in self.bots: print "%15s[%i] = %i" % (bot.get_name(), bot.id, bot.get_score()) def debug(self, text): if self.debug_flag: print text class BotHolder: """ Wrapper class to hold initialized bots """ id = None bot = None score = 0 def __init__(self, bot, id): self.bot_class = bot self.bot = bot() self.id = id def clone(self): return BotHolder(self.bot_class, 0) def get_name(self): return self.bot.name def get_score(self): return self.score def set_score(self, score): self.score = score def inc_score(self, inc): self.score += inc def answer(self, a, otherid): self.bot.answer(a,otherid) def inform(self, a, otherid): self.bot.inform(a,otherid)