11from axelrod import Player , obey_axelrod
22from ._strategies import strategies
3- from .hunter import DefectorHunter , AlternatorHunter , RandomHunter , MathConstantHunter
4-
3+ from .hunter import DefectorHunter , AlternatorHunter , RandomHunter , MathConstantHunter , CycleHunter , EventualCycleHunter
4+ from . cooperator import Cooperator
55
66# Needs to be computed manually to prevent circular dependency
77ordinary_strategies = [s for s in strategies if obey_axelrod (s )]
1010class MetaPlayer (Player ):
1111 """A generic player that has its own team of players."""
1212
13- team = []
13+ name = "Meta Player"
14+
15+ team = [Cooperator ]
1416 classifier = {
1517 'memory_depth' : float ('inf' ), # Long memory
1618 'stochastic' : False ,
@@ -30,9 +32,12 @@ def __init__(self):
3032 # Initiate all the player in out team.
3133 self .team = [t () for t in self .team ]
3234
33- # If the team will have stochastic players, this meta is also stochastic.
34- self .classifier ['stochastic' ] = (
35- any ([t .classifier ['stochastic' ] for t in self .team ]))
35+ # This player inherits the classifiers of its team.
36+ for key in ['stochastic' , 'inspects_source' , 'manipulates_source' ,
37+ 'manipulates_state' ]:
38+ self .classifier [key ] = (any ([t .classifier [key ] for t in self .team ]))
39+ self .classifier ['memory_depth' ] = max ([t .classifier ['memory_depth' ] for
40+ t in self .team ])
3641
3742 def strategy (self , opponent ):
3843
@@ -62,9 +67,14 @@ class MetaMajority(MetaPlayer):
6267
6368 name = "Meta Majority"
6469
65- def __init__ (self ):
66- self .team = ordinary_strategies
70+ def __init__ (self , team = None ):
71+ if team :
72+ self .team = team
73+ else :
74+ # Needs to be computed manually to prevent circular dependency
75+ self .team = ordinary_strategies
6776 super (MetaMajority , self ).__init__ ()
77+ self .init_args = (team ,)
6878
6979 def meta_strategy (self , results , opponent ):
7080 if results .count ('D' ) > results .count ('C' ):
@@ -77,9 +87,14 @@ class MetaMinority(MetaPlayer):
7787
7888 name = "Meta Minority"
7989
80- def __init__ (self ):
81- self .team = ordinary_strategies
90+ def __init__ (self , team = None ):
91+ if team :
92+ self .team = team
93+ else :
94+ # Needs to be computed manually to prevent circular dependency
95+ self .team = ordinary_strategies
8296 super (MetaMinority , self ).__init__ ()
97+ self .init_args = (team ,)
8398
8499 def meta_strategy (self , results , opponent ):
85100 if results .count ('D' ) < results .count ('C' ):
@@ -116,8 +131,6 @@ def strategy(self, opponent):
116131 # Update the running score for each player, before determining the next move.
117132 if len (self .history ):
118133 for player in self .team :
119- pl_C = player .proposed_history [- 1 ] == "C"
120- opp_C = opponent .history [- 1 ] == "C"
121134 game = self .tournament_attributes ["game" ]
122135 s = game .scores [(player .proposed_history [- 1 ], opponent .history [- 1 ])][0 ]
123136 player .score += s
@@ -136,6 +149,10 @@ def meta_strategy(self, results, opponent):
136149 for r , t in zip (results , self .team ):
137150 t .proposed_history .append (r )
138151
152+ if opponent .defections == 0 :
153+ # Don't poke the bear
154+ return 'C'
155+
139156 return bestresult
140157
141158
@@ -157,7 +174,7 @@ def __init__(self):
157174 # to hunters that use defections as cues. However, a really tangible benefit comes from
158175 # combining Random Hunter and Math Constant Hunter, since together they catch strategies
159176 # that are lightly randomized but still quite constant (the tricky/suspecious ones).
160- self .team = [DefectorHunter , AlternatorHunter , RandomHunter , MathConstantHunter ]
177+ self .team = [DefectorHunter , AlternatorHunter , RandomHunter , MathConstantHunter , CycleHunter , EventualCycleHunter ]
161178
162179 super (MetaHunter , self ).__init__ ()
163180
@@ -175,3 +192,69 @@ def meta_strategy(results, opponent):
175192 return 'D' if opponent .history [- 1 :] == ['D' ] else 'C'
176193 else :
177194 return 'C'
195+
196+
197+ class MetaMajorityMemoryOne (MetaMajority ):
198+ """MetaMajority with the team of Memory One players"""
199+
200+ name = "Meta Majority Memory One"
201+
202+ def __init__ (self ):
203+ team = [s for s in ordinary_strategies if s ().classifier ['memory_depth' ] <= 1 ]
204+ super (MetaMajorityMemoryOne , self ).__init__ (team = team )
205+ self .init_args = ()
206+
207+
208+ class MetaWinnerMemoryOne (MetaWinner ):
209+ """MetaWinner with the team of Memory One players"""
210+
211+ name = "Meta Winner Memory One"
212+
213+ def __init__ (self ):
214+ team = [s for s in ordinary_strategies if s ().classifier ['memory_depth' ] <= 1 ]
215+ super (MetaWinnerMemoryOne , self ).__init__ (team = team )
216+ self .init_args = ()
217+
218+
219+ class MetaMajorityFiniteMemory (MetaMajority ):
220+ """MetaMajority with the team of Finite Memory Players"""
221+
222+ name = "Meta Majority Finite Memory"
223+ def __init__ (self ):
224+ team = [s for s in ordinary_strategies if s ().classifier ['memory_depth' ]
225+ < float ('inf' )]
226+ super (MetaMajorityFiniteMemory , self ).__init__ (team = team )
227+ self .init_args = ()
228+
229+
230+ class MetaWinnerFiniteMemory (MetaWinner ):
231+ """MetaWinner with the team of Finite Memory Players"""
232+
233+ name = "Meta Winner Finite Memory"
234+ def __init__ (self ):
235+ team = [s for s in ordinary_strategies if s ().classifier ['memory_depth' ]
236+ < float ('inf' )]
237+ super (MetaWinnerFiniteMemory , self ).__init__ (team = team )
238+ self .init_args = ()
239+
240+
241+ class MetaMajorityLongMemory (MetaMajority ):
242+ """MetaMajority with the team of Long (infinite) Memory Players"""
243+
244+ name = "Meta Majority Long Memory"
245+ def __init__ (self ):
246+ team = [s for s in ordinary_strategies if s ().classifier ['memory_depth' ]
247+ == float ('inf' )]
248+ super (MetaMajorityLongMemory , self ).__init__ (team = team )
249+ self .init_args = ()
250+
251+
252+ class MetaWinnerLongMemory (MetaWinner ):
253+ """MetaWinner with the team of Long (infinite) Memory Players"""
254+
255+ name = "Meta Winner Long Memory"
256+ def __init__ (self ):
257+ team = [s for s in ordinary_strategies if s ().classifier ['memory_depth' ]
258+ == float ('inf' )]
259+ super (MetaWinnerLongMemory , self ).__init__ (team = team )
260+ self .init_args = ()
0 commit comments