Skip to content

Commit 1585233

Browse files
Merge pull request #1231 from gaffney2010/some-ashlock-strats
Added some of the strategies listed in Ashlock2009.
2 parents 3315c9f + 3c12ba5 commit 1585233

File tree

6 files changed

+135
-1
lines changed

6 files changed

+135
-1
lines changed

axelrod/strategies/_strategies.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@
7676
Pun1,
7777
Raider,
7878
Ripoff,
79+
UsuallyCooperates,
80+
UsuallyDefects,
7981
SolutionB1,
8082
SolutionB5,
8183
Thumper,
@@ -421,6 +423,8 @@
421423
TrickyLevelPunisher,
422424
Tullock,
423425
TwoTitsForTat,
426+
UsuallyCooperates,
427+
UsuallyDefects,
424428
VeryBad,
425429
Weiner,
426430
White,

axelrod/strategies/finite_state_machines.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,68 @@ def __init__(self) -> None:
325325
super().__init__(transitions=transitions, initial_state=1, initial_action=D)
326326

327327

328+
class UsuallyCooperates(FSMPlayer):
329+
"""
330+
This strategy cooperates except after a C following a D.
331+
332+
Names:
333+
334+
- Usually Cooperates (UC): [Ashlock2009]_
335+
"""
336+
337+
name = "UsuallyCooperates"
338+
classifier = {
339+
"memory_depth": 2,
340+
"stochastic": False,
341+
"makes_use_of": set(),
342+
"long_run_time": False,
343+
"inspects_source": False,
344+
"manipulates_source": False,
345+
"manipulates_state": False,
346+
}
347+
348+
def __init__(self) -> None:
349+
transitions = (
350+
(1, C, 1, C),
351+
(1, D, 2, C),
352+
(2, C, 1, D),
353+
(2, D, 1, C),
354+
)
355+
356+
super().__init__(transitions=transitions, initial_state=1, initial_action=C)
357+
358+
359+
class UsuallyDefects(FSMPlayer):
360+
"""
361+
This strategy defects except after a D following a C.
362+
363+
Names:
364+
365+
- Usually Defects (UD): [Ashlock2009]_
366+
"""
367+
368+
name = "UsuallyDefects"
369+
classifier = {
370+
"memory_depth": 2,
371+
"stochastic": False,
372+
"makes_use_of": set(),
373+
"long_run_time": False,
374+
"inspects_source": False,
375+
"manipulates_source": False,
376+
"manipulates_state": False,
377+
}
378+
379+
def __init__(self) -> None:
380+
transitions = (
381+
(1, C, 2, D),
382+
(1, D, 1, D),
383+
(2, C, 1, D),
384+
(2, D, 1, C),
385+
)
386+
387+
super().__init__(transitions=transitions, initial_state=1, initial_action=D)
388+
389+
328390
class SolutionB1(FSMPlayer):
329391
"""
330392
FSM player described in http://DOI.org/10.1109/TCIAIG.2014.2326012.

axelrod/strategies/grudger.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class Grudger(Player):
1818
- Grim: [Berg2015]_
1919
- Grim Trigger: [Banks1990]_
2020
- Spite: [Beaufils1997]_
21+
- Vengeful: [Ashlock2009]_
2122
"""
2223

2324
name = "Grudger"

axelrod/strategies/titfortat.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ class AntiTitForTat(Player):
225225
Names:
226226
227227
- Anti Tit For Tat: [Hilbe2013]_
228+
- Psycho (PSYC): [Ashlock2009]_
228229
"""
229230

230231
name = "Anti Tit For Tat"

axelrod/tests/strategies/test_finite_state_machines.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,72 @@ def test_strategy(self):
512512
self.transitions_test(state_and_actions)
513513

514514

515+
class TestUsuallyCooperates(TestFSMPlayer):
516+
name = "UsuallyCooperates"
517+
player = axelrod.UsuallyCooperates
518+
expected_classifier = {
519+
"memory_depth": 2,
520+
"stochastic": False,
521+
"makes_use_of": set(),
522+
"long_run_time": False,
523+
"inspects_source": False,
524+
"manipulates_source": False,
525+
"manipulates_state": False,
526+
}
527+
"""
528+
transitions = (
529+
(1, C, 1, C),
530+
(1, D, 2, C),
531+
(2, C, 1, D),
532+
(2, D, 1, C)
533+
)
534+
"""
535+
536+
def test_strategy(self):
537+
# Never leaves state 1 if C
538+
state_and_actions = [(1, C)] * 10
539+
self.transitions_test(state_and_actions)
540+
# Visits state 2, but then comes back
541+
# Defaults if DC streak is complete. Starts streak over either way.
542+
state_and_actions = [(1, D), (2, D)]
543+
self.transitions_test(state_and_actions)
544+
state_and_actions = [(1, D), (2, C)]
545+
self.transitions_test(state_and_actions)
546+
547+
548+
class TestUsuallyDefects(TestFSMPlayer):
549+
name = "UsuallyDefects"
550+
player = axelrod.UsuallyDefects
551+
expected_classifier = {
552+
"memory_depth": 2,
553+
"stochastic": False,
554+
"makes_use_of": set(),
555+
"long_run_time": False,
556+
"inspects_source": False,
557+
"manipulates_source": False,
558+
"manipulates_state": False,
559+
}
560+
"""
561+
transitions = (
562+
(1, C, 2, D),
563+
(1, D, 1, D),
564+
(2, C, 1, D),
565+
(2, D, 1, C)
566+
)
567+
"""
568+
569+
def test_strategy(self):
570+
# Never leaves state 1 if D
571+
state_and_actions = [(1, D)] * 10
572+
self.transitions_test(state_and_actions)
573+
# Visits state 2, but then comes back
574+
# Cooperates if CD streak is complete. Starts streak over either way.
575+
state_and_actions = [(1, C), (2, D)]
576+
self.transitions_test(state_and_actions)
577+
state_and_actions = [(1, C), (2, C)]
578+
self.transitions_test(state_and_actions)
579+
580+
515581
class TestSolutionB1(TestFSMPlayer):
516582

517583
name = "SolutionB1"

docs/tutorials/advanced/classification_of_strategies.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ range of memory_depth values, we can use the 'min_memory_depth' and
6969
... }
7070
>>> strategies = axl.filtered_strategies(filterset)
7171
>>> len(strategies)
72-
59
72+
61
7373

7474
We can also identify strategies that make use of particular properties of the
7575
tournament. For example, here is the number of strategies that make use of the

0 commit comments

Comments
 (0)