Skip to content

Commit 715f67c

Browse files
authored
Merge pull request #1097 from Axelrod-Python/new_zd
Three new ZD strategies
2 parents fdf04dd + 441cc48 commit 715f67c

File tree

11 files changed

+669
-464
lines changed

11 files changed

+669
-464
lines changed

axelrod/strategies/_strategies.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@
5050
from .mathematicalconstants import Golden, Pi, e
5151
from .memoryone import (
5252
MemoryOnePlayer, ALLCorALLD, FirmButFair, GTFT, SoftJoss,
53-
StochasticCooperator, StochasticWSLS, ZDExtort2, ZDExtort2v2, ZDExtort4,
54-
ZDGen2, ZDGTFT2, ZDSet2, WinStayLoseShift, WinShiftLoseStay, ReactivePlayer)
53+
StochasticCooperator, StochasticWSLS, WinStayLoseShift, WinShiftLoseStay,
54+
ReactivePlayer)
5555
from .memorytwo import MEM2
5656
from .mindcontrol import MindController, MindWarper, MindBender
5757
from .mindreader import MindReader, ProtectedMindReader, MirrorMindReader
@@ -76,10 +76,14 @@
7676
TitForTat, TitFor2Tats, TwoTitsForTat, Bully, SneakyTitForTat,
7777
SuspiciousTitForTat, AntiTitForTat, HardTitForTat, HardTitFor2Tats,
7878
OmegaTFT, Gradual, ContriteTitForTat, AdaptiveTitForTat,
79-
SpitefulTitForTat, SlowTitForTwoTats2, Alexei, EugineNier, DynamicTwoTitsForTat, NTitsForMTats)
79+
SpitefulTitForTat, SlowTitForTwoTats2, Alexei, EugineNier,
80+
DynamicTwoTitsForTat, NTitsForMTats)
8081
from .verybad import VeryBad
8182
from .worse_and_worse import (WorseAndWorse, KnowledgeableWorseAndWorse,
8283
WorseAndWorse2, WorseAndWorse3)
84+
from .zero_determinant import (
85+
ZDExtortion, ZDExtort2, ZDExtort3, ZDExtort2v2, ZDExtort4, ZDGen2, ZDGTFT2,
86+
ZDMischief, ZDSet2)
8387

8488
# Note: Meta* strategies are handled in .__init__.py
8589

@@ -259,11 +263,14 @@
259263
WorseAndWorse,
260264
WorseAndWorse2,
261265
WorseAndWorse3,
266+
ZDExtortion,
262267
ZDExtort2,
268+
ZDExtort3,
263269
ZDExtort2v2,
264270
ZDExtort4,
265271
ZDGTFT2,
266272
ZDGen2,
273+
ZDMischief,
267274
ZDSet2,
268275
e,
269276
DynamicTwoTitsForTat,

axelrod/strategies/memoryone.py

Lines changed: 10 additions & 241 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
"""Memory One strategies. Note that there are Memory One strategies in other
2+
files, including titfortat.py and zero_determinant.py"""
3+
14
from axelrod.action import Action
25
from axelrod.player import Player
36
from axelrod.random_ import random_choice
@@ -33,7 +36,8 @@ class MemoryOnePlayer(Player):
3336
'manipulates_state': False
3437
}
3538

36-
def __init__(self, four_vector: type_four_vector = None, initial: Action = C) -> None:
39+
def __init__(self, four_vector: type_four_vector = None,
40+
initial: Action = C) -> None:
3741
"""
3842
Parameters
3943
@@ -201,10 +205,10 @@ def __init__(self) -> None:
201205
class StochasticCooperator(MemoryOnePlayer):
202206
"""Stochastic Cooperator.
203207
204-
Names:
208+
Names:
205209
206-
- Stochastic Cooperator: [Adami2013]_
207-
"""
210+
- Stochastic Cooperator: [Adami2013]_
211+
"""
208212

209213
name = 'Stochastic Cooperator'
210214

