Match probability calculator, given Fargo ratings

A while back I made a spreadsheet to calculate the odds for high races. I'll share it here just as an alternative. It doesn't use a simulation. To be honest I forget exactly how it works, but here's the spreadsheet formula I came up with:

Code:
=SUM(ARRAYFORMULA(
    NEGBINOM.DIST(SEQUENCE(games_b)-1, games_a, FARGO_GAME_WIN_ODDS(rating_a, rating_b))
))

Edit: here's FARGO_GAME_WIN_ODDS for completeness
Code:
=1 / (1 + POW(2, (rating_b - rating_a)/100))

 
Last edited:
A while back I made a spreadsheet to calculate the odds for high races. I'll share it here just as an alternative. It doesn't use a simulation. To be honest I forget exactly how it works, but here's the spreadsheet formula I came up with:

Code:
=SUM(ARRAYFORMULA(
    NEGBINOM.DIST(SEQUENCE(games_b)-1, games_a, FARGO_GAME_WIN_ODDS(rating_a, rating_b))
))

It looks like you defined the function for Fargo odds. I didn't know you could do that in Excel.
 
And here's a Python version using SciPy. There's a cumulative distribution function, so I can avoid the looping (ARRAYFORMULA w/ SEQUENCE) that I had to do in the spreadsheet. Both cumulative and summed distribution work out the same as you'd expect.


Python:
from argparse import ArgumentParser

import scipy as sp

def fargorate_game_win_probability(rating_a, rating_b):
    return 1 / (1 + 2**((rating_b - rating_a)/100))


def race_odds_cdf(n: int, m: int, p: float) -> float:
    '''
    Args:
        n (int): number of successes needed for player A
        m (int): number of successes needed for player B
        p (float): probability of player A succeeding in a single trial
    '''
    return sp.stats.nbinom.cdf(k=m, n=n, p=p, loc=1)


def race_odds_summed_pmf(n: int, m: int, p: float) -> float:
    '''
    Args:
        n (int): number of successes needed for player A
        m (int): number of successes needed for player B
        p (float): probability of player A succeeding in a single trial
    '''
    return sum(sp.stats.nbinom.pmf(k=i, n=n, p=p) for i in range(m))


def main():
    argument_parser = ArgumentParser()
    argument_parser.add_argument('--games_a', type=int, required=True, help="number of games A needs to win")
    argument_parser.add_argument('--games_b', type=int, required=True, help="number of games B needs to win")
    argument_parser.add_argument('--rating_a', type=float, default=0.0, help="Player A's rating")
    argument_parser.add_argument('--rating_b', type=float, default=0.0, help="Player B's rating")
    args = argument_parser.parse_args()

    game_odds = fargorate_game_win_probability(args.rating_a, args.rating_b)
    print(f"game_odds:{game_odds:.5f}")

    race_odds = race_odds_cdf(args.games_a, args.games_b, game_odds)
    print(f"race_odds:{race_odds:.5f}")

    race_odds2 = race_odds_summed_pmf(args.games_a, args.games_b, game_odds)
    print(f"race_odds2:{race_odds2:.5f}")

if __name__ == '__main__':
    main()
 
Back
Top