def matchProb(s, t, gv=0, gw=0, sv=0, sw=0, mv=0, mw=0, sets=3): ## calculates probability of winning a match from any given score, ## given: ## s, t: p(server wins a service point), p(server wins return point) ## gv, gw: current score within the game. e.g. 30-15 is 2, 1 ## sv, sw: current score within the set. e.g. 5, 4 ## mv, mw: current score within the match (number of sets for each player) ## v's are serving player; w's are returning player ## sets: "best of", so default is best of 3 a = gameProb(s) b = gameProb(t) c = setGeneral(s, t) #print 'set prob: ',c[0] if gv == 0 and gw == 0: ## no point score if sv == 0 and sw == 0: ## no game score #print 'mwin: ', matchGeneral(c[0], v=mv, w=mw, s=sets) return matchGeneral(c[0], v=mv, w=mw, s=sets) else: ## we're in mid-set, no point score sWin = setGeneral(s, t, v=sv, w=sw)[0] sLoss = 1 - sWin elif sv == 6 and sw == 6: sWin = tiebreakProb(s, t, v=gv, w=gw) sLoss = 1 - sWin else: gWin = gameProb(s, v=gv, w=gw) gLoss = 1 - gWin sWin = gWin*(1 - setGeneral(1-t, 1-s, v=sw, w=sv+1)[0]) sWin += gLoss*(1 - setGeneral(1-t, 1-s, v=sw+1, w=sv)[0]) sLoss = 1 - sWin mWin = sWin*matchGeneral(c[0], v=mv+1, w=mw, s=sets) mWin += sLoss*matchGeneral(c[0], v=mv, w=mw+1, s=sets) #print 'mwin: ', mWin return mWin
def matchProb(s, t, gv=0, gw=0, sv=0, sw=0, mv=0, mw=0, sets=3): ## calculates probability of winning a match from any given score, ## given: ## s, t: p(server wins a service point), p(server wins return point) ## gv, gw: current score within the game. e.g. 30-15 is 2, 1 ## sv, sw: current score within the set. e.g. 5, 4 ## mv, mw: current score within the match (number of sets for each player) ## v's are serving player; w's are returning player ## sets: "best of", so default is best of 3 a = gameProb(s) b = gameProb(t) c = setGeneral(s, t) if gv == 0 and gw == 0: ## no point score if sv == 0 and sw == 0: ## no game score return matchGeneral(c, v=mv, w=mw, s=sets) else: ## we're in mid-set, no point score sWin = setGeneral(a, b, s, t, v=sv, w=sw) sLoss = 1 - sWin elif sv == 6 and sw == 6: sWin = tiebreakProb(s, t, v=gv, w=gw) sLoss = 1 - sWin else: gWin = gameProb(s, v=gv, w=gw) gLoss = 1 - gWin sWin = gWin*(1 - setGeneral((1-b), (1-a), (1-t), (1-s), v=sw, w=(sv+1))) sWin += gLoss*(1 - setGeneral((1-b), (1-a), (1-t), (1-s), v=(sw+1), w=sv)) sLoss = 1 - sWin mWin = sWin*matchGeneral(c, v=(mv+1), w=mw, s=sets) mWin += sLoss*matchGeneral(c, v=mv, w=(mw+1), s=sets) return mWin
def setGeneral(s, u, v=0, w=0, tb=1): ## calculate the probability of the current server winning ## a 6-game, tiebreak set, given prob. of server winning any ## given service point (s) or return point (u), and the current ## game score (v, w) ## get prob of current server winning a service game: g = gameProb(s) ## and current server winning a return game: h = gameProb(u) ## is set over? if tb: if v == 7: return 1 elif w == 7: return 0 elif v == 6 and (v-w) > 1: return 1 elif w == 6 and (w-v) > 1: return 0 else: pass else: if v >= 6 and (v-w) > 1: return 1 elif w >= 6 and (w-v) > 1: return 0 else: pass ## if not over, re-adjust down to no higher than 6-6 while True: if (v+w) > 12: v -= 1 w -= 1 else: break ## if no tiebreak, chance that server wins set is ratio of server's prob of winning ## two games in a row to returner's prob of winning two games in a row if not tb: deuceprob = (g*h)/((g*h) + (1-g)*(1-h)) outcomes = {} ## special cases, 11 games or more already if (v+w) == 12: if tb: tp = tiebreakProb(s, u) outcomes['76'] = tp outcomes['67'] = 1 - tp else: outcomes['75'] = deuceprob outcomes['57'] = 1-deuceprob elif (v+w) == 11: if tb: tp = tiebreakProb((1-u), (1-s)) if v == 6: outcomes['75'] = g x = (1-g) outcomes['76'] = x*(1 - tp) outcomes['67'] = x*tp else: outcomes['57'] = 1-g x = g outcomes['76'] = x*(1 - tp) outcomes['67'] = x*tp else: if v == 6: outcomes['75'] = g outcomes['57'] = 0 f = 1 - g ## f is p(getting to 6-6) else: outcomes['57'] = 1-g outcomes['75'] = 0 f = g ## f is p(getting to 6-6) outcomes['75'] += f*deuceprob outcomes['57'] += f*(1-deuceprob) else: ## win probabilities for i in range(5): ## i = 0 t = 6 + i - v - w ## total games remaining in set if t < 1: continue if t % 2 == 0: final = h sGames = t/2 rGames = sGames - 1 else: final = g sGames = (t-1)/2 rGames = (t-1)/2 pOutcome = setOutcome(final, sGames, rGames, v, g, h) key = '6' + str(i) outcomes[key] = pOutcome ## loss probabilities ## this section isn't necessary, but I wrote it for informal ## testing purposes for i in range(5): t = 6 + i - v - w ## total games in set; here it's 6 if t < 1: continue if t % 2 == 0: final = 1-h sGames = t/2 rGames = sGames - 1 else: final = 1-g sGames = (t-1)/2 rGames = (t-1)/2 pOutcome = setOutcome(final, sGames, rGames, w, (1-g), (1-h)) key = str(i) + '6' outcomes[key] = pOutcome ## prob of getting to 5-5 t = 10 - v - w if t % 2 == 0: sGames = t/2 rGames = t/2 else: sGames = (t-1)/2 + 1 rGames = (t-1)/2 f = setOutcome(1, sGames, rGames, v, g, h) if tb == 1: outcomes['75'] = f*g*h outcomes['57'] = f*(1-g)*(1-h) x = f*g*(1-h) + f*(1-g)*h ## p(getting to 6-6) if (v+w) % 2 == 0: tp = tiebreakProb(s, u) else: tp = tiebreakProb(u, s) outcomes['76'] = x*tp outcomes['67'] = x - x*tp else: outcomes['75'] = f*deuceprob outcomes['57'] = f*(1-deuceprob) win = 0 for o in outcomes: if o in ['60', '61', '62', '63', '64', '75', '76']: win += outcomes[o] else: pass return win, outcomes
def setGeneral(s, u, v=0, w=0, tb=1): ## calculate the probability of the current server winning ## a 6-game, tiebreak set, given prob. of server winning any ## given service point (s) or return point (u), and the current ## game score (v, w) ## get prob of current server winning a service game: __ = '' # dummy variable to address type issues g = gameProb(s) ## and current server winning a return game: h = gameProb(u) ## is set over? if tb: if v == 7: return 1, __ elif w == 7: return 0, __ elif v == 6 and (v - w) > 1: return 1, __ elif w == 6 and (w - v) > 1: return 0, __ else: pass else: if v >= 6 and (v - w) > 1: return 1, __ elif w >= 6 and (w - v) > 1: return 0, __init__ else: pass ## if not over, re-adjust down to no higher than 6-6 while True: if (v + w) > 12: v -= 1 w -= 1 else: break ## if no tiebreak, chance that server wins set is ratio of server's prob of winning ## two games in a row to returner's prob of winning two games in a row if not tb: deuceprob = (g * h) / ((g * h) + (1 - g) * (1 - h)) outcomes = {} ## special cases, 11 games or more already if (v + w) == 12: if tb: tp = tiebreakProb(s, u) outcomes['76'] = tp outcomes['67'] = 1 - tp else: outcomes['75'] = deuceprob outcomes['57'] = 1 - deuceprob elif (v + w) == 11: if tb: tp = tiebreakProb((1 - u), (1 - s)) if v == 6: outcomes['75'] = g x = (1 - g) outcomes['76'] = x * (1 - tp) outcomes['67'] = x * tp else: outcomes['57'] = 1 - g x = g outcomes['76'] = x * (1 - tp) outcomes['67'] = x * tp else: if v == 6: outcomes['75'] = g outcomes['57'] = 0 f = 1 - g ## f is p(getting to 6-6) else: outcomes['57'] = 1 - g outcomes['75'] = 0 f = g ## f is p(getting to 6-6) outcomes['75'] += f * deuceprob outcomes['57'] += f * (1 - deuceprob) else: ## win probabilities for i in range(5): ## i = 0 t = 6 + i - v - w ## total games remaining in set if t < 1: continue if t % 2 == 0: final = h sGames = t / 2 rGames = sGames - 1 else: final = g sGames = (t - 1) / 2 rGames = (t - 1) / 2 pOutcome = setOutcome(final, sGames, rGames, v, g, h) key = '6' + str(i) outcomes[key] = pOutcome ## loss probabilities ## this section isn't necessary, but I wrote it for informal ## testing purposes for i in range(5): t = 6 + i - v - w ## total games in set; here it's 6 if t < 1: continue if t % 2 == 0: final = 1 - h sGames = t / 2 rGames = sGames - 1 else: final = 1 - g sGames = (t - 1) / 2 rGames = (t - 1) / 2 pOutcome = setOutcome(final, sGames, rGames, w, (1 - g), (1 - h)) key = str(i) + '6' outcomes[key] = pOutcome ## prob of getting to 5-5 t = 10 - v - w if t % 2 == 0: sGames = t / 2 rGames = t / 2 else: sGames = (t - 1) / 2 + 1 rGames = (t - 1) / 2 f = setOutcome(1, sGames, rGames, v, g, h) if tb == 1: outcomes['75'] = f * g * h outcomes['57'] = f * (1 - g) * (1 - h) x = f * g * (1 - h) + f * (1 - g) * h ## p(getting to 6-6) if (v + w) % 2 == 0: tp = tiebreakProb(s, u) else: tp = tiebreakProb(u, s) outcomes['76'] = x * tp outcomes['67'] = x - x * tp else: outcomes['75'] = f * deuceprob outcomes['57'] = f * (1 - deuceprob) win = 0 for o in outcomes: if o in ['60', '61', '62', '63', '64', '75', '76']: win += outcomes[o] else: pass return win, outcomes