Skip to content

Commit e9da4f9

Browse files
committed
Add a hypothesis test for memory depth.
This checks that players need at most the memory depth that is described.
1 parent 3ee5c1f commit e9da4f9

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

axelrod/tests/strategies/test_player.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@
44
import unittest
55

66
import numpy as np
7+
from hypothesis import given, settings
8+
from hypothesis.strategies import integers
79

810
import axelrod
911
from axelrod import DefaultGame, Player
1012
from axelrod.player import get_state_distribution_from_history, update_history
13+
from axelrod.tests.property import strategy_lists
1114

1215

1316
C, D = axelrod.Action.C, axelrod.Action.D
1417

18+
short_run_time_short_mem = [s for s in axelrod.short_run_time_strategies
19+
if s().classifier["memory_depth"] <= 1]
20+
1521

1622
# Generic strategy functions for testing
1723

@@ -446,6 +452,27 @@ def test_clone(self):
446452
self.assertEqual(len(player1.history), turns)
447453
self.assertEqual(player1.history, player2.history)
448454

455+
@given(strategies=strategy_lists(max_size=5,
456+
strategies=short_run_time_short_mem),
457+
seed=integers(min_value=1, max_value=200),
458+
turns=integers(min_value=1, max_value=200))
459+
@settings(max_examples=1, max_iterations=1)
460+
def test_memory_depth_upper_bound(self, strategies, seed, turns):
461+
"""
462+
Test that the memory depth is indeed an upper bound.
463+
"""
464+
player = self.player()
465+
memory = player.classifier["memory_depth"]
466+
if memory < float("inf"):
467+
for strategy in strategies:
468+
opponent = strategy()
469+
self.assertTrue(test_memory(player=player,
470+
opponent=opponent,
471+
seed=seed,
472+
turns=turns,
473+
memory_length=memory),
474+
msg="Failed for seed={} and opponent={}".format(seed, opponent))
475+
449476
def versus_test(self, opponent, expected_actions,
450477
noise=None, seed=None, turns=10,
451478
match_attributes=None, attrs=None,
@@ -564,3 +591,50 @@ def test_four_vector(test_class, expected_dictionary):
564591
for key in sorted(expected_dictionary.keys(), key=str):
565592
test_class.assertAlmostEqual(
566593
player1._four_vector[key], expected_dictionary[key])
594+
595+
596+
def test_memory(player, opponent, memory_length, seed=None, turns=10):
597+
"""
598+
Checks if a player reacts to the plays of an opponent in the same way if
599+
only the given amount of memory is used.
600+
"""
601+
if seed is not None:
602+
axelrod.seed(seed)
603+
604+
match = axelrod.Match((player, opponent), turns=turns)
605+
expected_results = match.play()
606+
607+
if seed is not None:
608+
axelrod.seed(seed)
609+
player.reset()
610+
opponent.reset()
611+
612+
results = []
613+
for _ in range(turns):
614+
player.history = player.history[-memory_length:]
615+
opponent.history = opponent.history[-memory_length:]
616+
player.play(opponent)
617+
results.append(player.history[-1])
618+
return results == [interactions[0] for interactions in expected_results]
619+
620+
class TestMemoryTest(unittest.TestCase):
621+
"""
622+
Test for the memory test function.
623+
"""
624+
def test_passes(self):
625+
"""
626+
The memory test function returns True in this case as the correct mem
627+
length is used
628+
"""
629+
player = axelrod.TitFor2Tats()
630+
opponent = axelrod.Defector()
631+
self.assertTrue(test_memory(player, opponent, memory_length=2))
632+
633+
def test_failures(self):
634+
"""
635+
The memory test function returns False in this case as the incorrect mem
636+
length is used
637+
"""
638+
player = axelrod.TitFor2Tats()
639+
opponent = axelrod.Defector()
640+
self.assertFalse(test_memory(player, opponent, memory_length=1))

0 commit comments

Comments
 (0)