Skip to content
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

Adds a memory two generalization of a zero determinant strategy #1099

Merged
merged 6 commits into from
Jul 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions axelrod/strategies/_strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from .geller import Geller, GellerCooperator, GellerDefector
from .gambler import (
Gambler, PSOGambler1_1_1, PSOGambler2_2_2, PSOGambler2_2_2_Noise05,
PSOGamblerMem1)
PSOGamblerMem1, ZDMem2)
from .gobymajority import (GoByMajority,
GoByMajority10, GoByMajority20, GoByMajority40,
GoByMajority5,
Expand All @@ -50,8 +50,8 @@
from .mathematicalconstants import Golden, Pi, e
from .memoryone import (
MemoryOnePlayer, ALLCorALLD, FirmButFair, GTFT, SoftJoss,
StochasticCooperator, StochasticWSLS, ZDExtort2, ZDExtort2v2, ZDExtort4,
ZDGen2, ZDGTFT2, ZDSet2, WinStayLoseShift, WinShiftLoseStay, ReactivePlayer)
StochasticCooperator, StochasticWSLS, WinStayLoseShift, WinShiftLoseStay,
ReactivePlayer)
from .memorytwo import MEM2
from .mindcontrol import MindController, MindWarper, MindBender
from .mindreader import MindReader, ProtectedMindReader, MirrorMindReader
Expand All @@ -76,13 +76,18 @@
TitForTat, TitFor2Tats, TwoTitsForTat, Bully, SneakyTitForTat,
SuspiciousTitForTat, AntiTitForTat, HardTitForTat, HardTitFor2Tats,
OmegaTFT, Gradual, ContriteTitForTat, AdaptiveTitForTat,
SpitefulTitForTat, SlowTitForTwoTats2, Alexei, EugineNier, DynamicTwoTitsForTat, NTitsForMTats)
SpitefulTitForTat, SlowTitForTwoTats2, Alexei, EugineNier,
DynamicTwoTitsForTat, NTitsForMTats)
from .verybad import VeryBad
from .worse_and_worse import (WorseAndWorse, KnowledgeableWorseAndWorse,
WorseAndWorse2, WorseAndWorse3)
from .zero_determinant import (
ZDExtortion, ZDExtort2, ZDExtort3, ZDExtort2v2, ZDExtort4, ZDGen2, ZDGTFT2,
ZDMischief, ZDSet2)

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


