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

Stein and rapoport #1007

Closed
Closed
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
3 changes: 2 additions & 1 deletion axelrod/strategies/_strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
from .verybad import VeryBad
from .worse_and_worse import (WorseAndWorse, KnowledgeableWorseAndWorse,
WorseAndWorse2, WorseAndWorse3)

from .axelrod_first import SteinAndRapoport
# Note: Meta* strategies are handled in .__init__.py

all_strategies = [
Expand Down Expand Up @@ -228,6 +228,7 @@
SolutionB5,
SpitefulTitForTat,
Stalker,
SteinAndRapoport,
StochasticCooperator,
StochasticWSLS,
SuspiciousTitForTat,
Expand Down
76 changes: 76 additions & 0 deletions axelrod/strategies/axelrod_first.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
Additional strategies from Axelrod's first tournament.
"""

from axelrod.strategy_transformers import FinalTransformer
import random

from axelrod.actions import Actions, flip_action, Action
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 +490,76 @@ 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):
"""
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.
"""

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) -> 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 :
return C

if round_number >= 16 :
# >=16 before for the first 15 round he plays for sure titfortat
times15_in_list = (round_number // 15) * 15
# lets suppose we are in 28th round
# So we still play according to chi-squared test in the 15th round
all_c = 0 # Each time we consider the whole history
all_d = 0
for i in range (0, times15_in_list - 1):
if opponent.history[i] == 'C' :
all_c = all_c + 1
else :
all_d = all_d + 1
if chisquare([all_c, all_d]).pvalue >= self.alpha :
# Defect if opponent plays randomly
return D
else : # TitForTatat if opponent plays not randomly
if opponent.history[-1] == 'D' :
return D
else :
return C
37 changes: 37 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,40 @@ 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, seed=1)

# 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)
101 changes: 92 additions & 9 deletions axelrod/tests/strategies/test_mutual.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,37 @@ class TestDesperate(TestPlayer):
def test_strategy(self):
self.first_play_test(C, seed=1)
self.first_play_test(D, seed=2)
self.responses_test([D], [C] * 4, [D] * 4)
self.responses_test([D], [D, D, C], [C, C, D])
self.responses_test([C], [D, D, D], [C, C, D])

# Our Player (Desperate) vs Cooperator SEED --> 1
opponent = axelrod.Cooperator()
opponent_actions = [C] * 5
actions = [(C, C), (D, C), (D, C), (D, C), (D, C)]
self.versus_test(opponent, expected_actions=actions, seed=1)

# Our Player (Desperate) vs Cooperator SEED --> 2
opponent = axelrod.Cooperator()
actions = [(D, C), (D, C), (D, C), (D, C), (D, C)]
self.versus_test(opponent, expected_actions=actions, seed=2)

# Our Player (Desperate) vs Defector SEED --> 1
opponent = axelrod.Defector()
actions = [(C, D), (D, D), (C, D), (D, D), (C, D)]
self.versus_test(opponent, expected_actions=actions, seed=1)

# Our Player (Desperate) vs Defector SEED --> 2
opponent = axelrod.Defector()
actions = [(D, D), (C, D), (D, D), (C, D), (D, D)]
self.versus_test(opponent, expected_actions=actions, seed=2)

# Our Player (Desperate) vs Alternator SEED --> 1
opponent = axelrod.Alternator()
actions = [(C, C), (D, D), (C, C), (D, D), (C, C)]
self.versus_test(opponent, expected_actions=actions, seed=1)

# Our Player (Desperate) vs Alternator SEED --> 2
opponent = axelrod.Alternator()
actions = [(D, C), (D, D), (C, C), (D, D), (C, C)]
self.versus_test(opponent, expected_actions=actions, seed=2)

class TestHopeless(TestPlayer):

Expand All @@ -44,9 +71,37 @@ class TestHopeless(TestPlayer):
def test_strategy(self):
self.first_play_test(C, seed=1)
self.first_play_test(D, seed=2)
self.responses_test([C], [C] * 4, [D] * 4)
self.responses_test([C], [D] * 5, [C] * 5)
self.responses_test([D], [C, D, C], [C, C, C])

# Our Player (Hopeless) vs Cooperator SEED --> 1
opponent = axelrod.Cooperator()
opponent_actions = [C] * 5
actions = [(C, C), (D, C), (C, C), (D, C), (C, C)]
self.versus_test(opponent, expected_actions=actions, seed=1)

# Our Player (Hopeless) vs Cooperator SEED --> 2
opponent = axelrod.Cooperator()
actions = [(D, C), (C, C), (D, C), (C, C), (D, C)]
self.versus_test(opponent, expected_actions=actions, seed=2)

# Our Player (Hopeless) vs Defector SEED --> 1
opponent = axelrod.Defector()
actions = [(C, D), (C, D), (C, D), (C, D), (C, D)]
self.versus_test(opponent, expected_actions=actions, seed=1)

# Our Player (Hopeless) vs Defector SEED --> 2
opponent = axelrod.Defector()
actions = [(D, D), (C, D), (C, D), (C, D), (C, D)]
self.versus_test(opponent, expected_actions=actions, seed=2)

# Our Player (Hopeless) vs Alternator SEED --> 1
opponent = axelrod.Alternator()
actions = [(C, C), (D, D), (C, C), (D, D), (C, C)]
self.versus_test(opponent, expected_actions=actions, seed=1)

# Our Player (Hopeless) vs Alternator SEED --> 2
opponent = axelrod.Alternator()
actions = [(D, C), (C, D), (C, C), (D, D), (C, C)]
self.versus_test(opponent, expected_actions=actions, seed=2)


class TestWilling(TestPlayer):
Expand All @@ -66,6 +121,34 @@ class TestWilling(TestPlayer):
def test_strategy(self):
self.first_play_test(C, seed=1)
self.first_play_test(D, seed=2)
self.responses_test([C], [C] * 4, [D] * 4)
self.responses_test([C], [D] * 5, [C] * 5)
self.responses_test([D], [C, C, D], [C, C, D])

# Our Player (Willing) vs Cooperator SEED --> 1
opponent = axelrod.Cooperator()
opponent_actions = [C] * 5
actions = [(C, C), (C, C), (C, C), (C, C), (C, C)]
self.versus_test(opponent, expected_actions=actions, seed=1)

# Our Player (Willing) vs Cooperator SEED --> 2
opponent = axelrod.Cooperator()
actions = [(D, C), (C, C), (C, C), (C, C), (C, C)]
self.versus_test(opponent, expected_actions=actions, seed=2)

# Our Player (Willing) vs Defector SEED --> 1
opponent = axelrod.Defector()
actions = [(C, D), (C, D), (C, D), (C, D), (C, D)]
self.versus_test(opponent, expected_actions=actions, seed=1)

# Our Player (Willing) vs Defector SEED --> 2
opponent = axelrod.Defector()
actions = [(D, D), (D, D), (D, D), (D, D), (D, D)]
self.versus_test(opponent, expected_actions=actions, seed=2)

# Our Player (Willing) vs Alternator SEED --> 1
opponent = axelrod.Alternator()
actions = [(C, C), (C, D), (C, C), (C, D), (C, C)]
self.versus_test(opponent, expected_actions=actions, seed=1)

# Our Player (Willing) vs Alternator SEED --> 2
opponent = axelrod.Alternator()
actions = [(D, C), (C, D), (C, C), (C, D), (C, C)]
self.versus_test(opponent, expected_actions=actions, seed=2)