Skip to content

Commit

Permalink
original PR state. will fix according to suggestions on Axelrod-Pytho…
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-s-s committed Apr 26, 2017
1 parent b2953c8 commit 96d9880
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 51 deletions.
15 changes: 8 additions & 7 deletions axelrod/strategies/gobymajority.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from axelrod.actions import Actions, Action
from axelrod.player import Player

from typing import Dict, Any
from typing import Dict, Any, Union

import copy

Expand Down Expand Up @@ -30,23 +30,24 @@ class GoByMajority(Player):
'manipulates_source': False,
'manipulates_state': False,
'memory_depth': float('inf')
} # type: Dict[str, Any]
} # type: Dict[str, Any]

def __init__(self, memory_depth: int = float('inf'), soft: bool = True) -> None:
def __init__(self, memory_depth: Union[int, float] = float('inf'),
soft: bool = True) -> None:
"""
Parameters
----------
memory_depth, int >= 0
memory_depth: int >= 0
The number of rounds to use for the calculation of the cooperation
and defection probabilities of the opponent.
soft, bool
soft: bool
Indicates whether to cooperate or not in the case that the
cooperation and defection probabilities are equal.
"""

super().__init__()
self.soft = soft
self.classifier['memory_depth'] = memory_depth
self.classifier['memory_depth'] = memory_depth
if self.classifier['memory_depth'] < float('inf'):
self.memory = self.classifier['memory_depth']
else:
Expand Down Expand Up @@ -140,7 +141,7 @@ class HardGoByMajority(GoByMajority):
"""
name = 'Hard Go By Majority'

def __init__(self, memory_depth: int = float('inf')) -> None:
def __init__(self, memory_depth: Union[int, float] = float('inf')) -> None:
super().__init__(memory_depth=memory_depth, soft=False)


Expand Down
121 changes: 77 additions & 44 deletions axelrod/tests/strategies/test_gobymajority.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import axelrod
from .test_player import TestPlayer
from axelrod import MockPlayer

C, D = axelrod.Actions.C, axelrod.Actions.D

Expand All @@ -10,8 +11,8 @@ class TestHardGoByMajority(TestPlayer):

name = "Hard Go By Majority"
player = axelrod.HardGoByMajority
default_soft = False
eq_play = D
soft = False

expected_classifier = {
'stochastic': False,
Expand All @@ -24,40 +25,55 @@ class TestHardGoByMajority(TestPlayer):
}

def test_strategy(self):
# Starts by defecting.
self.first_play_test(self.eq_play)
# If opponent cooperates at least as often as they defect then the
# player defects.
self.responses_test([self.eq_play], [C, D, D, D], [D, D, C, C])
# If opponent defects strictly more often than they defect then the
# player defects.
self.responses_test([D], [C, C, D, D, C], [D, D, C, C, D])
# If opponent cooperates strictly more often than they defect then the
# player cooperates.
self.responses_test([C], [C, C, D, D, C], [D, C, C, C, D])

def test_default_soft(self):

expected, opponent_actions = self.get_infinite_memory_depth_actions()
self.versus_test(MockPlayer(actions=opponent_actions),
expected_actions=expected)

def get_infinite_memory_depth_actions(self):
opponent_actions = [C, D, D]
first_three = [(self.eq_play, C), (C, D), (self.eq_play, D)]
second_three = [(D, C), (self.eq_play, D), (D, D)]
subsequent = [(D, C), (D, D), (D, D)]
expected = first_three + second_three + subsequent * 10
return expected, opponent_actions

def test_memory_depth(self):
memory_depth = 4
opponent_actions = [C, C, C, D, D, D]
first_six = [(self.eq_play, C), (C, C), (C, C),
(C, D), (C, D), (self.eq_play, D)]
subsequent = [(D, C), (D, C), (self.eq_play, C),
(C, D), (C, D), (self.eq_play, D)]

expected = first_six + subsequent * 10
self.versus_test(MockPlayer(actions=opponent_actions),
expected_actions=expected,
init_kwargs={'memory_depth': memory_depth})

def test_soft_value(self):
player = self.player()
self.assertEqual(player.soft, self.default_soft)
self.assertFalse(player.soft)


class TestGoByMajority(TestHardGoByMajority):

name = "Soft Go By Majority"
player = axelrod.GoByMajority
default_soft = True
eq_play = C

def test_strategy(self):
# In case of equality (including first play), cooperates.
super().test_strategy()

# Test tie break rule for soft=False
player = self.player(soft=False)
opponent = axelrod.Cooperator()
self.assertEqual('D', player.strategy(opponent))

def test_soft(self):
soft = True

def test_set_soft_to_false(self):
self.eq_play = D
expected, opponent_actions = self.get_infinite_memory_depth_actions()
self.versus_test(MockPlayer(actions=opponent_actions),
expected_actions=expected, init_kwargs={'soft': False})
self.eq_play = C

def test_soft_value(self):
default = self.player()
self.assertTrue(default.soft)
player = self.player(soft=True)
self.assertTrue(player.soft)
player = self.player(soft=False)
Expand All @@ -68,17 +84,22 @@ def test_name(self):
self.assertEqual(player.name, "Soft Go By Majority")
player = self.player(soft=False)
self.assertEqual(player.name, "Hard Go By Majority")
player = self.player(memory_depth=5)
self.assertEqual(player.name, "Soft Go By Majority: 5")

def test_repr(self):
def test_str(self):
player = self.player(soft=True)
name = str(player)
self.assertEqual(name, "Soft Go By Majority")
player = self.player(soft=False)
name = str(player)
self.assertEqual(name, "Hard Go By Majority")
player = self.player(memory_depth=5)
name = str(player)
self.assertEqual(name, "Soft Go By Majority: 5")


def factory_TestGoByRecentMajority(L, soft=True):
def factory_TestGoByRecentMajority(memory_depth, soft=True):

prefix = "Hard"
prefix2 = "Hard"
Expand All @@ -88,12 +109,13 @@ def factory_TestGoByRecentMajority(L, soft=True):

class TestGoByRecentMajority(TestPlayer):

name = "{} Go By Majority: {}".format(prefix, L)
player = getattr(axelrod, "{}GoByMajority{}".format(prefix2, L))
name = "{} Go By Majority: {}".format(prefix, memory_depth)
player = getattr(axelrod, "{}GoByMajority{}".format(prefix2,
memory_depth))

expected_classifier = {
'stochastic': False,
'memory_depth': L,
'memory_depth': memory_depth,
'makes_use_of': set(),
'long_run_time': False,
'inspects_source': False,
Expand All @@ -102,27 +124,38 @@ class TestGoByRecentMajority(TestPlayer):
}

def test_strategy(self):
# Test initial play.
"""
with memory_depth=3 always switches after
opponent_history=[C, C, C, D, D] (int(3*1.5) + 1 = 5)
with memory_depth=4 soft switches after
op_history=[C, C, C, C, D, D, D] (int(4*1.5) + 1 = 7)
and hard switches after
op_history=[C, C, C, C, D, D] (int(4 * 1.5) = 6)
"""

if soft:
self.first_play_test(C)
else:
self.first_play_test(D)

self.responses_test([C], [C] * L,
[C] * (L // 2 + 1) + [D] * (L // 2 - 1))
self.responses_test([D], [C] * L,
[D] * (L // 2 + 1) + [C] * (L // 2 - 1))
opponent_actions = [C] * memory_depth + [D] * memory_depth

if memory_depth % 2 == 1 or soft:
cooperation_len = int(memory_depth * 1.5) + 1
else:
cooperation_len = int(memory_depth * 1.5)
defect_len = 2 * memory_depth - cooperation_len

# Test 50:50 play difference with soft
k = L
if L % 2 == 1:
k -= 1
if soft:
self.responses_test([C], [C] * k,
[C] * (k // 2) + [D] * (k // 2))
first_move = [C]
else:
self.responses_test([D], [C] * k,
[C] * (k // 2) + [D] * (k // 2))
first_move = [D]

player_actions = (first_move + [C] * (cooperation_len - 1) +
[D] * defect_len)
expected = list(zip(player_actions, opponent_actions))
self.versus_test(MockPlayer(actions=opponent_actions),
expected_actions=expected)

return TestGoByRecentMajority

Expand Down

0 comments on commit 96d9880

Please sign in to comment.