Skip to content

Instantly share code, notes, and snippets.

@sdebaun
Last active January 2, 2016 21:19
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save sdebaun/8362314 to your computer and use it in GitHub Desktop.
from random import sample, shuffle
from string import ascii_lowercase
class Game(object):
def __init__(self,player_count, mins_per_player, gains_per_min, gains_per_reform):
self.player_count, self.mins_per_player, self.gains_per_reform, self.gains_per_min = player_count, mins_per_player, gains_per_reform, gains_per_min
self.total_mins = self.player_count * self.mins_per_player
self.minset = [l for l in ascii_lowercase[:self.total_mins]]
self.gainset = self.minset * self.gains_per_min
self.total_gains = self.total_mins * self.gains_per_min
self.max_gain_coop_threshold = round(1.0 * self.gains_per_reform / self.player_count)
self.player_minsets = [list() for i in xrange(self.player_count)]
for minset in self.player_minsets:
for mpp in xrange(self.mins_per_player): minset.append(self.minset.pop())
self.trials = 0
self.stats = { 'aligns': {'coop':0,'split':0,'defect':0} }
def execute(self,trials):
for i in xrange(trials):
r = Round(self)
r.execute()
self.trials += 1
self.count('aligns',r.balance,1)
def count(self,stat,key,amount):
try: self.stats[stat][key] += amount
except: self.stats[stat][key] = amount
class Round(object):
def __init__(self,game):
self.game = game
self.gains = []
def execute(self):
self.gains = sample(self.game.gainset, self.game.gains_per_reform)
self.player_gains = []
for minset in self.game.player_minsets:
self.player_gains.append( sum([self.gains.count(min) for min in minset]))
self.player_gains.sort()
self.calculate_alignments()
def calculate_alignments(self):
self.defects, self.coops = 0, 0
for cur_p in self.player_gains:
net_change = 0
for other_p in self.player_gains: net_change += (cur_p - other_p)
if net_change > 0: self.defects += 1
else: self.coops += 1
if self.defects > self.coops: self.balance = "defect"
elif self.coops > self.defects: self.balance = "coop"
else: self.balance = "split"
from random import sample, shuffle
from string import ascii_lowercase
class Game(object):
# added to the existing object...
@classmethod
def header(cls):
f = ('players','mins/player','total mins','gains/min','total gains','gains/reform','coop thresh','align coop','align split','align defect')
return "\t".join(f)
def out(self):
f = [self.player_count, self.mins_per_player, self.total_mins, self.gains_per_min, self.total_gains, self.gains_per_reform, self.max_gain_coop_threshold]
f = f + ["%0.3f" % (1.0*self.stats['aligns'][k]/self.trials) for k in ['coop','split','defect']]
return "\t".join([str(i) for i in f])
# meanwhile, back at the loop...
print Game.header()
for p, gprset in configs.iteritems():
# that really
# deep
# nested loop
g = Game(p,mpp,gpm,gpr)
g.execute(1000)
print g.out()
configs = {3: [3,4,5],
4: [4,5,6],
5: [2,3,4,5,6,7,8],
6: [2,3,4,5]}
MINISTRIES_PER_PLAYER = (1,2,3)
GAINS_PER_MINISTRY = (1,2,3,4)
for p, gprset in configs.iteritems():
for mpp in MINISTRIES_PER_PLAYER:
for gpr in gprset:
for gpm in GAINS_PER_MINISTRY:
if (gpr > (p * mpp * gpm)): continue
if (p * mpp) > 20: continue
g = Game(p,mpp,gpm,gpr)
g.execute(1000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment