Meaningful games in November

Mea culpa in not realizing last week that SDSU’s “home” game was actually played in Carson. That’s (partially) why the line didn’t reflect a true home field advantage for SDSU and indeed it moved more toward Fresno at game time and Fresno did win convincingly. Gambling advice is for entertainment only! Fresno and San Diego getting together for a neutral game in Carson does have a “California is the universe” aesthetic that suits this blog.

$ python3 ./mcc_schedule.py --verbose
San José State 7 at USC 30 on Sep 04, 2021
Stanford 42 at USC 28 on Sep 11, 2021
Fresno State 40 at UCLA 37 on Sep 18, 2021
UCLA 35 at Stanford 24 on Sep 25, 2021
San Diego State 19 at San José State 13 on Oct 15, 2021
Fresno State 30 at San Diego State 20 on Oct 30, 2021
USC at California on Nov 12, 2021
California at Stanford on Nov 19, 2021
UCLA at USC on Nov 19, 2021
Fresno State at San José State on Nov 24, 2021
California at UCLA on Nov 26, 2021

Fresno State            2-0
San Diego State         1-1
UCLA                    1-1
Stanford                1-1
USC                     1-1
San José State          0-2
2021, 11, ,

At this point in time every remaining game is still relevant to the final Cup winner. Only Cal truly controls their own destiny: If they go 3-0 and beat UCLA by more than 3 points, they win. Fresno State needs to beat San Jose State and hope Cal loses at least one. UCLA and USC both have a chance if they win out and Fresno State loses to San Jose State.

Were that Fresno v. SJS game played this weekend Fresno would be more than a touchdown favorite. As it stands now their title chances are definitely over 50%.

As I’ve noted before a 538-style simulation of the rest of the season would be a nice feature. Building this out from a results-based dataset is an interesting challenge. Right now unplayed games are simply passed over in build_standings:

def build_standings(mcc_games) :
    standings = {}
    for mcc_game_id in mcc_games :
        cur_mcc_game = mcc_games[mcc_game_id]
        if (cur_mcc_game.away_points is None or cur_mcc_game.home_points is None) :
            pass

In order to handle hypothetical results you have to have some harness that fills in possible results in lots of different combinations. Two basic approaches come to mind: walk it through in a traversal that ensures every possible combo is achieved (essentially treating each outcome like a 50/50 coinflip.) Or apply probabilistic random chance to eat outcome using the team’s known strength but run enough trials that you get some fuzz. (I believe this would count as unsophisticated Monte Carlo simulation.)

First try at this I would say: streamline standings/tiebreak/winner code so that it can be run in a loop on a large set without generating a lot of noise and the results can be easily built into a table, instead of geared to a line by line printout of actual results, as they are now. Then build a recursive traversal harness that pumps through the entire dataset first making home teams the winner and then at each node trying again after return with the road team as winner. I have to think about that but that’s the fun part. The ugly part is refactoring the code enough so that the games abstraction is clear enough to seamlessly be used in the actual or hypothetical, and then building enough of an output UI that the results aren’t just a wall of text.

Baseline first pass at the output there is probably just a table of the teams and the percent of the time they win the title in an every-outcome traversal and then in a Monte Carlo. Monte Carlo is probably a little easier to code once you have the power ranking weightings set, because you’re just looping through remaining games and firing the random number at each one.