Search code examples
pythonpython-3.xkeyerrorgame-theory

How can I resolve a key error in python axelrod Lookerup strategy


Using python axelrod library, I am going through the following (and excellent) blog for myself: http://mojones.net/evolving-strategies-for-an-iterated-prisoners-dilemma-tournament.html . In trying to implement the lookerup strategy, I get the following error:

KeyError: Plays(self_plays=(C, C), op_plays=(C, D), op_openings=(C, D))

How can I resolve this error? Am I implementing the lookerup strategy incorrectly? I have tried tracing the error through the the strategy's code on github, but I'm just not seeing the issue. The following code provides an example of my issue. And if I switch out the lookerup strategy for another (with another Alternator for example), the axelrod game performs as I would expect.

import axelrod
import random
import itertools
def get_random_table():
    strings = [''.join(x) for x in itertools.product('CD', repeat=2)]
    keys = list(itertools.product(strings, strings, strings))
    values = ''.join([random.choice('CD') for _ in keys])
    return dict(zip(keys, values))
player_1 = axelrod.LookerUp(random_table)
#player_1 = axelrod.Alternator()
player_2 = axelrod.Alternator()

g = axelrod.Game()
iterations = 10
for turn in range(iterations):
    player_1.play(player_2)

(Other tags might include "axelrod" and "prisoner's-dilemma".)


Solution

  • The issue is that you are using strings to represent actions, when you need to be using Actions. The repair is quite simple:

    import axelrod
    from axelrod.action import Action
    import itertools
    import random
    
    
    def get_random_table():
        action_pairs = list(itertools.product((Action.C, Action.D), repeat=2))  # <- Action
        keys = list(itertools.product(action_pairs, action_pairs, action_pairs))
        values = [random.choice((Action.C, Action.D)) for _ in keys]  # <- Actions instead of strings
        return dict(zip(keys, values))
    
    
    player_1 = axelrod.LookerUp(get_random_table())
    # player_1 = axelrod.Alternator()
    player_2 = axelrod.Alternator()
    
    g = axelrod.Game()
    iterations = 10
    for turn in range(iterations):
        player_1.play(player_2)