Skip to content

SteinAndRapoport Strategy #1012

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

Merged
merged 7 commits into from
May 22, 2017
Merged
Show file tree
Hide file tree
Changes from 2 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
3 changes: 2 additions & 1 deletion axelrod/strategies/_strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from .averagecopier import AverageCopier, NiceAverageCopier
from .axelrod_first import (
Davis, RevisedDowning, Feld, Grofman, Nydegger, Joss, Shubik, Tullock,
UnnamedStrategy)
UnnamedStrategy, SteinAndRapoport)
from .axelrod_second import Champion, Eatherley, Tester
from .backstabber import BackStabber, DoubleCrosser
from .better_and_better import BetterAndBetter
Expand Down Expand Up @@ -232,6 +232,7 @@
SolutionB5,
SpitefulTitForTat,
Stalker,
SteinAndRapoport,
StochasticCooperator,
StochasticWSLS,
SuspiciousTitForTat,
Expand Down
70 changes: 70 additions & 0 deletions axelrod/strategies/axelrod_first.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from axelrod.player import Player
from axelrod.random_ import random_choice
from.memoryone import MemoryOnePlayer
from axelrod.strategy_transformers import FinalTransformer
from scipy.stats import chisquare

from typing import List, Dict, Tuple

Expand Down Expand Up @@ -487,3 +489,71 @@ class UnnamedStrategy(Player):
def strategy(opponent: Player) -> Action:
r = random.uniform(3, 7) / 10
return random_choice(r)

@FinalTransformer((D, D), name_prefix=None)
class SteinAndRapoport(Player):
"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not indented on the correct level. It should look like:

class SteinAndRapoport(Player):
    ```
    A player who plays...
    ...
    ```

A player who plays according to statistic methods.
Begins by playing C for the first four (4) rounds , then it plays
tit for tat and at the last 2 round it Defects. Every 15 turns it
run a chi-squared test to check whether the opponent behaves randomly
or not . In case the opponent behaves randomly then Stein_and_Rapoport
Defects untill the next 15 round (where we check again), otherwise he
still plays TitForTat.

Names:
- SteinAndRapoport [Axelrod1980]_
"""

name = 'Stein and Rapoport'
classifier = {
'memory_depth': 15,
'stochastic': False,
'makes_use_of': set(),
'long_run_time': False,
'inspects_source': False,
'manipulates_source': False,
'manipulates_state': False
}

def __init__(self, alpha: float=0.05) -> None:
"""
Parameters
----------
alpha, float
The significant level of pvalue from chi-squared test
0.05 by default according to literature
"""
super().__init__()
self.alpha = alpha
if (self.alpha > 1) or (self.alpha < 0):
self.alpha = 0.05

def strategy(self , opponent: Player , chi_tests = [0]) -> Action:
round_number = len(self.history) + 1

# First 4 moves
if round_number < 5:
return C

# For first 15 rounds tit for tat as we dont know opponents strategy
if round_number < 16:
if opponent.history[-1] == 'D':
return D
else :
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else : should be else:

return C

if len(self.history) % 15 == 0:
if chisquare([opponent.cooperations, opponent.defections]).pvalue >= self.alpha:
chi_tests.append(1)
else:
chi_tests.append(0)

if chi_tests[-1] == 1:
# Defect if opponent plays randomly
return D
else : # TitForTatat if opponent plays not randomly
if opponent.history[-1] == 'D':
return D
else:
return C
38 changes: 38 additions & 0 deletions axelrod/tests/strategies/test_axelrod_first.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,3 +387,41 @@ def test_strategy(self):
actions = [(C, C), (C, C), (D, C), (C, C), (C, C), (D, C)]
self.versus_test(axelrod.Cooperator(), expected_actions=actions,
seed=10)


class SteinAndRapoport(TestPlayer):

name = "SteinAndRapoport"
player = axelrod.SteinAndRapoport
expected_classifier = {
'memory_depth': 15,
'long_run_time': False,
'stochastic': False,
'makes_use_of': set(),
'inspects_source': False,
'manipulates_source': False,
'manipulates_state': False
}

def test_strategy(self):
self.first_play_test(C)

# Our Player (SteinAndRapoport) vs Cooperator
# After 15th round (pvalue < alpha) still plays titfortat
opponent = axelrod.Cooperator()
actions = [(C, C)] * 17 + [(D, C)] * 2
self.versus_test(opponent, expected_actions=actions)

# Our Player (SteinAndRapoport) vs Defector
# After 15th round (pvalue < alpha) still plays titfortat
opponent = axelrod.Cooperator()
actions = [(C, D)] * 4 + [(D, D)] * 15
self.versus_test(opponent, expected_actions=actions)

# Our Player (SteinAndRapoport) vs Alternator
# After 15th round (pvalue > alpha) starts defect
opponent = axelrod.Alternator()
actions = [(C, C), (C, D), (C, C), (C, D), (D, C), (C, D), (D, C),
(C, D), (D, C), (C, D), (D, C), (C, D),(D, C), (C, D),
(D, C), (D, D), (D, C), (D, D), (D, C)]
self.versus_test(opponent, expected_actions=actions)
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ matplotlib>=1.4.2
hypothesis>=3.2
tqdm>=3.4.0
prompt-toolkit>=1.0.7
scipy>=0.19.0