blob: 9a92fecb3d528a9751034573e1cf4aa6e6ed7fab [file] [log] [blame]
/* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
/* Permission to use this code is granted as long as the copyright */
/* notice remains in place. */
#include <stdio.h>
#include <stdlib.h>
#include "definitions.h"
#include "stats.h"
TEAMS_STATS common_games;
TEAM common_teams[NUM_TEAMS+1];
extern void display_split(FILE *stream,TEAM *teams,int split,int num);
BOOL matches_any_team(int num,TEAM code)
{
int i;
for (i=1;i<=num;i++)
if (common_teams[i] == code)
return i;
return NO;
}
void common(int num)
{
TEAM tmp_team,temp;
int week,game,i;
int in_common[NUM_TEAMS+1];
TEAM team1,team2;
int site1,site2;
for (tmp_team=1;tmp_team<=NUM_TEAMS; tmp_team++)
in_common[tmp_team] = 0;
for (temp=1;temp<=num;temp++)
for (tmp_team=1;tmp_team<=NUM_TEAMS; tmp_team++)
in_common[tmp_team] += team_plays[common_teams[temp]][tmp_team];
for (temp=1;temp<=NUM_TEAMS;temp++) {
if (in_common[temp] < num)
in_common[temp] = NO;
else in_common[temp] = YES;
}
/* stats */
for (team1=1;team1<=NUM_TEAMS; team1++) {
common_games[team1].wins = common_games[team1].loses = 0;
common_games[team1].ties = 0;
common_games[team1].points_for = common_games[team1].points_against = 0;
}
for (week = 1; week <= num_games;week++)
for (game = 1;game<=NUM_TEAMS/2; game++)
for (i = 1; i<=2; i++) {
if ( i == 1) {
team1 = sched[week][game][HOST]; site1 = HOST;
team2 = sched[week][game][VISITOR]; site2 = VISITOR;
} else {
team1 = sched[week][game][VISITOR]; site1 = VISITOR;
team2 = sched[week][game][HOST]; site2 = HOST;
}
if ( team1 != 0 && in_common[team1] )
if (matches_any_team(num,team2))
if (scores[week][game][HOST] >= 0 &&
scores[week][game][VISITOR] >=0) {
if (scores[week][game][site1] < scores[week][game][site2])
common_games[team2].wins ++;
else if (scores[week][game][site1] > scores[week][game][site2])
common_games[team2].loses ++;
else common_games[team2].ties ++;
} else common_games[team2].points_for ++;
}
for (team1=1;team1<=28;team1++)
if (common_games[team1].wins + common_games[team1].loses +
common_games[team1].ties + common_games[team1].points_for < 4)
common_games[team1].wins = -1;
}
int head_to_head_sweap(TEAM *teams,int num)
{
TEAM temp1,temp2;
BOOL sweap_win=YES,sweap_lose=YES;
for (temp1=0;temp1<num;temp1++) {
sweap_win = sweap_lose = YES;
for (temp2=0;temp2<num;temp2++)
if (temp1 != temp2) {
if (h_to_h_stats[teams[temp1]][teams[temp2]].ties == 0 &&
h_to_h_stats[teams[temp1]][teams[temp2]].wins == 0 &&
h_to_h_stats[teams[temp1]][teams[temp2]].loses == 0)
sweap_win = sweap_lose = NO;
if (h_to_h_stats[teams[temp1]][teams[temp2]].ties != 0 )
sweap_win = sweap_lose = NO;
if (h_to_h_stats[teams[temp1]][teams[temp2]].loses != 0)
sweap_win = NO;
if (h_to_h_stats[teams[temp1]][teams[temp2]].wins != 0)
sweap_lose = NO;
}
if (sweap_win) {
TEAM tmp_team;
tmp_team = teams[0];
teams[0] = teams[temp1];
teams[temp1] = tmp_team;
return 1;
}
if (sweap_lose) {
TEAM tmp_team;
tmp_team = teams[num-1];
teams[num-1] = teams[temp1];
teams[temp1] = tmp_team;
return num-1;
}
}
return num;
}
void split_around(TEAM *teams,int num_best,int num,double *pct,double best_pct)
{
int t1,t2;
int i;
TEAM temp[NUM_TEAMS];
t1 = t2 = 0;
for (i=0;i<num;i++)
if (pct[i] == best_pct) {
temp[t1] = teams[i];
t1 ++;
} else {
temp[t2+num_best] = teams[i];
t2 ++;
}
for (i=0;i<num;i++)
teams[i] = temp[i];
}
int head_to_head(TEAM *teams,int num)
{
int i,j;
double best_pct,pct[MAX_TEAMS_DIV];
int num_best;
int wins,loses,ties;
if (num > MAX_TEAMS_DIV) {
(void) printf("ERROR in head_to_head (common.c). Assumption violated.\n");
exit(1);
}
best_pct = 0.0;
num_best = 0;
for (i=0;i<num;i++) {
wins = loses = ties = 0;
for (j=0;j<num;j++)
if (i != j) {
wins += h_to_h_stats[teams[i]][teams[j]].wins;
loses += h_to_h_stats[teams[i]][teams[j]].loses;
ties += h_to_h_stats[teams[i]][teams[j]].ties;
}
pct[i] = (wins+loses+ties == 0 ? 0.0 :
((double) wins + 0.5 * ties) / ((double) (wins + loses + ties)));
if (pct[i] > best_pct) {
best_pct = pct[i];
num_best = 0;
}
if (pct[i] == best_pct) num_best++;
}
split_around(teams,num_best,num,pct,best_pct);
return num_best;
}
/* */
int break_common(TEAM *teams,int num)
{
int i;
double best_pct,pct[NUM_TEAMS];
int num_best;
if (num > NUM_TEAMS) {
(void) printf("ERROR in break_common (common.c). Assumption violated.\n");
exit(1);
}
for (i=0;i<num;i++)
common_teams[i+1] = teams[i];
common(num);
for (i=0;i<num;i++) {
if (common_games[teams[i]].wins == -1) return num;
}
best_pct = 0.0;
num_best = 0;
for (i=0;i<num;i++) {
pct[i] = WIN_PCT(common_games[teams[i]]);
if (pct[i] > best_pct) {
best_pct = pct[i];
num_best = 0;
}
if (pct[i] == best_pct) num_best++;
}
split_around(teams,num_best,num,pct,best_pct);
return num_best;
}
/* */
int div_conf_rec(TEAM *teams,int num,int which)
{
int i;
double best_pct,pct[NUM_TEAMS];
int num_best;
if (num > NUM_TEAMS) {
(void) printf("ERROR in div_conf_rec (common.c). Assumption violated.\n");
exit(1);
}
best_pct = 0.0;
num_best = 0;
for (i=0;i<num;i++) {
if (which == DIVISION)
pct[i] = WIN_PCT(team_info_wi_div[teams[i]]);
else pct[i] = WIN_PCT(team_info_wi_conf[teams[i]]);
if (pct[i] > best_pct) {
best_pct = pct[i];
num_best = 0;
}
if (pct[i] == best_pct) num_best++;
}
split_around(teams,num_best,num,pct,best_pct);
return num_best;
}
int break_net_points(TEAM *teams,int num,int which)
{
int i;
double best_pct,pct[NUM_TEAMS];
int num_best;
if (num > NUM_TEAMS) {
(void) printf("ERROR in break_net_points (common.c). Assumption violated.\n");
exit(1);
}
best_pct = -10000.0;
num_best = 0;
for (i=0;i<num;i++) {
if (which == DIVISION)
pct[i] = (double) NET_POINTS(team_info_wi_div,teams[i]);
else if (which == CONFERENCE)
pct[i] = (double) NET_POINTS(team_info_wi_conf,teams[i]);
else pct[i] = (double) NET_POINTS(team_info,teams[i]);
if (pct[i] > best_pct) {
best_pct = pct[i];
num_best = 0;
}
if (pct[i] == best_pct) num_best++;
}
split_around(teams,num_best,num,pct,best_pct);
return num_best;
}
void break_a_tie(TEAM *teams,int num,BOOL display)
{
BOOL ALL_SAME_DIV;
int value,i;
if (num <= 1) return;
ALL_SAME_DIV = YES;
for (i=1;i<num;i++)
ALL_SAME_DIV = ALL_SAME_DIV && (divisions[teams[0]][DIVISION] ==
divisions[teams[i]][DIVISION]);
if (display) {
(void) printf("------ Break a tie (all same div: %d) -------\n",
ALL_SAME_DIV);
display_split(stdout,teams,num,num);
}
if (ALL_SAME_DIV || num == 2) {
value = head_to_head(teams,num);
if (value != num) {
if (display) {
display_split(stdout,teams,value,num);
(void) printf("Split because of head to head record.\n");
}
break_a_tie(teams,value,display);
break_a_tie(&(teams[value]),num-value,display);
return;
}
} else {
value = head_to_head_sweap(teams,num);
if (value != num) {
if (display) {
display_split(stdout,teams,value,num);
(void) printf("Split because of head to head sweap.\n");
}
break_a_tie(teams,value,display);
break_a_tie(&(teams[value]),num-value,display);
return;
}
}
if (ALL_SAME_DIV) {
value = div_conf_rec(teams,num,DIVISION);
if (value != num) {
if (display) {
display_split(stdout,teams,value,num);
(void) printf("Split because of divisional record.\n");
}
break_a_tie(teams,value,display);
break_a_tie(&(teams[value]),num-value,display);
return;
}
}
value = div_conf_rec(teams,num,CONFERENCE);
if (value != num) {
if (display) {
display_split(stdout,teams,value,num);
(void) printf("Split because of conference record.\n");
}
break_a_tie(teams,value,display);
break_a_tie(&(teams[value]),num-value,display);
return;
}
value = break_common(teams,num);
if (value != num) {
if (display) {
display_split(stdout,teams,value,num);
(void) printf("Split because of common game record.\n");
}
break_a_tie(teams,value,display);
break_a_tie(&(teams[value]),num-value,display);
return;
}
if (ALL_SAME_DIV) {
value = break_net_points(teams,num,DIVISION);
if (value != num) {
if (display) {
display_split(stdout,teams,value,num);
(void) printf("Split because of division net points.\n");
}
break_a_tie(teams,value,display);
break_a_tie(&(teams[value]),num-value,display);
return;
}
} else {
value = break_net_points(teams,num,CONFERENCE);
if (value != num) {
if (display) {
display_split(stdout,teams,value,num);
(void) printf("Split because of conference net points.\n");
}
break_a_tie(teams,value,display);
break_a_tie(&(teams[value]),num-value,display);
return;
}
}
value = break_net_points(teams,num,NFL_0);
if (value != num) {
if (display) {
display_split(stdout,teams,value,num);
(void) printf("Split because of net points.\n");
}
break_a_tie(teams,value,display);
break_a_tie(&(teams[value]),num-value,display);
return;
}
if (display)
(void) printf("Ordered by COIN TOSS.\n");
}
void display_split(FILE *stream,TEAM *teams,int split,int num)
{
int i;
for (i=0;i<num;i++) {
(void) fprintf(stream,"%s ",team[teams[i]][FULL_NAME_0]);
if (i==(split-1) && split != num)
(void) fprintf(stream," * ");
}
(void) fprintf(stream,"\n");
}