Skip to content

Commit

Permalink
Rework classifiers for transformers, rebuild expected classifiers to …
Browse files Browse the repository at this point in the history
…correctly capture Meta player makes_use_of
  • Loading branch information
marcharper committed Aug 1, 2020
1 parent 761f887 commit 1fd9dd6
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 28 deletions.
45 changes: 34 additions & 11 deletions axelrod/data/all_classifiers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -961,39 +961,47 @@ Meta Hunter Aggressive:
Meta Majority:
inspects_source: false
long_run_time: true
makes_use_of: !!set {}
makes_use_of: !!set
game: null
length: null
manipulates_source: false
manipulates_state: false
memory_depth: .inf
stochastic: true
Meta Majority Finite Memory:
inspects_source: false
long_run_time: true
makes_use_of: !!set {}
makes_use_of: !!set
game: null
manipulates_source: false
manipulates_state: false
memory_depth: .inf
stochastic: true
Meta Majority Long Memory:
inspects_source: false
long_run_time: true
makes_use_of: !!set {}
makes_use_of: !!set
game: null
length: null
manipulates_source: false
manipulates_state: false
memory_depth: .inf
stochastic: true
Meta Majority Memory One:
inspects_source: false
long_run_time: true
makes_use_of: !!set {}
makes_use_of: !!set
game: null
manipulates_source: false
manipulates_state: false
memory_depth: .inf
stochastic: true
Meta Minority:
inspects_source: false
long_run_time: true
makes_use_of: !!set {}
makes_use_of: !!set
game: null
length: null
manipulates_source: false
manipulates_state: false
memory_depth: .inf
Expand All @@ -1011,6 +1019,7 @@ Meta Winner:
long_run_time: true
makes_use_of: !!set
game: null
length: null
manipulates_source: false
manipulates_state: false
memory_depth: .inf
Expand All @@ -1020,6 +1029,7 @@ Meta Winner Deterministic:
long_run_time: true
makes_use_of: !!set
game: null
length: null
manipulates_source: false
manipulates_state: false
memory_depth: .inf
Expand All @@ -1029,6 +1039,7 @@ Meta Winner Ensemble:
long_run_time: true
makes_use_of: !!set
game: null
length: null
manipulates_source: false
manipulates_state: false
memory_depth: .inf
Expand All @@ -1047,6 +1058,7 @@ Meta Winner Long Memory:
long_run_time: true
makes_use_of: !!set
game: null
length: null
manipulates_source: false
manipulates_state: false
memory_depth: .inf
Expand All @@ -1065,6 +1077,7 @@ Meta Winner Stochastic:
long_run_time: true
makes_use_of: !!set
game: null
length: null
manipulates_source: false
manipulates_state: false
memory_depth: .inf
Expand Down Expand Up @@ -1130,40 +1143,47 @@ N Tit(s) For M Tat(s):
NMWE Deterministic:
inspects_source: false
long_run_time: true
makes_use_of: &id001 !!set
makes_use_of: !!set
game: null
length: null
manipulates_source: false
manipulates_state: false
memory_depth: .inf
stochastic: true
NMWE Finite Memory:
inspects_source: false
long_run_time: true
makes_use_of: *id001
makes_use_of: !!set
game: null
manipulates_source: false
manipulates_state: false
memory_depth: .inf
stochastic: true
NMWE Long Memory:
inspects_source: false
long_run_time: true
makes_use_of: *id001
makes_use_of: !!set
game: null
length: null
manipulates_source: false
manipulates_state: false
memory_depth: .inf
stochastic: true
NMWE Memory One:
inspects_source: false
long_run_time: true
makes_use_of: *id001
makes_use_of: !!set
game: null
manipulates_source: false
manipulates_state: false
memory_depth: .inf
stochastic: true
NMWE Stochastic:
inspects_source: false
long_run_time: true
makes_use_of: *id001
makes_use_of: !!set
game: null
length: null
manipulates_source: false
manipulates_state: false
memory_depth: .inf
Expand Down Expand Up @@ -1197,14 +1217,17 @@ Nice Meta Winner:
long_run_time: true
makes_use_of: !!set
game: null
length: null
manipulates_source: false
manipulates_state: false
memory_depth: .inf
stochastic: true
Nice Meta Winner Ensemble:
inspects_source: false
long_run_time: true
makes_use_of: *id001
makes_use_of: !!set
game: null
length: null
manipulates_source: false
manipulates_state: false
memory_depth: .inf
Expand Down
13 changes: 10 additions & 3 deletions axelrod/makes_use_of.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ def method_makes_use_of(method: Callable) -> Set[Text]:


