Created
February 25, 2013 03:59
-
-
Save drocamor/5027626 to your computer and use it in GitHub Desktop.
Thinking about the prisoners dilemma with iPython. This is an iPython notebook. I made it python to share it with people.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
# <nbformat>3.0</nbformat> | |
# <headingcell level=1> | |
# The Game World | |
# <codecell> | |
def pd(previous_games, p1_fun, p2_fun): | |
"""Run one iteration of the prisoners dilemna""" | |
p1_result = p1_fun(previous_games, player_identity='p1') | |
p2_result = p2_fun(previous_games, player_identity='p2') | |
previous_games.append({'p1': p1_result, 'p2': p2_result}) | |
return previous_games | |
# <codecell> | |
def ipd(p1_fun, p2_fun, iterations = 100): | |
games = [] | |
for i in range(iterations): | |
result = pd(games, p1_fun, p2_fun) | |
games = result | |
scores = score(games) | |
# Make the players names readable | |
scores['game'] = p1_fun.func_name + " vs " + p2_fun.func_name | |
return scores | |
# <codecell> | |
def score_a_game(game): | |
p1 = game['p1'] | |
p2 = game['p2'] | |
if p1 is True and p2 is True: | |
return {'p1': 3, 'p2': 3} | |
if p1 is True and p2 is False: | |
return {'p1': 0, 'p2': 5} | |
if p1 is False and p2 is False: | |
return {'p1': 1, 'p2': 1} | |
if p1 is False and p2 is True: | |
return {'p1': 5, 'p2': 0} | |
# <codecell> | |
def score(games): | |
# Convert game outcomes into scores | |
scores = [ score_a_game(x) for x in games ] | |
p1_score = 0 | |
p2_score = 0 | |
for score in scores: | |
p1_score += score['p1'] | |
p2_score += score['p2'] | |
return {'p1': p1_score, | |
'p2': p2_score} | |
# <headingcell level=1> | |
# Helper functions, imports, etc | |
# <codecell> | |
from random import choice | |
import itertools | |
import operator | |
def most_common(L): | |
# get an iterable of (item, iterable) pairs | |
SL = sorted((x, i) for i, x in enumerate(L)) | |
# print 'SL:', SL | |
groups = itertools.groupby(SL, key=operator.itemgetter(0)) | |
# auxiliary function to get "quality" for an item | |
def _auxfun(g): | |
item, iterable = g | |
count = 0 | |
min_index = len(L) | |
for _, where in iterable: | |
count += 1 | |
min_index = min(min_index, where) | |
# print 'item %r, count %r, minind %r' % (item, count, min_index) | |
return count, -min_index | |
# pick the highest-count/earliest item | |
return max(groups, key=_auxfun)[0] | |
# <headingcell level=1> | |
# The Players | |
# <codecell> | |
def tit_for_tat(previous_games, player_identity): | |
"""Just do whatever the opponent did to you last time. Cooperate the first time.""" | |
opponent = 'p1' if player_identity == 'p2' else 'p2' | |
if len(previous_games) == 0: | |
return True | |
else: | |
return previous_games[-1][opponent] | |
# <codecell> | |
def tat_for_tit(previous_games, player_identity): | |
"""Do the opposite of whatever the opponent did last time. Cooperate the first time.""" | |
opponent = 'p1' if player_identity == 'p2' else 'p2' | |
if len(previous_games) == 0: | |
return True | |
if previous_games[-1][opponent]: | |
return False | |
else: | |
return True | |
# <codecell> | |
def be_an_ass(previous_games, player_identity): | |
"""Dumb and mean.""" | |
return False | |
# <codecell> | |
def be_naive(previous_games, player_identity): | |
"""Cooperative, and pretty stupid.""" | |
return True | |
# <codecell> | |
def be_crazy(previous_games, player_identity): | |
"""I AM SO RANDOM""" | |
return choice([True, False]) | |
# <codecell> | |
def have_a_long_memory(previous_games, player_identity): | |
"""Evaluate all of the games played, and do what the opponent usually does. Cooperate the first time.""" | |
opponent = 'p1' if player_identity == 'p2' else 'p2' | |
if len(previous_games) == 0: | |
return True | |
else: | |
opponents_moves = [ x[opponent] for x in previous_games ] | |
return most_common(opponents_moves) | |
# <headingcell level=1> | |
# Let the games begin! | |
# <codecell> | |
# Get the players in a list | |
players = [tit_for_tat, tat_for_tit, be_an_ass, be_naive, be_crazy, have_a_long_memory] | |
matches = itertools.combinations_with_replacement(players, 2) | |
results = [ ipd(match[0], match[1]) for match in matches ] | |
# <codecell> | |
for result in results: | |
print "%s: %s to %s" % (result['game'], result['p1'], result['p2']) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment