# tossing.py, a disc-tossing simulation. # By Dustin Freeman, dustinfreeman.org, Sept 28, 2009. from array import array import random random.seed() #I make no excuse for messy code practices. Love, Dustin. num_tossers = 6 init_tossers = array ('c',['w','d','d','d','w','w']) # w - waiting # d - has a disc # t - just threw a disc # c - just caught a disc # f - just dropped a disc. Will pick it up for next turn tosser_type = array('c',['r','r','r','r','r','r']) # j - jerk # r - reluctant tosser_waiting = array ('i',[0,0,0,0,0,0]) # how many turns a tosser has waited. incoming_discs_init = array ('i',[0,0,0,0,0,0]) # the number of discs incoming to each person. >1 is a fail state. tossers = array('i') incoming_discs_prev= array('i') incoming_discs_curr= array('i') num_collisions = 0 num_tosses = 0 def initialize(): global tossers tossers = init_tossers[:] global incoming_discs_prev incoming_discs_prev = incoming_discs_init[:] global incoming_discs_curr incoming_discs_curr = incoming_discs_init[:] def toss(i): global tossers global incoming_discs_curr global num_tosses reciever = random.randint(0,num_tossers-1) while ((tossers[reciever] != 'w') & (incoming_discs_curr[reciever] == 0)): reciever = random.randint(0,num_tossers-1) incoming_discs_curr[reciever] +=1 tossers[i] = 't' num_tosses += 1 tosser_waiting[i]= 0 def toss_decision(i): global num_tossers global tossers global tosser_type if (tosser_type[i] == 'j'): #jerks toss right away. toss(i) elif (tosser_waiting[i] < 3): wait = False for j in range(0,num_tossers): if ((tossers[j] == 'c') | (tossers[j] == 'd')): wait=True if (wait): tossers[i] = 'd' tosser_waiting[i] +=1 else: toss(i) else: if (random.random() > 0.5): toss(i) failure_rate = 0.1 Its = 10000 verbose = False initialize() #main simulation loop for it in range(0, Its): if (verbose): print (it , ': ' , tossers.tostring(), incoming_discs_prev) num_discs = 0 for i in range(0,num_tossers): #error checking to make sure I don't "lose" discs. if ((tossers[i] == 't') | (tossers[i] == 'f') | (tossers[i] == 'c')| (tossers[i] == 'd')): num_discs +=1 print ('num discs ', num_discs) for i in range(0,num_tossers): if tossers[i] == 'w': if incoming_discs_prev[i] > 1: if (verbose): print ('collision!') num_collisions+=1 initialize() break elif incoming_discs_prev[i] ==1: tossers[i] = 'c' elif tossers[i] == 't': tossers[i] = 'w' elif tossers[i] == 'c': if incoming_discs_prev[i] > 0: if (verbose): print ('collision!') num_collisions+=1 initialize() break if (random.random() < failure_rate): #dropped the disc tossers[i] = 'f' else: toss_decision(i) elif tossers[i] == 'f': toss_decision(i) elif tossers[i] == 'd': toss_decision(i) incoming_discs_prev = incoming_discs_curr[:] incoming_discs_curr = incoming_discs_init[:] #results print ('Its: ', Its, 'Num Collisions: ' , num_collisions, 'Num Tosses: ',num_tosses, 'Coll per Toss: ', num_collisions/float(num_tosses))