from random import * def we(dr=111): # USCF formula for winning expectation # dr = rating difference return 1./(1.+10.**(dr/400.)) class player: def __init__(self, name, rating): self.name = name self.rating = rating self.score = 0.0 def match(drawprob=.25, maxrounds=4): sloan = player('Sloan', 1936) brock = player('Brock', 1936+111) white_advantage = 50. sloan_white_first_round = False if sloan_white_first_round: white, black = sloan, brock else: white, black = brock, sloan assert maxrounds % 2 == 0 result = [] for round in xrange(1,maxrounds+1): expectation = we(white.rating + white_advantage - black.rating) winprob = expectation - drawprob/2. lossprob = 1. - (winprob + drawprob) assert abs(winprob+lossprob+drawprob-1.0) < .0001 # print '%d PW=%.3f PL=%.3f PD=%.3f'% \ # (round, winprob, lossprob, drawprob) r = random() if r < drawprob: white.score += .5 black.score += .5 result.append('draw') else: winner = (black, white)[r < (drawprob + lossprob)] winner.score += 1 result.append(winner.name + ' wins') if sloan.score >= maxrounds//2 or brock.score > maxrounds//2: break white, black = black, white rr = brock.score > maxrounds//2 return rr def sim(n=10): a = [0,0] for i in xrange(n): a[match(drawprob=.25)] += 1 print a # a = (sloan score, brock score) trials = 100000 sim(trials)