all_strategies = [
Adaptive,
AdaptiveTitForTat,
Expand Down Expand Up @@ -259,11 +264,15 @@
WorseAndWorse,
WorseAndWorse2,
WorseAndWorse3,
ZDExtortion,
ZDExtort2,
ZDExtort3,
ZDExtort2v2,
ZDExtort4,
ZDGTFT2,
ZDGen2,
ZDMem2,
ZDMischief,
ZDSet2,
e,
DynamicTwoTitsForTat,
Expand Down
33 changes: 33 additions & 0 deletions axelrod/strategies/gambler.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,36 @@ def __init__(self) -> None:
parameters = Plays(self_plays=2, op_plays=2, op_openings=2)

super().__init__(parameters=parameters, pattern=pattern)


class ZDMem2(Gambler):
"""
A memory two generalization of a zero determinant player.

Names:

- ZDMem2: Original name by Marc Harper
- Unnamed [LiS2014]_

"""

name = "ZD-Mem2"

classifier = {
'memory_depth': 2,
'stochastic': True,
'makes_use_of': set(),
'long_run_time': False,
'inspects_source': False,
'manipulates_source': False,
'manipulates_state': False
}

def __init__(self) -> None:
pattern = [11 / 12, 4 / 11, 7 / 9, 1 / 10,
5 / 6, 3 / 11, 7 / 9, 1 / 10,
2 / 3, 1 / 11, 7 / 9, 1 / 10,
3 / 4, 2 / 11, 7 / 9, 1 / 10]
parameters = Plays(self_plays=2, op_plays=2, op_openings=0)

super().__init__(parameters=parameters, pattern=pattern)
3 changes: 1 addition & 2 deletions axelrod/strategies/lookerup.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,7 @@ def make_keys_into_plays(lookup_table: dict) -> dict:
return new_table


def create_lookup_table_keys(player_depth: int,
op_depth: int,
def create_lookup_table_keys(player_depth: int, op_depth: int,
op_openings_depth: int) -> list:
"""Returns a list of Plays that has all possible permutations of C's and
D's for each specified depth. the list is in order,
Expand Down
251 changes: 10 additions & 241 deletions axelrod/strategies/memoryone.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
"""Memory One strategies. Note that there are Memory One strategies in other
files, including titfortat.py and zero_determinant.py"""

from axelrod.action import Action
from axelrod.player import Player
from axelrod.random_ import random_choice
Expand Down Expand Up @@ -33,7 +36,8 @@ class MemoryOnePlayer(Player):
'manipulates_state': False
}

def __init__(self, four_vector: type_four_vector = None, initial: Action = C) -> None:
def __init__(self, four_vector: type_four_vector = None,
initial: Action = C) -> None:
"""
Parameters

Expand Down Expand Up @@ -201,10 +205,10 @@ def __init__(self) -> None:
class StochasticCooperator(MemoryOnePlayer):
"""Stochastic Cooperator.

Names:
Names:

- Stochastic Cooperator: [Adami2013]_
"""
- Stochastic Cooperator: [Adami2013]_
"""

name = 'Stochastic Cooperator'

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

self.ep = ep
four_vector = (1.-ep, ep, ep, 1.-ep)
four_vector = (1. - ep, ep, ep, 1. - ep)
super().__init__(four_vector)
self.set_four_vector(four_vector)


class LRPlayer(MemoryOnePlayer):
"""Abstraction for Linear Relation players. These players enforce a linear
difference in stationary payoffs s * (S_xy - l) = S_yx - l, with 0 <= l <= R.
The parameter `s` is called the slope and the parameter `l` the
baseline payoff. For extortionate strategies, the extortion factor is the
inverse of the slope.

This parameterization is Equation 14 in
http://journals.plos.org/plosone/article?id=10.1371/journal.pone.0077886.
See Figure 2 of the article for a more in-depth explanation.

Names:

- Linear Relation player: [Hilbe2013]_
"""

name = 'LinearRelation'
classifier = {
'memory_depth': 1, # Memory-one Four-Vector
'stochastic': True,
'makes_use_of': set(["game"]),
'long_run_time': False,
'inspects_source': False,
'manipulates_source': False,
'manipulates_state': False
}


def receive_match_attributes(self, phi: float = 0, s: float = None, l: float = None):
"""
Parameters

phi, s, l: floats
Parameter used to compute the four-vector according to the
parameterization of the strategies below.
"""

(R, P, S, T) = self.match_attributes["game"].RPST()
if s is None:
s = 1
if l is None:
l = R

# Check parameters
s_min = - min((T-l) / (l-S), (l-S) / (T-l))
if (l < P) or (l > R) or (s > 1) or (s < s_min):
raise ValueError

p1 = 1 - phi * (1 - s) * (R - l)
p2 = 1 - phi * (s * (l - S) + (T - l))
p3 = phi * ((l - S) + s * (T - l))
p4 = phi * (1 - s) * (l - P)

four_vector = [p1, p2, p3, p4]
self.set_four_vector(four_vector)


class ZDExtort2(LRPlayer):
"""
An Extortionate Zero Determinant Strategy with l=P.

Names:

- Extort-2: [Stewart2012]_
"""

name = 'ZD-Extort-2'

def __init__(self, phi: float = 1/9, s: float = 0.5) -> None:
"""
Parameters

phi, s: floats
Parameters passed through to LRPlayer to determine
the four vector.
"""
self.phi = phi
self.s = s
super().__init__()

def receive_match_attributes(self):
(R, P, S, T) = self.match_attributes["game"].RPST()
self.l = P
super().receive_match_attributes(
self.phi, self.s, self.l)


class ZDExtort2v2(LRPlayer):
"""
An Extortionate Zero Determinant Strategy with l=1.


Names:

- EXTORT2: [Kuhn2017]_
"""

name = 'ZD-Extort-2 v2'

def __init__(self, phi: float = 1/8, s: float = 0.5, l: float = 1) -> None:
"""
Parameters

phi, s: floats
Parameters passed through to LRPlayer to determine
the four vector.
"""
self.phi = phi
self.s = s
self.l = l
super().__init__()

def receive_match_attributes(self):
super().receive_match_attributes(
self.phi, self.s, self.l)


class ZDExtort4(LRPlayer):
"""
An Extortionate Zero Determinant Strategy with l=1, s=1/4. TFT is the
other extreme (with l=3, s=1)


Names:

- Extort 4: Original name by Marc Harper
"""

name = 'ZD-Extort-4'

def __init__(self, phi: float = 4/17, s: float = 0.25, l: float = 1) -> None:
"""
Parameters

phi, s: floats
Parameters passed through to LRPlayer to determine
the four vector.
"""
self.phi = phi
self.s = s
self.l = l
super().__init__()

def receive_match_attributes(self):
super().receive_match_attributes(
self.phi, self.s, self.l)


class ZDGen2(LRPlayer):
"""
A Generous Zero Determinant Strategy with l=3.

Names:

- GEN2: [Kuhn2017]_
"""

name = 'ZD-GEN-2'

def __init__(self, phi: float = 1/8, s: float = 0.5, l: float = 3) -> None:
"""
Parameters

phi, s: floats
Parameters passed through to LRPlayer to determine
the four vector.
"""
self.phi = phi
self.s = s
self.l = l
super().__init__()

def receive_match_attributes(self):
super().receive_match_attributes(
self.phi, self.s, self.l)


class ZDGTFT2(LRPlayer):
"""
A Generous Zero Determinant Strategy with l=R.

Names:

- ZDGTFT-2: [Stewart2012]_
"""

name = 'ZD-GTFT-2'

def __init__(self, phi: float = 0.25, s: float = 0.5) -> None:
"""
Parameters

phi, s: floats
Parameters passed through to LRPlayer to determine
the four vector.
"""
self.phi = phi
self.s = s
super().__init__()

def receive_match_attributes(self):
(R, P, S, T) = self.match_attributes["game"].RPST()
self.l = R
super().receive_match_attributes(
self.phi, self.s, self.l)


class ZDSet2(LRPlayer):
"""
A Generous Zero Determinant Strategy with l=2.

Names:

- SET2: [Kuhn2017]_
"""

name = 'ZD-SET-2'

def __init__(self, phi: float = 1/4, s: float = 0., l: float = 2) -> None:
"""
Parameters

phi, s: floats
Parameters passed through to LRPlayer to determine
the four vector.
"""
self.phi = phi
self.s = s
self.l = l
super().__init__()

def receive_match_attributes(self):
super().receive_match_attributes(
self.phi, self.s, self.l)


class SoftJoss(MemoryOnePlayer):
"""
Defects with probability 0.9 when the opponent defects, otherwise
Expand Down Expand Up @@ -555,6 +323,7 @@ class ReactivePlayer(MemoryOnePlayer):
- Reactive: [Nowak1989]_
"""
name = "Reactive Player"

def __init__(self, probabilities: Tuple[float, float]) -> None:
four_vector = (*probabilities, *probabilities)
super().__init__(four_vector)
Expand Down
Loading