@@ -241,247 +245,11 @@ def __init__(self, ep: float = 0.05) -> None:
241245
"""
242246

243247
self.ep = ep
244-
four_vector = (1.-ep, ep, ep, 1.-ep)
248+
four_vector = (1. - ep, ep, ep, 1. - ep)
245249
super().__init__(four_vector)
246250
self.set_four_vector(four_vector)
247251

248252

249-
class LRPlayer(MemoryOnePlayer):
250-
"""Abstraction for Linear Relation players. These players enforce a linear
251-
difference in stationary payoffs s * (S_xy - l) = S_yx - l, with 0 <= l <= R.
252-
The parameter `s` is called the slope and the parameter `l` the
253-
baseline payoff. For extortionate strategies, the extortion factor is the
254-
inverse of the slope.
255-
256-
This parameterization is Equation 14 in
257-
http://journals.plos.org/plosone/article?id=10.1371/journal.pone.0077886.
258-
See Figure 2 of the article for a more in-depth explanation.
259-
260-
Names:
261-
262-
- Linear Relation player: [Hilbe2013]_
263-
"""
264-
265-
name = 'LinearRelation'
266-
classifier = {
267-
'memory_depth': 1, # Memory-one Four-Vector
268-
'stochastic': True,
269-
'makes_use_of': set(["game"]),
270-
'long_run_time': False,
271-
'inspects_source': False,
272-
'manipulates_source': False,
273-
'manipulates_state': False
274-
}
275-
276-
277-
def receive_match_attributes(self, phi: float = 0, s: float = None, l: float = None):
278-
"""
279-
Parameters
280-
281-
phi, s, l: floats
282-
Parameter used to compute the four-vector according to the
283-
parameterization of the strategies below.
284-
"""
285-
286-
(R, P, S, T) = self.match_attributes["game"].RPST()
287-
if s is None:
288-
s = 1
289-
if l is None:
290-
l = R
291-
292-
# Check parameters
293-
s_min = - min((T-l) / (l-S), (l-S) / (T-l))
294-
if (l < P) or (l > R) or (s > 1) or (s < s_min):
295-
raise ValueError
296-
297-
p1 = 1 - phi * (1 - s) * (R - l)
298-
p2 = 1 - phi * (s * (l - S) + (T - l))
299-
p3 = phi * ((l - S) + s * (T - l))
300-
p4 = phi * (1 - s) * (l - P)
301-
302-
four_vector = [p1, p2, p3, p4]
303-
self.set_four_vector(four_vector)
304-
305-
306-
class ZDExtort2(LRPlayer):
307-
"""
308-
An Extortionate Zero Determinant Strategy with l=P.
309-
310-
Names:
311-
312-
- Extort-2: [Stewart2012]_
313-
"""
314-
315-
name = 'ZD-Extort-2'
316-
317-
def __init__(self, phi: float = 1/9, s: float = 0.5) -> None:
318-
"""
319-
Parameters
320-
321-
phi, s: floats
322-
Parameters passed through to LRPlayer to determine
323-
the four vector.
324-
"""
325-
self.phi = phi
326-
self.s = s
327-
super().__init__()
328-
329-
def receive_match_attributes(self):
330-
(R, P, S, T) = self.match_attributes["game"].RPST()
331-
self.l = P
332-
super().receive_match_attributes(
333-
self.phi, self.s, self.l)
334-
335-
336-
class ZDExtort2v2(LRPlayer):
337-
"""
338-
An Extortionate Zero Determinant Strategy with l=1.
339-
340-
341-
Names:
342-
343-
- EXTORT2: [Kuhn2017]_
344-
"""
345-
346-
name = 'ZD-Extort-2 v2'
347-
348-
def __init__(self, phi: float = 1/8, s: float = 0.5, l: float = 1) -> None:
349-
"""
350-
Parameters
351-
352-
phi, s: floats
353-
Parameters passed through to LRPlayer to determine
354-
the four vector.
355-
"""
356-
self.phi = phi
357-
self.s = s
358-
self.l = l
359-
super().__init__()
360-
361-
def receive_match_attributes(self):
362-
super().receive_match_attributes(
363-
self.phi, self.s, self.l)
364-
365-
366-
class ZDExtort4(LRPlayer):
367-
"""
368-
An Extortionate Zero Determinant Strategy with l=1, s=1/4. TFT is the
369-
other extreme (with l=3, s=1)
370-
371-
372-
Names:
373-
374-
- Extort 4: Original name by Marc Harper
375-
"""
376-
377-
name = 'ZD-Extort-4'
378-
379-
def __init__(self, phi: float = 4/17, s: float = 0.25, l: float = 1) -> None:
380-
"""
381-
Parameters
382-
383-
phi, s: floats
384-
Parameters passed through to LRPlayer to determine
385-
the four vector.
386-
"""
387-
self.phi = phi
388-
self.s = s
389-
self.l = l
390-
super().__init__()
391-
392-
def receive_match_attributes(self):
393-
super().receive_match_attributes(
394-
self.phi, self.s, self.l)
395-
396-
397-
class ZDGen2(LRPlayer):
398-
"""
399-
A Generous Zero Determinant Strategy with l=3.
400-
401-
Names:
402-
403-
- GEN2: [Kuhn2017]_
404-
"""
405-
406-
name = 'ZD-GEN-2'
407-
408-
def __init__(self, phi: float = 1/8, s: float = 0.5, l: float = 3) -> None:
409-
"""
410-
Parameters
411-
412-
phi, s: floats
413-
Parameters passed through to LRPlayer to determine
414-
the four vector.
415-
"""
416-
self.phi = phi
417-
self.s = s
418-
self.l = l
419-
super().__init__()
420-
421-
def receive_match_attributes(self):
422-
super().receive_match_attributes(
423-
self.phi, self.s, self.l)
424-
425-
426-
class ZDGTFT2(LRPlayer):
427-
"""
428-
A Generous Zero Determinant Strategy with l=R.
429-
430-
Names:
431-
432-
- ZDGTFT-2: [Stewart2012]_
433-
"""
434-
435-
name = 'ZD-GTFT-2'
436-
437-
def __init__(self, phi: float = 0.25, s: float = 0.5) -> None:
438-
"""
439-
Parameters
440-
441-
phi, s: floats
442-
Parameters passed through to LRPlayer to determine
443-
the four vector.
444-
"""
445-
self.phi = phi
446-
self.s = s
447-
super().__init__()
448-
449-
def receive_match_attributes(self):
450-
(R, P, S, T) = self.match_attributes["game"].RPST()
451-
self.l = R
452-
super().receive_match_attributes(
453-
self.phi, self.s, self.l)
454-
455-
456-
class ZDSet2(LRPlayer):
457-
"""
458-
A Generous Zero Determinant Strategy with l=2.
459-
460-
Names:
461-
462-
- SET2: [Kuhn2017]_
463-
"""
464-
465-
name = 'ZD-SET-2'
466-
467-
def __init__(self, phi: float = 1/4, s: float = 0., l: float = 2) -> None:
468-
"""
469-
Parameters
470-
471-
phi, s: floats
472-
Parameters passed through to LRPlayer to determine
473-
the four vector.
474-
"""
475-
self.phi = phi
476-
self.s = s
477-
self.l = l
478-
super().__init__()
479-
480-
def receive_match_attributes(self):
481-
super().receive_match_attributes(
482-
self.phi, self.s, self.l)
483-
484-
485253
class SoftJoss(MemoryOnePlayer):
486254
"""
487255
Defects with probability 0.9 when the opponent defects, otherwise
@@ -555,6 +323,7 @@ class ReactivePlayer(MemoryOnePlayer):
555323
- Reactive: [Nowak1989]_
556324
"""
557325
name = "Reactive Player"
326+
558327
def __init__(self, probabilities: Tuple[float, float]) -> None:
559328
four_vector = (*probabilities, *probabilities)
560329
super().__init__(four_vector)

axelrod/strategies/titfortat.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,7 @@ def strategy(self, opponent: Player) -> Action:
649649
# Otherwise play previous move
650650
return self.history[-1]
651651

652+
652653
@FinalTransformer((D,), name_prefix=None)
653654
class Alexei(Player):
654655
"""
@@ -677,6 +678,7 @@ def strategy(self, opponent: Player) -> Action:
677678
return D
678679
return C
679680

