Reputation: 127
I was writing an implementation of the iterated prisoner's dilemma in Python, and am having the following problem.
for p in players:
for o in players:
if p.name != o.name:
try:
p.history[o.name]
except KeyError:
p.history[o.name] = []
o.history[p.name] = []
for i in xrange(0,2):
result = play(p.logic(p.history[o.name]),
o.logic(o.history[p.name]))
p.history[o.name].append(result[0])
o.history[p.name].append(result[1])
This is the code I have. The 'players' list is a list of Strategy objects which have 'name' a string, and 'logic' a function. The trouble I am having occurs at the lines
p.history[o.name].append(result[0])
I am attempting to create the following dictionaries:
Player 1.history = {"Player 2 Name": [result, result, result]}
Player 2.history = {"Player 1 Name": [result, result, result]}
But I get this instead:
Player 1.history = {"Player 1 Name": [wrong results],
"Player 2 Name": [wrong results]}
The results aren't all wrong, but some are. Does anyone know why either the results aren't all right or why I have the key "Player 1 Name" in Player 1's dictionary and "Player 2 Name" in Player 2's dictionary?
EDIT: Some more code on request
class Strategy:
"""Basic class for all strategies to use. The 'logic' function is defined oustide and governs behavior"""
def __init__(self, logic, name):
self.logic = logic
self.name = name
history = {}
def makePlayer(name):
if name == "Defects":
def logic(hist):
return 1
if name == "Tit for Tat":
def logic(hist):
for i in xrange(1,3):
try:
if hist[len(hist) - i][1] == 1:
return 1
except IndexError:
pass
return 0
return Strategy(logic, name)
payoff = [[100, 0], [101, 1]]
def play(choice1, choice2): #choiceFoo = 0 => cooperate; 1 => defect
return [[choice1, choice2, payoff[choice1][choice2]], [choice2, choice1, payoff[choice2][choice1]]]
Upvotes: 0
Views: 150
Reputation: 43497
This isn't a complete answer, but doing "real work" in an exception block is bound to cause confusion. If you want to see if there is a key in a dictionary, do so explicitly with the in
operation.
You can drop the try/except block by changing the conditional to
if p.name != o.name and o.name not in p.history:
Then again, part of the iterated prisoners dilemma is that a strategy should play against itself so that might be better as:
if o.name not in p.history:
Without more of the troublesome code (e.g. play
) it is hard to give more advice on this problem.
Upvotes: 1