Skip to content

Add a versus_test method to TestPlayer #875

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 32 commits into from
Mar 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
84f44f7
Rewrite test for TitForTat.
drvinceknight Mar 4, 2017
5deddbc
Write a versus_test method in TestPlayer.
drvinceknight Mar 5, 2017
b22c0a2
Make Mock player cycle.
drvinceknight Mar 5, 2017
8d0b809
Test for tit for tat.
drvinceknight Mar 5, 2017
48ec039
Reword the documentation.
drvinceknight Mar 5, 2017
8070070
Add variable names to method calls.
drvinceknight Mar 5, 2017
ac4164f
Remove option to versus test with a sequence.
drvinceknight Mar 6, 2017
4747071
Refactor tests for Random.
drvinceknight Mar 6, 2017
c29820f
Rename test resets.
drvinceknight Mar 6, 2017
0d9ba49
Remove option to use init_args.
drvinceknight Mar 6, 2017
8746199
Address comments about tests.
drvinceknight Mar 7, 2017
4ec9fb2
Fix bug in base reset case.
drvinceknight Mar 7, 2017
cfd5ded
Fix test test for sequence player.
drvinceknight Mar 7, 2017
eb5db4b
Fix q learners.
drvinceknight Mar 7, 2017
78cde50
Fix punisher.
drvinceknight Mar 7, 2017
54f9cd3
Fix appeaser.
drvinceknight Mar 7, 2017
74228d7
Fix Revised Downing.
drvinceknight Mar 7, 2017
08f8959
Fix adaptive pavlov.
drvinceknight Mar 7, 2017
c55374a
Fix test for calculator + implemented player eq
drvinceknight Mar 7, 2017
dcb21d5
Fix hmm.
drvinceknight Mar 7, 2017
eeb58f3
Fix fsm player.
drvinceknight Mar 7, 2017
aae3665
Correct test for hmm and fsm eq.
drvinceknight Mar 7, 2017
87e7781
Fix type check in reset test.
drvinceknight Mar 7, 2017
db5637e
Add specific test for meta players.
drvinceknight Mar 7, 2017
72fb241
Rename extra test for grumpy.
drvinceknight Mar 7, 2017
2f342b9
Revert "Fix test for calculator + implemented player eq"
drvinceknight Mar 7, 2017
1a6eacc
Refactor out a sub method in test player.
drvinceknight Mar 7, 2017
83d05dc
Correct failing test.
drvinceknight Mar 7, 2017
e2ccc13
Correct classification of Stalker.
drvinceknight Mar 7, 2017
988d288
Substitute: expected_outcomes -> expected_actions
drvinceknight Mar 8, 2017
bc398f2
Remove versus_test + 1st_play intft, rand and docs
drvinceknight Mar 9, 2017
3d81683
Revert "Remove versus_test + 1st_play intft, rand and docs"
drvinceknight Mar 9, 2017
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
7 changes: 4 additions & 3 deletions axelrod/mock_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from axelrod.actions import Actions, Action
from axelrod.player import Player, update_history, update_state_distribution
from collections import defaultdict
from itertools import cycle

from typing import List, Tuple