def class_makes_use_of(cls) -> Set[Text]:
result = set()
try:
result = cls.classifier["makes_use_of"]
except (AttributeError, KeyError):
result = set()

for method in inspect.getmembers(cls, inspect.ismethod):
if method[0] == "__init__":
continue
Expand All @@ -32,10 +36,13 @@ def makes_use_of(player: Type[Player]) -> Set[Text]:


def makes_use_of_variant(
player_or_method: Union[Callable, Type[Player]], verbose=False
player_or_method: Union[Callable, Type[Player]]
) -> Set[Text]:
"""A version of makes_use_of that works on functions or player classes."""
try:
return method_makes_use_of(player_or_method)
except:
# OSError catches the case of a transformed player, which has a dynamically
# created class.
# TypeError is the case in which we have a class rather than a method
except (OSError, TypeError):
return class_makes_use_of(player_or_method)
24 changes: 11 additions & 13 deletions axelrod/strategy_transformers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
See the various Meta strategies for another type of transformation.
"""

import inspect
from importlib import import_module
from typing import Any

from axelrod.strategies.sequence_player import SequencePlayer

from .action import Action
from .makes_use_of import *
from .makes_use_of import makes_use_of_variant
from .player import Player

C, D = Action.C, Action.D
Expand All @@ -25,8 +26,11 @@
def makes_use_of_reclassifier(original_classifier, player_class, wrapper):
"""Reclassifier for post-transformation determination of whether
strategy makes_use_of anything differently."""
classifier_makes_use_of = makes_use_of(player_class)
classifier_makes_use_of = makes_use_of_variant(player_class)
# Wrapper is usually a function, but can be a class, e.g. in the case of the
# RetaliationUntilApologyWrapper
classifier_makes_use_of.update(makes_use_of_variant(wrapper))

try:
original_classifier["makes_use_of"].update(classifier_makes_use_of)
except KeyError:
Expand Down Expand Up @@ -156,16 +160,6 @@ def strategy(self, opponent):
# Modify the Player name (class variable inherited from Player)
name = " ".join([name_prefix, PlayerClass.name])

# original_classifier = copy.deepcopy(PlayerClass.classifier) # Copy
# if reclassifier is not None:
# classifier = reclassifier(original_classifier, *args, **kwargs)
# else:
# classifier = original_classifier
# classifier_makes_use_of = makes_use_of(PlayerClass)
# classifier_makes_use_of.update(
# makes_use_of_variant(strategy_wrapper))
# classifier["makes_use_of"] = classifier_makes_use_of

# Define the new __repr__ method to add the wrapper arguments
# at the end of the name
def __repr__(self):
Expand Down Expand Up @@ -494,10 +488,14 @@ def final_sequence(player, opponent, action, seq):


def final_reclassifier(original_classifier, seq):
"""Reclassify the strategy"""
"""Reclassify the strategy."""
original_classifier["memory_depth"] = max(
len(seq), original_classifier["memory_depth"]
)
# This should also be picked up by the makes_use_of inspection,
# but we list it here to be explicit.
if len(seq) > 0:
original_classifier["makes_use_of"].add("length")
return original_classifier


Expand Down
24 changes: 23 additions & 1 deletion axelrod/tests/unit/test_makes_use_of.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
import unittest

import axelrod as axl
from axelrod.makes_use_of import makes_use_of
from axelrod.makes_use_of import (
class_makes_use_of,
makes_use_of,
makes_use_of_variant,
method_makes_use_of
)
from axelrod.strategy_transformers import final_sequence


class TestMakesUseOfLengthAndGamePlayer(axl.Player):
Expand Down Expand Up @@ -45,3 +51,19 @@ def test_makes_use_of_length_and_game(self):

def test_makes_use_of_empty(self):
self.assertEqual(makes_use_of(TestMakesUseOfNothingPlayer()), set())

def test_untransformed_class(self):
for player in [axl.Cooperator(), axl.Random()]:
self.assertEqual(class_makes_use_of(player), set())
self.assertEqual(makes_use_of_variant(player), set())
self.assertEqual(method_makes_use_of(player.strategy), set())

def test_transformer_wrapper(self):
# Test that the final transformer wrapper makes use of length
self.assertEqual(method_makes_use_of(final_sequence), {"length"})

def test_makes_use_of_transformed(self):
# These players use match length via Final transformer
for player in [axl.BackStabber(), axl.FirstBySteinAndRapoport()]:
self.assertEqual(makes_use_of(player), {"length"})
self.assertEqual(makes_use_of_variant(player), {"length"})

0 comments on commit 1fd9dd6

Please sign in to comment.