Skip to content

New meta strategies #777

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 21 commits into from
Dec 6, 2016
Merged
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
4 changes: 2 additions & 2 deletions axelrod/deterministic_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def _is_valid_key(self, key):
if len(key) != 3:
return False

# The triplet should be a pair of axelrod.Player sublclasses and an
# The triplet should be a pair of axelrod.Player instances and an
# integer
try:
if not (
Expand All @@ -111,7 +111,7 @@ def _is_valid_key(self, key):
except TypeError:
return False

# Each Player class should be deterministic
# Each Player should be deterministic
if key[0].classifier['stochastic'] or key[1].classifier['stochastic']:
return False

Expand Down
36 changes: 27 additions & 9 deletions axelrod/strategies/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,35 @@
# because it creates circular dependencies

from .meta import (
MetaPlayer, MetaMajority, MetaMinority, MetaWinner, MetaHunter,
MetaMajorityMemoryOne, MetaWinnerMemoryOne, MetaMajorityFiniteMemory,
MetaWinnerFiniteMemory, MetaMajorityLongMemory, MetaWinnerLongMemory,
MetaMixer, MetaWinnerEnsemble
MetaHunter, MetaHunterAggressive, MetaPlayer, MetaMajority,
MetaMajorityMemoryOne, MetaMajorityFiniteMemory, MetaMajorityLongMemory,
MetaMinority, MetaMixer, MetaWinner, MetaWinnerDeterministic,
MetaWinnerEnsemble, MetaWinnerMemoryOne, MetaWinnerFiniteMemory,
MetaWinnerLongMemory, MetaWinnerStochastic, MWEDeterministic,
MWEFiniteMemory, MWELongMemory, MWEMemoryOne, MWEStochastic
)

all_strategies.extend([MetaHunter, MetaMajority, MetaMinority, MetaWinner,
MetaMajorityMemoryOne, MetaWinnerMemoryOne,
MetaMajorityFiniteMemory, MetaWinnerFiniteMemory,
MetaMajorityLongMemory, MetaWinnerLongMemory, MetaMixer,
MetaWinnerEnsemble])
all_strategies += [MetaHunter,
Copy link
Member

Choose a reason for hiding this comment

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

Is this just a stylistic change?

(I don't mind at all, not requesting a change here, just curious.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes

MetaHunterAggressive,
MetaMajority,
MetaMajorityMemoryOne,
MetaMajorityFiniteMemory,
MetaMajorityLongMemory,
MetaMinority,
MetaMixer,
MetaWinner,
MetaWinnerDeterministic,
MetaWinnerEnsemble,
MetaWinnerMemoryOne,
MetaWinnerFiniteMemory,
MetaWinnerLongMemory,
MetaWinnerStochastic,
MWEDeterministic,
MWEFiniteMemory,
MWELongMemory,
MWEMemoryOne,
MWEStochastic
]


# Distinguished strategy collections in addition to
Expand Down
20 changes: 10 additions & 10 deletions axelrod/strategies/_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
import operator


def passes_operator_filter(strategy, classifier_key, value, operator):
def passes_operator_filter(player, classifier_key, value, operator):
"""
Tests whether a given strategy passes a filter for a
Tests whether a given player passes a filter for a
given key in its classifier dict using a given (in)equality operator.

e.g.
Expand All @@ -19,13 +19,13 @@ class ExampleStrategy(Player):
'makes_use_of': ['game', 'length']
}

passes_operator_filter(ExampleStrategy, 'memory_depth', 10, operator.eq)
passes_operator_filter(ExampleStrategy(), 'memory_depth', 10, operator.eq)

would test whether the 'memory_depth' entry equals 10 and return True

Parameters
----------
strategy : a descendant class of axelrod.Player
player : an instance of axelrod.Player
classifier_key: string
Defining which entry from the strategy's classifier dict is to be
tested (e.g. 'memory_depth').
Expand All @@ -43,18 +43,18 @@ class ExampleStrategy(Player):
True if the value from the strategy's classifier dictionary matches
the value and operator passed to the function.
"""
classifier_value = strategy.classifier[classifier_key]
classifier_value = player.classifier[classifier_key]
if (isinstance(classifier_value, str) and
classifier_value.lower() == 'infinity'):
classifier_value = float('inf')

return operator(classifier_value, value)


def passes_in_list_filter(strategy, classifier_key, value):
def passes_in_list_filter(player, classifier_key, value):
"""
Tests whether a given list of values exist in the list returned from the
given strategy's classifier dict for the given classifier_key.
given players's classifier dict for the given classifier_key.

e.g.

Expand All @@ -68,7 +68,7 @@ class ExampleStrategy(Player):
'makes_use_of': ['game', 'length']
}

passes_in_list_filter(ExampleStrategy, 'makes_use_of', 'game', operator.eq)
passes_in_list_filter(ExampleStrategy(), 'makes_use_of', 'game', operator.eq)

would test whether 'game' exists in the strategy's' 'makes_use_of' entry
and return True.
Expand All @@ -89,7 +89,7 @@ class ExampleStrategy(Player):
"""
result = True
for entry in value:
if entry not in strategy.classifier[classifier_key]:
if entry not in player.classifier[classifier_key]:
result = False
return result

Expand Down Expand Up @@ -211,7 +211,7 @@ class ExampleStrategy(Player):

if filterset.get(_filter, None) is not None:
kwargs = filter_function.kwargs
kwargs['strategy'] = strategy
kwargs['player'] = strategy()
kwargs['value'] = filterset[_filter]
passes_filters.append(filter_function.function(**kwargs))

Expand Down
2 changes: 1 addition & 1 deletion axelrod/strategies/adaptive.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def __init__(self, initial_plays=None):
if not initial_plays:
initial_plays = [C] * 6 + [D] * 5
self.initial_plays = initial_plays
self.reset()
self.scores = {C: 0, D: 0}

def score_last_round(self, opponent):
# Load the default game if not supplied by a tournament.
Expand Down
20 changes: 12 additions & 8 deletions axelrod/strategies/grudger.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ def __init__(self):
self.grudge_memory = 0

def strategy(self, opponent):
"""Begins by playing C, then plays D for mem_length rounds if the opponent ever plays D."""
"""Begins by playing C, then plays D for mem_length rounds if the
opponent ever plays D."""
if self.grudge_memory >= self.mem_length:
self.grudge_memory = 0
self.grudged = False
Expand All @@ -79,7 +80,8 @@ def reset(self):


class OppositeGrudger(Player):
"""A player starts by defecting however will cooperate if at any point the opponent has cooperated."""
"""A player starts by defecting however will cooperate if at any point the
opponent has cooperated."""

name = 'Opposite Grudger'
classifier = {
Expand All @@ -94,7 +96,8 @@ class OppositeGrudger(Player):

@staticmethod
def strategy(opponent):
"""Begins by playing D, then plays C for the remaining rounds if the opponent ever plays C."""
"""Begins by playing D, then plays C for the remaining rounds if the
opponent ever plays C."""
if opponent.cooperations:
return C
return D
Expand Down Expand Up @@ -174,7 +177,6 @@ def reset(self):
self.grudge_memory = 0



class GrudgerAlternator(Player):
"""
A player starts by cooperating until the first opponents defection,
Expand All @@ -198,17 +200,18 @@ class GrudgerAlternator(Player):
}

def strategy(self, opponent):
"""Begins by playing C, then plays Alternator for the remaining rounds if the opponent ever plays D."""
"""Begins by playing C, then plays Alternator for the remaining rounds
if the opponent ever plays D."""
if opponent.defections:
if self.history[-1] == Actions.C:
return Actions.D
return Actions.C



class EasyGo(Player):
"""
A player starts by defecting however will cooperate if at any point the opponent has defected.
A player starts by defecting however will cooperate if at any point the
opponent has defected.

Names:

Expand All @@ -228,7 +231,8 @@ class EasyGo(Player):

@staticmethod
def strategy(opponent):
"""Begins by playing D, then plays C for the remaining rounds if the opponent ever plays D."""
"""Begins by playing D, then plays C for the remaining rounds if the
opponent ever plays D."""
if opponent.defections:
return C
return D
Loading