-
Notifications
You must be signed in to change notification settings - Fork 282
an idea for Geller, Darwin, MindReader #950
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4d9fe7e
84e12fd
52beae4
2b66fdf
a74f865
b570aec
ec34b38
8b401fa
b45d11d
284bc32
d09d2b7
e8328d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,11 +3,11 @@ | |
| indicated by their classifier). We do not recommend putting a lot of time in to | ||
| optimising them. | ||
| """ | ||
| import inspect | ||
|
|
||
| from axelrod.actions import Actions, Action | ||
| from axelrod.player import Player | ||
| from axelrod.random_ import random_choice | ||
| from axelrod._strategy_utils import inspect_strategy | ||
|
|
||
| C, D = Actions.C, Actions.D | ||
|
|
||
|
|
@@ -36,7 +36,6 @@ class Geller(Player): | |
| """ | ||
|
|
||
| name = 'Geller' | ||
| default = lambda self: random_choice(0.5) | ||
| classifier = { | ||
| 'memory_depth': -1, | ||
| 'stochastic': True, | ||
|
|
@@ -47,27 +46,26 @@ class Geller(Player): | |
| 'manipulates_state': False | ||
| } | ||
|
|
||
| @staticmethod | ||
| def foil_strategy_inspection() -> Action: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Docstring. |
||
| """Foils _strategy_utils.inspect_strategy and _strategy_utils.look_ahead""" | ||
| return random_choice(0.5) | ||
|
|
||
| def strategy(self, opponent: Player) -> Action: | ||
| """ | ||
| Look at what the opponent will play in the next round and choose a strategy | ||
| that gives the least jail time, which is is equivalent to playing the same | ||
| strategy as that which the opponent will play. | ||
| """ | ||
| curframe = inspect.currentframe() | ||
| calframe = inspect.getouterframes(curframe, 2) | ||
| calname = calframe[1][3] | ||
| if calname == 'strategy': | ||
| return self.default() | ||
| else: | ||
| return opponent.strategy(self) | ||
|
|
||
| return inspect_strategy(self, opponent) | ||
|
|
||
|
|
||
| class GellerCooperator(Geller): | ||
| """Observes what the payer will do (like :code:`Geller`) but if unable to | ||
| will cooperate. | ||
| """ | ||
| name = 'Geller Cooperator' | ||
| default = lambda self: C | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the IDE balked at making a variable a lambda and recommended changing to a function. so i did. |
||
| classifier = { | ||
| 'memory_depth': -1, | ||
| 'stochastic': False, | ||
|
|
@@ -78,13 +76,17 @@ class GellerCooperator(Geller): | |
| 'manipulates_state': False | ||
| } | ||
|
|
||
| @staticmethod | ||
| def foil_strategy_inspection() -> Action: | ||
| """Foils _strategy_utils.inspect_strategy and _strategy_utils.look_ahead""" | ||
| return C | ||
|
|
||
|
|
||
| class GellerDefector(Geller): | ||
| """Observes what the payer will do (like :code:`Geller`) but if unable to | ||
| will defect. | ||
| """ | ||
| name = 'Geller Defector' | ||
| default = lambda self: D | ||
| classifier = { | ||
| 'memory_depth': -1, | ||
| 'stochastic': False, | ||
|
|
@@ -94,3 +96,8 @@ class GellerDefector(Geller): | |
| 'manipulates_source': False, | ||
| 'manipulates_state': False | ||
| } | ||
|
|
||
| @staticmethod | ||
| def foil_strategy_inspection() -> Action: | ||
| """Foils _strategy_utils.inspect_strategy and _strategy_utils.look_ahead""" | ||
| return D | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,15 +3,14 @@ | |
| indicated by their classifier). We do not recommend putting a lot of time in to | ||
| optimising them. | ||
| """ | ||
| import inspect | ||
|
|
||
| from axelrod.actions import Actions, Action | ||
| from axelrod.player import Player | ||
| from axelrod._strategy_utils import look_ahead | ||
| from axelrod._strategy_utils import look_ahead, inspect_strategy | ||
|
|
||
|
|
||
| C, D = Actions.C, Actions.D | ||
|
|
||
|
|
||
| class MindReader(Player): | ||
| """A player that looks ahead at what the opponent will do and decides what | ||
| to do.""" | ||
|
|
@@ -27,23 +26,17 @@ class MindReader(Player): | |
| 'manipulates_state': False | ||
| } | ||
|
|
||
| @staticmethod | ||
| def foil_strategy_inspection() -> Action: | ||
| """Foils _strategy_utils.inspect_strategy and _strategy_utils.look_ahead""" | ||
| return D | ||
|
|
||
| def strategy(self, opponent: Player) -> Action: | ||
| """Pretends to play the opponent a number of times before each match. | ||
| """ | ||
| Pretends to play the opponent a number of times before each match. | ||
| The primary purpose is to look far enough ahead to see if a defect will | ||
| be punished by the opponent. | ||
|
|
||
| If the MindReader attempts to play itself (or another similar | ||
| strategy), then it will cause a recursion loop, so this is also handled | ||
| in this method, by defecting if the method is called by strategy | ||
| """ | ||
|
|
||
| curframe = inspect.currentframe() | ||
| calframe = inspect.getouterframes(curframe, 2) | ||
| calname = calframe[1][3] | ||
|
|
||
| if calname in ('strategy', 'simulate_match'): | ||
| return D | ||
|
|
||
| game = self.match_attributes["game"] | ||
|
|
||
| best_strategy = look_ahead(self, opponent, game) | ||
|
|
@@ -74,6 +67,7 @@ def __setattr__(self, name: str, val: str): | |
| else: | ||
| self.__dict__[name] = val | ||
|
|
||
|
|
||
| class MirrorMindReader(ProtectedMindReader): | ||
| """A player that will mirror whatever strategy it is playing against by | ||
| cheating and calling the opponent's strategy function instead of its own.""" | ||
|
|
@@ -90,18 +84,11 @@ class MirrorMindReader(ProtectedMindReader): | |
| 'manipulates_state': False | ||
| } | ||
|
|
||
| def strategy(self, opponent: Player) -> Action: | ||
| """Will read the mind of the opponent and play the opponent's strategy. | ||
|
|
||
| Also avoid infinite recursion when called by itself or another mind | ||
| reader or bender by cooperating. | ||
| """ | ||
| @staticmethod | ||
| def foil_strategy_inspection() -> Action: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Docstring please. |
||
| """Foils _strategy_utils.inspect_strategy and _strategy_utils.look_ahead""" | ||
| return C | ||
|
|
||
| curframe = inspect.currentframe() | ||
| calframe = inspect.getouterframes(curframe, 2) | ||
| calname = calframe[1][3] | ||
|
|
||
| if calname in ('strategy', 'simulate_match'): | ||
| return C | ||
|
|
||
| return opponent.strategy(self) | ||
| def strategy(self, opponent: Player) -> Action: | ||
| """Will read the mind of the opponent and play the opponent's strategy. """ | ||
| return inspect_strategy(self, opponent) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,9 +30,13 @@ def test_setup(self): | |
| self.assertEqual(player.genome, [C]) | ||
| self.assertEqual(player.history, []) | ||
|
|
||
| def test_foil_strategy_inspection(self): | ||
| self.assertEqual(self.player().foil_strategy_inspection(), C) | ||
|
|
||
| def test_strategy(self): | ||
| p1 = self.player() | ||
| p1.reset() | ||
|
|
||
| self.versus_test(axelrod.Cooperator(), expected_actions=[(C, C)] * 5, attrs={'genome': [C] * 5}) | ||
|
|
||
| expected_genome = [D] * 4 + [C] | ||
|
|
@@ -47,23 +51,6 @@ def test_against_geller_and_mindreader(self): | |
|
|
||
| self.versus_test(axelrod.MindReader(), expected_actions=[(C, D)] * 2, attrs={'genome': [D, C]}) | ||
|
|
||
| def test_play(self): | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when i refactored test_darwin, i forgot to recommend removing test_play(self). Because versus_test calls "play", these are now redundant. |
||
| """valid_callers must contain at least one entry...""" | ||
| self.assertTrue(len(self.player.valid_callers) > 0) | ||
| """...and should allow round_robin.play to call""" | ||
| self.assertTrue("play" in self.player.valid_callers) | ||
| self.play() | ||
| self.play() | ||
|
|
||
| def play(self): | ||
| """We need this to circumvent the agent's anti-inspection measure""" | ||
| p1 = self.player() | ||
| p2 = axelrod.Player() | ||
| p1.reset() | ||
| p1.strategy(p2) | ||
| # Genome contains only valid responses. | ||
| self.assertEqual(p1.genome.count(C) + p1.genome.count(D), len(p1.genome)) | ||
|
|
||
| def test_reset_only_resets_first_move_of_genome(self): | ||
| self.versus_test(axelrod.Defector(), expected_actions=[(C, D)] + [(D, D)] * 4) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a docstring here please.