Expand All @@ -28,16 +29,16 @@ def __init__(self, actions: List[Action] =None, history: List[Action] =None, sta
if state_dist:
self.state_distribution = dict(state_dist)
if actions:
self.actions = list(actions)
self.actions = cycle(actions)
else:
self.actions = []

def strategy(self, opponent: Player) -> Action:
# Return the next saved action, if present.
try:
action = self.actions.pop(0)
action = self.actions.__next__()
return action
except IndexError:
except AttributeError:
return C


Expand Down
4 changes: 2 additions & 2 deletions axelrod/strategies/apavlov.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class APavlov2006(Player):

def __init__(self) -> None:
super().__init__()
self.opponent_class = ""
self.opponent_class = None

def strategy(self, opponent: Player) -> Action:
# TFT for six rounds
Expand Down Expand Up @@ -96,7 +96,7 @@ class APavlov2011(Player):

def __init__(self) -> None:
super().__init__()
self.opponent_class = ""
self.opponent_class = None

def strategy(self, opponent: Player) -> Action:
# TFT for six rounds
Expand Down
10 changes: 5 additions & 5 deletions axelrod/strategies/appeaser.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ class Appeaser(Player):

def strategy(self, opponent: Player) -> Action:
if not len(opponent.history):
self.move = C
return C
else:
if opponent.history[-1] == D:
if self.move == C:
self.move = D
if self.history[-1] == C:
return D
else:
self.move = C
return self.move
return C
return self.history[-1]
14 changes: 6 additions & 8 deletions axelrod/strategies/axelrod_first.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,10 @@ def strategy(self, opponent: Player) -> Action:

if self.revised:
if round_number == 1:
self.move = C
return self.move
return C
elif not self.revised:
if round_number <= 2:
self.move = D
return self.move
return D

# Update various counts
if round_number > 2:
Expand All @@ -121,12 +119,12 @@ def strategy(self, opponent: Player) -> Action:
c = 6.0 * self.good - 8.0 * self.bad - 2
alt = 4.0 * self.good - 5.0 * self.bad - 1
if (c >= 0 and c >= alt):
self.move = C
move = C
elif (c >= 0 and c < alt) or (alt >= 0):
self.move = flip_action(self.move)
move = flip_action(self.history[-1])
else:
self.move = D
return self.move
move = D
return move

def reset(self):
super().reset()
Expand Down
9 changes: 9 additions & 0 deletions axelrod/strategies/finite_state_machines.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ def move(self, opponent_action):
self.state = next_state
return next_action

def __eq__(self, other):
"""Equality of two FSMs"""
check = True
for attr in ["state", "state_transitions"]:
check = check and getattr(self, attr) == getattr(other, attr)
return check


class FSMPlayer(Player):
"""Abstract base class for finite state machine players."""
Expand All @@ -57,6 +64,7 @@ def __init__(self, transitions=None, initial_state=None,
initial_action = C
super().__init__()
self.initial_state = initial_state
self.state = initial_state
Copy link
Member

Choose a reason for hiding this comment

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

What's the purpose of this line?

Copy link
Member Author

Choose a reason for hiding this comment

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

Needed for the reset test. The cloned player did not have a self.state attribute if it had not played yet.

self.initial_action = initial_action
self.fsm = SimpleFSM(transitions, initial_state)

Expand All @@ -73,6 +81,7 @@ def strategy(self, opponent):
def reset(self):
super().reset()
self.fsm.state = self.initial_state
self.state = self.initial_state


class Fortress3(FSMPlayer):
Expand Down
11 changes: 11 additions & 0 deletions axelrod/strategies/hmm.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ def is_well_formed(self):
return False
return True

def __eq__(self, other):
"""Equality of two HMMs"""
check = True
for attr in ["transitions_C", "transitions_D",
"emission_probabilities", "state"]:
check = check and getattr(self, attr) == getattr(other, attr)
return check


def move(self, opponent_action):
"""Changes state and computes the response action.

Expand Down Expand Up @@ -114,6 +123,7 @@ def __init__(self, transitions_C=None, transitions_D=None,
self.hmm = SimpleHMM(transitions_C, transitions_D,
emission_probabilities, initial_state)
assert self.hmm.is_well_formed()
self.state = self.hmm.state
self.classifier['stochastic'] = self.is_stochastic()

def is_stochastic(self):
Expand Down Expand Up @@ -141,6 +151,7 @@ def strategy(self, opponent):
def reset(self):
super().reset()
self.hmm.state = self.initial_state
self.state = self.hmm.state


class EvolvedHMM5(HMMPlayer):
Expand Down
10 changes: 5 additions & 5 deletions axelrod/strategies/punisher.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def reset(self):
"""
super().reset()
self.grudged = False
self.grudge_memory = 0
self.grudge_memory = 1
self.mem_length = 1


Expand Down Expand Up @@ -122,15 +122,15 @@ def reset(self):
"""Resets internal variables and history"""
super().reset()
self.grudged = False
self.grudge_memory = 0
self.grudge_memory = 1
self.mem_length = 1

class LevelPunisher(Player):
"""
A player starts by cooperating however, after 10 rounds
will defect if at any point the number of defections
A player starts by cooperating however, after 10 rounds
will defect if at any point the number of defections
by an opponent is greater than 20%.

Names:

- Level Punisher: Name from CoopSim https://github.com/jecki/CoopSim
Expand Down
3 changes: 2 additions & 1 deletion axelrod/strategies/qlearner.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def __init__(self) -> None:
self.classifier['stochastic'] = True

self.prev_action = random_choice()
self.original_prev_action = self.prev_action
self.history = [] # type: List[Action]
self.score = 0
self.Qs = OrderedDict({'': OrderedDict(zip([C, D], [0, 0]))})
Expand Down Expand Up @@ -117,7 +118,7 @@ def reset(self):
self.Qs = {'': {C: 0, D: 0}}
self.Vs = {'': 0}
self.prev_state = ''
self.prev_action = random_choice()
self.prev_action = self.original_prev_action


class ArrogantQLearner(RiskyQLearner):
Expand Down
4 changes: 2 additions & 2 deletions axelrod/strategies/stalker.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class Stalker(Player):
classifier = {
'memory_depth': float('inf'),
'stochastic': True,
'makes_use_of': set(),
'makes_use_of': set(["game", "length"]),
'long_run_time': False,
'inspects_source': False,
'manipulates_source': False,
Expand All @@ -46,7 +46,7 @@ def __init__(self) -> None:
R, P, S, T = self.match_attributes["game"].RPST()
self.very_good_score = R
self.very_bad_score = P
self.wish_score = ( R + P ) / 2
self.wish_score = (R + P) / 2
self.current_score = 0

def score_last_round(self, opponent: Player):
Expand Down
8 changes: 4 additions & 4 deletions axelrod/strategies/titfortat.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ def strategy(self, opponent: Player) -> Action:

# Are we deadlocked? (in a CD -> DC loop)
if (self.deadlock_counter >= self.deadlock_threshold):
self.move = C
move = C
if self.deadlock_counter == self.deadlock_threshold:
self.deadlock_counter = self.deadlock_threshold + 1
else:
Expand All @@ -323,16 +323,16 @@ def strategy(self, opponent: Player) -> Action:
# Compare counts to thresholds
# If randomness_counter exceeds Y, Defect for the remainder
if self.randomness_counter >= 8:
self.move = D
move = D
else:
# TFT
self.move = D if opponent.history[-1:] == [D] else C
move = D if opponent.history[-1:] == [D] else C
# Check for deadlock
if opponent.history[-2] != opponent.history[-1]:
self.deadlock_counter += 1
else:
self.deadlock_counter = 0
return self.move
return move

def reset(self):
super().reset()
Expand Down
4 changes: 4 additions & 0 deletions axelrod/tests/unit/test_calculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,7 @@ def test_strategy(self):
D, C]
self.responses_test([C], [C] * 22, history)

def attribute_equality_test(self, player, clone):
"""Overwrite the default test to check Joss instance"""
self.assertIsInstance(player.joss_instance, axelrod.Joss)
self.assertIsInstance(clone.joss_instance, axelrod.Joss)
2 changes: 1 addition & 1 deletion axelrod/tests/unit/test_grumpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def test_strategy(self):
init_kwargs={"grumpy_threshold": 3,
"nice_threshold": 0})

def test_reset(self):
def test_reset_state_with_non_default_init(self):
P1 = axelrod.Grumpy(starting_state='Grumpy')
P1.state = 'Nice'
P1.reset()
Expand Down
4 changes: 4 additions & 0 deletions axelrod/tests/unit/test_human.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,7 @@ def test_strategy(self):
expected_action = C
actual_action = human.strategy(Player(), lambda: C)
self.assertEqual(actual_action, expected_action)

def test_reset_history_and_attributes(self):
"""Overwrite the reset method for this strategy."""
pass
13 changes: 13 additions & 0 deletions axelrod/tests/unit/test_memorytwo.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,16 @@ def test_strategy(self):
# ALLD forever if all D twice
self.responses_test([D] * 10, [C, D, D, D, D, D], [D, D, D, D, D, D])
self.responses_test([D] * 9, [C] + [D] * 5 + [C] * 4, [D] * 6 + [C] * 4)

def attribute_equality_test(self, player, clone):
"""Overwrite specific test to be able to test self.players"""
for p in [player, clone]:
self.assertEqual(p.play_as, "TFT")
self.assertEqual(p.shift_counter, 3)
self.assertEqual(p.alld_counter, 0)

for key, value in [("TFT", axelrod.TitForTat),
("TFTT", axelrod.TitFor2Tats),
("ALLD", axelrod.Defector)]:
self.assertEqual(p.players[key].history, [])
self.assertIsInstance(p.players[key], value)
21 changes: 8 additions & 13 deletions axelrod/tests/unit/test_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,15 @@ def classifier_test(self, expected_class_classifier=None):
msg="%s - Behaviour: %s != Expected Behaviour: %s" %
(key, player.classifier[key], classifier[key]))

def test_reset(self):
p1 = self.player()
p2 = axelrod.Cooperator()
p1.play(p2)
p1.play(p2)
p1.play(p2)
p1.reset()
for player in p1.team:
self.assertEqual(len(player.history), 0)
def attribute_equality_test(self, player, clone):
"""Overwriting this specific method to check team."""
for p1, p2 in zip(player.team, clone.team):
self.assertEqual(len(p1.history), 0)
self.assertEqual(len(p2.history), 0)

team_player_names = [p.__repr__() for p in player.team]
team_clone_names = [p.__repr__() for p in clone.team]
self.assertEqual(team_player_names, team_clone_names)

class TestMetaMajority(TestMetaPlayer):

Expand Down Expand Up @@ -222,8 +221,6 @@ def test_strategy(self):
self.responses_test([D], [C] * 4, [D] * 4)
self.responses_test([D], [C] * 6, [C, D] * 3)
self.responses_test([D], [C] * 8, [C, C, C, D, C, C, C, D])
self.responses_test([D], [C] * 100,
[random.choice([C, D]) for i in range(100)])
# Test post 100 rounds responses
self.responses_test([C], [C] * 101, [C] * 101)
self.responses_test([D], [C] * 101, [C] * 100 + [D])
Expand Down Expand Up @@ -257,8 +254,6 @@ def test_strategy(self):
self.responses_test([D], [C] * 4, [D] * 4)
self.responses_test([D], [C] * 6, [C, D] * 3)
self.responses_test([D], [C] * 8, [C, C, C, D, C, C, C, D])
self.responses_test([D], [C] * 100,
[random.choice([C, D]) for i in range(100)])
# Test post 100 rounds responses
self.responses_test([D], [C] * 101, [C] * 101)
self.responses_test([D], [C] * 101, [C] * 100 + [D])
Expand Down
5 changes: 3 additions & 2 deletions axelrod/tests/unit/test_mock_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ def test_strategy(self):
def test_history(self):
t = TestOpponent()
m1 = MockPlayer([C], history=[C]*10)
self.assertEqual(m1.actions[0], C)
self.assertEqual(m1.actions.__next__(), C)
self.assertEqual(m1.history, [C] * 10)
self.assertEqual(m1.cooperations, 10)
self.assertEqual(m1.defections, 0)
self.assertEqual(m1.strategy(t), C)

m2 = MockPlayer([D], history=[D]*10)
self.assertEqual(m2.actions[0], D)
self.assertEqual(m2.actions.__next__(), D)
self.assertEqual(m2.history, [D] * 10)
self.assertEqual(m2.cooperations, 0)
self.assertEqual(m2.defections, 10)
Expand Down
Loading