def convert_key(old_key: tuple) -> Plays: opponent_start, player, opponent = old_key return Plays( self_plays=str_to_actions(player), op_plays=str_to_actions(opponent), op_openings=str_to_actions(opponent_start), )
def read_interactions_from_file(filename, progress_bar=True, num_interactions=False): """ Reads a file and returns a dictionary mapping tuples of player pairs to lists of interactions """ if progress_bar: if not num_interactions: with open(filename) as f: num_interactions = sum(1 for line in f) progress_bar = tqdm.tqdm(total=num_interactions, desc="Loading") pairs_to_interactions = {} with open(filename, 'r') as f: for row in csv.reader(f): index_pair = (int(row[0]), int(row[1])) p1_actions = str_to_actions(row[4]) p2_actions = str_to_actions(row[5]) interaction = list(zip(p1_actions, p2_actions)) try: pairs_to_interactions[index_pair].append(interaction) except KeyError: pairs_to_interactions[index_pair] = [interaction] if progress_bar: progress_bar.update() if progress_bar: progress_bar.close() return pairs_to_interactions
def convert_key(old_key: tuple) -> Plays: opponent_start, player, opponent = old_key return Plays( self_plays=str_to_actions(player), op_plays=str_to_actions(opponent), op_openings=str_to_actions(opponent_start), )
def _get_actions_cycle_against_cooperator(cycle_string: str): """Converts str like 'CCDC' to an itertools.cycle against Cooperator. The above example returns: itertools.cycle([(C, C), (C, C), (D, C), (C, C)])""" cooperator_opponent_action = C action_iterator = str_to_actions(cycle_string) out = [(action, cooperator_opponent_action) for action in action_iterator] return itertools.cycle(out)
def _normalize_parameters(cls, lookup_dict=None, initial_actions=None, pattern=None, parameters=None, mutation_probability=None): if lookup_dict and initial_actions: # Compute the associated pattern and parameters # Map the table keys to namedTuple Plays lookup_table = cls._get_lookup_table(lookup_dict, pattern, parameters) lookup_dict = lookup_table.dictionary parameters = (lookup_table.player_depth, lookup_table.op_depth, lookup_table.op_openings_depth) pattern = tuple(v for k, v in sorted(lookup_dict.items())) elif pattern and parameters and initial_actions: # Compute the associated lookup table plays, op_plays, op_start_plays = parameters lookup_table = cls._get_lookup_table(lookup_dict, pattern, parameters) lookup_dict = lookup_table.dictionary elif parameters: # Generate a random pattern and (maybe) initial actions plays, op_plays, op_start_plays = parameters pattern, lookup_table = cls.random_params(plays, op_plays, op_start_plays) lookup_dict = lookup_table.dictionary if not initial_actions: num_actions = max([plays, op_plays, op_start_plays]) initial_actions = tuple([choice((C, D)) for _ in range(num_actions)]) else: raise InsufficientParametersError("Insufficient Parameters to instantiate EvolvableLookerUp") # Normalize pattern if isinstance(pattern, str): pattern = str_to_actions(pattern) pattern = tuple(pattern) if mutation_probability is None: plays, op_plays, op_start_plays = parameters keys = create_lookup_table_keys(plays, op_plays, op_start_plays) mutation_probability = 2. / len(keys) return lookup_dict, initial_actions, pattern, parameters, mutation_probability
def _get_actions_cycle_against_cooperator(cycle_string: str): """Converts str like 'CCDC' to an itertools.cycle against Cooperator. The above example returns: itertools.cycle([(C, C), (C, C), (D, C), (C, C)])""" cooperator_opponent_action = C action_iterator = str_to_actions(cycle_string) out = [(action, cooperator_opponent_action) for action in action_iterator] return itertools.cycle(out)
def _get_lookup_table(self, lookup_dict: dict, pattern: Any, parameters: tuple) -> LookupTable: if lookup_dict: return LookupTable(lookup_dict=lookup_dict) if pattern is not None and parameters is not None: if isinstance(pattern, str): pattern = str_to_actions(pattern) self_depth, op_depth, op_openings_depth = parameters return LookupTable.from_pattern(pattern, self_depth, op_depth, op_openings_depth) return LookupTable(self.default_tft_lookup_table)
def read_match_chunks(self, progress_bar=False): """ A generator to return a given repetitions of matches Parameters ---------- progress_bar : bool whether or not to display a progress bar Yields ------ repetitions : list A list of lists include index pairs, player pairs and repetitions. All repetitions for a given pair are yielded together. """ if progress_bar: progress_bar = self.create_progress_bar(desc="Analysing") with open(self.filename, 'r') as f: csv_reader = csv.reader(f) repetitions = [] count = 0 for row in csv_reader: index_and_names = row[:4] p1_actions = str_to_actions(row[4]) p2_actions = str_to_actions(row[5]) interactions = list(zip(p1_actions, p2_actions)) repetitions.append(index_and_names + interactions) count += 1 if progress_bar: progress_bar.update() if count == self.repetitions: yield repetitions repetitions = [] count = 0 if progress_bar: progress_bar.close()
def _get_lookup_table( self, lookup_dict: dict, pattern: Any, parameters: tuple ) -> LookupTable: if lookup_dict: return LookupTable(lookup_dict=lookup_dict) if pattern is not None and parameters is not None: if isinstance(pattern, str): pattern = str_to_actions(pattern) self_depth, op_depth, op_openings_depth = parameters return LookupTable.from_pattern( pattern, self_depth, op_depth, op_openings_depth ) return LookupTable(self.default_tft_lookup_table)
def mutate(self) -> EvolvablePlayer: """ Basic mutation which may change any random actions in the sequence. """ if random.random() <= self.mutation_probability: mutated_sequence = list(str_to_actions(self.cycle)) for _ in range(self.mutation_potency): index_to_change = random.randint(0, len(mutated_sequence) - 1) mutated_sequence[index_to_change] = mutated_sequence[index_to_change].flip() cycle = actions_to_str(mutated_sequence) else: cycle = self.cycle cycle, _ = self._normalize_parameters(cycle) return self.create_new(cycle=cycle)
def test_str_to_actions(self): self.assertEqual(str_to_actions(""), ()) self.assertEqual(str_to_actions("C"), (C, )) self.assertEqual(str_to_actions("CDDC"), (C, D, D, C))
def get_new_itertools_cycle(self): return itertools.cycle(str_to_actions(self.cycle_str))
def test_str_to_actions(self): self.assertEqual(str_to_actions(''), ()) self.assertEqual(str_to_actions('C'), (C, )) self.assertEqual(str_to_actions('CDDC'), (C, D, D, C))
def set_cycle(self, cycle: str): """Set or change the cycle.""" self.cycle = cycle self.cycle_iter = itertools.cycle(str_to_actions(self.cycle)) self.classifier["memory_depth"] = len(cycle) - 1