http://www.perlmonks.org?node_id=195889

I've always been a nut about predicting NFL games. Since I was a kid I've been working this system on paper. Well not for the last couple of year.

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 (%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 = '  '; }

}

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);

#-----------------------------------------------------------