System is this. Each team has an offense and defense power rating. Say the Niners have OFF=44 and DEF=27 and the Giants have OFF=40 and DEF=20. Each teams predicted score is just its OFF - opponents DEF. The home team gets a 3 point bonus. So:
Niners = 44 - 20 = 24
Giants = 40 - 27 + 3 = 16
Niners only scored 16 so their OFF gets adjusted down and Giants DEF gets adjusted up by (24 - 16) / 7 = 1.1428.
Giants only scored 13 so their OFF goes down, Niners DEF goes up by (16 - 13) / 7 = .4285
7 is just a fudge factor to keep ratings from changing too fast because of upsets. 3 home field points is also fudge. After trying many values, it seemed these gave the best result. That was a while ago, maybe they should be checked again.
PickemFoo
Season beginnings are always tricky but based on two years of scores, my picks:
FortyNiners 16 (24) Giants 13 (16) Jets 00 (22) Bills 00 (18) Ravens 00 (24) Panthers 00 (12) Vikings 00 (12) Bears 00 (26) Chargers 00 (14) Bengals 00 (18) Chiefs 00 (22) Browns 00 (21) Falcons 00 (15) Packers 00 (30) Colts 00 (24) Jaguars 00 (31) Lions 00 (12) Dolphins 00 (23) Eagles 00 (28) Titans 00 (19) Cardinals 00 (14) Redskins 00 (21) Rams 00 (30) Broncos 00 (18) Seahawks 00 (19) Raiders 00 (23) Saints 00 (16) Buccaneers 00 (32) Cowboys 00 (15) Texans 00 (23) Steelers 00 (16) Patriots 00 (19)
#!/usr/bin/perl use strict; my $SCORES = 'scores.txt'; # Format of scores file is: # visitors score hometeam score # one score per line # for games not yet played, scores are 0 # Like: Patriots 20 Rams 17 my $OFF = 42; # Default offense rating my $DEF = 21; # Default defense rating my $HOME = 3; # Home field advantage my $ADJUST = 7; # Adjustment factor my (%nfl, $wins, $loss, $length); if (!open (IN, $SCORES)) { printf STDERR "\nError opening file: $SCORES\n$!\n\n"; exit; } while (chomp (my $line = <IN>)) { if ($line =~ m{__END__}) { last; } if ($line =~ m{^\s*$}) { next; } if ($line =~ m{^\s*#}) { print "$line\n"; next; } if ($line =~ m{(\S.*\S)\s+(\d+)\s+(\S.*\S)\s+(\d+)}) { my ($away, $anum, $home, $hnum) = ($1, $2, $3, $4); if (!defined($nfl{$away})) { $nfl{$away} = { off => $OFF, def => $DEF}; if (length($away) > $length) { $length = length($away); } } if (!defined($nfl{$home})) { $nfl{$home} = { off => $OFF, def => $DEF}; if (length($home) > $length) { $length = length($home); } } my $atry = int($nfl{$away}->{off} - $nfl{$home}->{def}); my $htry = int($nfl{$home}->{off} - $nfl{$away}->{def} + $HOM +E); if ($atry == $htry) { $htry++; } my ($actual, $guess, $result); if ($anum != 0 || $hnum != 0) { $actual = $hnum - $anum; $guess = $htry - $atry; if ($actual * $guess > 0) { $wins++; $result = '++'; } else { $loss++; $result = ' '; } adjust($nfl{$away}, $nfl{$home}, $anum, $atry); adjust($nfl{$home}, $nfl{$away}, $hnum, $htry); } printf (STDOUT "%-*.*s %2.2d (%2.2d) \n", $length, $length, $away, $anum, $atry); printf (STDOUT "%-*.*s %2.2d (%2.2d) ", $length, $length, $home, $hnum, $htry); printf (STDOUT "%+2.2d (%+2.2d) %s\n\n", $actual, $guess, $result); } else { print STDERR "Unknown format:$line\n"; } } for my $team (sort { $b->[0] <=> $a->[0] } map { [ $nfl{$_}->{off} + $nfl{$_}->{def}, $_]; } keys(%nfl)) { $team = $team->[1]; printf(STDOUT "%-*.*s %4.1f %4.1f %4.1f\n", $length, $length, $team, $nfl{$team}->{off} + $nfl{$team}->{def}, $nfl{$team}->{off}, $nfl{$team}->{def}) } printf (STDOUT "\nW:$wins L:$loss %5.2f%\n", ($wins / ($wins + $loss)) * 100); #----------------------------------------------------------- sub adjust { my ($team, $oppo, $score, $guess) = @_; my $adjust = ($score - $guess) / $ADJUST; $team->{off} += $adjust; $oppo->{def} -= $adjust; }