diff --git a/axelrod/strategies/_strategies.py b/axelrod/strategies/_strategies.py index c2582c8dd..62f9071e6 100644 --- a/axelrod/strategies/_strategies.py +++ b/axelrod/strategies/_strategies.py @@ -67,6 +67,7 @@ Retaliate, Retaliate2, Retaliate3, LimitedRetaliate, LimitedRetaliate2, LimitedRetaliate3) from .sequence_player import SequencePlayer, ThueMorse, ThueMorseInverse +from .selfsteem import SelfSteem from .shortmem import ShortMem from .titfortat import ( TitForTat, TitFor2Tats, TwoTitsForTat, Bully, SneakyTitForTat, @@ -210,6 +211,7 @@ RevisedDowning, Ripoff, RiskyQLearner, + SelfSteem, ShortMem, Shubik, SlowTitForTwoTats, diff --git a/axelrod/strategies/selfsteem.py b/axelrod/strategies/selfsteem.py new file mode 100644 index 000000000..04576407a --- /dev/null +++ b/axelrod/strategies/selfsteem.py @@ -0,0 +1,53 @@ +from axelrod.actions import Action, Actions +from axelrod.player import Player +from axelrod.random_ import random_choice + +from math import pi, sin + +C, D = Actions.C, Actions.D + + +class SelfSteem(Player): + """ + This strategy is based on the feeling with the same name. + It is modeled on the sine curve(f = sin( 2* pi * n / 10 )), which varies + with the current iteration. + + If f > 0.95, 'ego' of the algorithm is inflated; always defects. + If 0.95 > abs(f) > 0.3, rational behavior; follows TitForTat algortithm. + If 0.3 > f > -0.3; random behavior. + If f < -0.95, algorithm is at rock bottom; always cooperates. + + Futhermore, the algorithm implements a retaliation policy, if the opponent + defects; the sin curve is shifted. But due to lack of further information, + this implementation does not include a sin phase change. + Names: + + - SelfSteem: [Andre2013]_ + """ + + name = 'SelfSteem' + classifier = { + 'memory_depth': float("inf"), + 'stochastic': True, + 'makes_use_of': set(), + 'long_run_time': False, + 'inspects_source': False, + 'manipulates_source': False, + 'manipulates_state': False + } + + def strategy(self, opponent: Player) -> Action: + turns_number = len(self.history) + sine_value = sin(2 * pi * turns_number / 10) + + if sine_value > 0.95: + return D + + if abs(sine_value) < 0.95 and abs(sine_value) > 0.3: + return opponent.history[-1] + + if sine_value < 0.3 and sine_value > -0.3: + return random_choice() + + return C diff --git a/axelrod/tests/unit/test_selfsteem.py b/axelrod/tests/unit/test_selfsteem.py new file mode 100644 index 000000000..60e2f9831 --- /dev/null +++ b/axelrod/tests/unit/test_selfsteem.py @@ -0,0 +1,38 @@ +"""Tests for the SelfSteem strategy.""" + +import axelrod +import random +from .test_player import TestPlayer + +C, D = axelrod.Actions.C, axelrod.Actions.D + +class TestSelfSteem(TestPlayer): + + name = "SelfSteem" + player = axelrod.SelfSteem + expected_classifier = { + 'memory_depth': float("inf"), + 'stochastic': True, + 'makes_use_of': set(), + 'inspects_source': False, + 'manipulates_source': False, + 'manipulates_state': False + } + + def test_strategy(self): + # Check for f > 0.95 + self.responses_test([D], [C] * 2 , [C] * 2) + self.responses_test([D], [C] * 13, [C] * 13) + + # Check for f < -0.95 + self.responses_test([C], [C] * 7, [C] * 7) + self.responses_test([C], [C] * 18, [D] * 18) + + # Check for -0.3 < f < 0.3 + self.responses_test([C], [C] * 20, [C] * 20, seed=6) + self.responses_test([D], [C] * 20, [D] * 20, seed=5) + + # Check for 0.95 > abs(f) > 0.3 + self.responses_test([C], [C], [C]) + self.responses_test([D], [C] * 16, [D] * 16) + self.responses_test([C], [D] * 9, [C] * 9) diff --git a/docs/reference/all_strategies.rst b/docs/reference/all_strategies.rst index 0ce535c85..46bb9e98c 100644 --- a/docs/reference/all_strategies.rst +++ b/docs/reference/all_strategies.rst @@ -135,6 +135,9 @@ Here are the docstrings of all the strategies in the library. .. automodule:: axelrod.strategies.shortmem :members: :undoc-members: +.. automodule:: axelrod.strategies.selfsteem + :members: + :undoc-members: .. automodule:: axelrod.strategies.titfortat :members: :undoc-members: diff --git a/docs/reference/bibliography.rst b/docs/reference/bibliography.rst index 68ee55e83..fda82e109 100644 --- a/docs/reference/bibliography.rst +++ b/docs/reference/bibliography.rst @@ -6,6 +6,7 @@ Bibliography This is a collection of various bibliographic items referenced in the documentation. +.. [Andre2013] Andre L. C., Honovan P., Felipe T. and Frederico G. (2013). Iterated Prisoner’s Dilemma - An extended analysis, http://abricom.org.br/wp-content/uploads/2016/03/bricsccicbic2013_submission_202.pdf .. [Ashlock2006] Ashlock, D., & Kim E. Y, & Leahy, N. (2006). Understanding Representational Sensitivity in the Iterated Prisoner’s Dilemma with Fingerprints. IEEE Transactions On Systems, Man, And Cybernetics, Part C: Applications And Reviews, 36 (4) .. [Ashlock2008] Ashlock, D., & Kim, E. Y. (2008). Fingerprinting: Visualization and automatic analysis of prisoner’s dilemma strategies. IEEE Transactions on Evolutionary Computation, 12(5), 647–659. http://doi.org/10.1109/TEVC.2008.920675 .. [Ashlock2009] Ashlock, D., Kim, E. Y., & Ashlock, W. (2009) Fingerprint analysis of the noisy prisoner’s dilemma using a finite-state representation. IEEE Transactions on Computational Intelligence and AI in Games. 1(2), 154-167 http://doi.org/10.1109/TCIAIG.2009.2018704 @@ -37,4 +38,3 @@ documentation. .. [Stewart2012] Stewart, a. J., & Plotkin, J. B. (2012). Extortion and cooperation in the Prisoner’s Dilemma. Proceedings of the National Academy of Sciences, 109(26), 10134–10135. http://doi.org/10.1073/pnas.1208087109 .. [Szabó1992] Szabó, G., & Fáth, G. (2007). Evolutionary games on graphs. Physics Reports, 446(4-6), 97–216. http://doi.org/10.1016/j.physrep.2007.04.004 .. [Tzafestas2000] Tzafestas, E. (2000). Toward adaptive cooperative behavior. From Animals to Animals: Proceedings of the 6th International Conference on the Simulation of Adaptive Behavior {(SAB-2000)}, 2, 334–340. -.. [Andre2013] Andre L. C., Honovan P., Felipe T. and Frederico G. (2013). Iterated Prisoner’s Dilemma - An extended analysis, http://abricom.org.br/wp-content/uploads/2016/03/bricsccicbic2013_submission_202.pdf diff --git a/docs/tutorials/advanced/classification_of_strategies.rst b/docs/tutorials/advanced/classification_of_strategies.rst index 4a025693d..dfd6e98f1 100644 --- a/docs/tutorials/advanced/classification_of_strategies.rst +++ b/docs/tutorials/advanced/classification_of_strategies.rst @@ -47,7 +47,7 @@ strategies:: ... } >>> strategies = axl.filtered_strategies(filterset) >>> len(strategies) - 64 + 65 Or, to find out how many strategies only use 1 turn worth of memory to make a decision::