681+
680682
@FinalTransformer((D,), name_prefix=None)
681683
class EugineNier(Player):
682684
"""
@@ -721,9 +723,9 @@ def reset(self):
721723
class NTitsForMTats(Player):
722724
"""
723725
A parameterizable Tit-for-Tat,
724-
The arguments are :
725-
1) the number of defection before retaliation
726-
2) the number of retaliations
726+
The arguments are:
727+
1) M: the number of defection before retaliation
728+
2) N: the number of retaliations
727729
728730
Names:
729731
@@ -745,9 +747,9 @@ def __init__(self, N: int=3, M: int=2) -> None:
745747
"""
746748
Parameters
747749
----------
748-
N
750+
N: int
749751
Number of retaliations
750-
M
752+
M: int
751753
Number of defection before retaliation
752754
753755
Special Cases
@@ -761,7 +763,7 @@ def __init__(self, N: int=3, M: int=2) -> None:
761763
super().__init__()
762764
self.N = N
763765
self.M = M
764-
self.classifier['memory_depth'] = max([M,N])
766+
self.classifier['memory_depth'] = max([M, N])
765767
self.retaliate_count = 0
766768

767769
def strategy(self, opponent: Player) -> Action:
@@ -772,3 +774,7 @@ def strategy(self, opponent: Player) -> Action:
772774
self.retaliate_count -= 1
773775
return D
774776
return C
777+
778+
def reset(self):
779+
super().reset()
780+
self.retaliate_count = 0

0 commit comments

Comments
 (0)