class Controler: def __init__(self): self.ais = [ ai.RandomAI(), ai.BeijingAlgorithmAI(), ai.MarkovChainAi(), ai.RandomBiasedAi(), ] self.stats = Stats() def play(self, player_choice): votes = {c: set() for c in Choice} for ai in self.ais: votes[ai.get_choice()].add(ai) top_choice = self.vote(votes) for ai_choice, voters in votes.items(): for ai in voters: ai.add_result(Result(player_choice, top_choice, ai_choice)) result = Result(player_choice, top_choice, top_choice) self.stats.add_result(result) return result def vote(self, votes): weights = {c: 0 for c in Choice} for choice, voters in votes.items(): for ai in voters: weights[choice] += ai.win_rate return max(weights.items(), key=operator.itemgetter(1))[0]
class AI(ABC): def __init__(self): self.stats = Stats() def add_result(self, result): self.stats.add_result(result) @property def win_rate(self): return self.stats.win_rate @property def loss_rate(self): return self.stats.loss_rate def random_choice(self): return random.choice(list(Choice)) @abstractmethod def get_choice(self): pass def __str__(self): return type(self).__name__