/* C PROGRAM TO CALCULATE SUM ERROR SQUARED FOR JWB AND PERFORMANCE RATINGS */ #include #include #include struct TEAM { char *name; /* team name */ float rating; float JWB; struct TEAM *link; /* link to next team */ } *team_list = NULL; struct NAME { char *name; /* possible team name variant */ char *official; /* official team name */ struct NAME *link; /* link to next possible name */ } *name_list = NULL; char save_line[80]; /* orginal input line for error message */ long int ngames; /* number of games */ char date[80]; /* a date line from games */ float PerfSumErrSq = 0.0; float JWBsumErrSq = 0.0; float Perf2SumErrSq = 0.0; float JWB2sumErrSq = 0.0; float TwoOverPi; void syntax_error() { printf(" Sorry, I don't understand: %s",save_line); printf(" (Input line for game number %ld)\n",ngames+1); exit(1); } char *malloc(); char *mallocck(size) int size; { char *result; if(size <= 0 || size > 1000) { printf("Bad memory allocation size requested: %d\n",size); exit(1); } result = malloc((long) size); if(!result) {printf("***Memory Overflow***\n"); exit(1);} return result; } void read_names() { FILE *namesfp; char line[256]; /* input line */ char *cp, *cp2, *official; struct NAME *namep; namesfp = fopen("../../names.txt","r"); if(!namesfp) {printf("Can't open names.txt\n"); exit(1);} printf("Reading names.txt...\n"); /* read input file */ fgets(line, sizeof line, namesfp); while(!feof(namesfp)) { official = 0; for(cp = line;cp2 = strchr(cp,'|');cp = cp2+1) { *cp2 = 0; namep = (struct NAME *) mallocck(sizeof(struct NAME)); namep->name = mallocck(strlen(cp)+1); strcpy(namep->name,cp); if(!official) official = namep->name; namep->official = official; namep->link = name_list; name_list = namep; } fgets(line, sizeof line, namesfp); } fclose(namesfp); } int strcasecmp(s1,s2) register char *s1, *s2; { /* case insensative strcmp */ register char ch1, ch2; do { ch1 = toupper(*s1++); ch2 = toupper(*s2++); } while(ch1 == ch2 && ch1); return (ch1 - ch2); } struct TEAM *find_team(name) char *name; { struct TEAM *teamp; struct NAME *namep; /* look up official name */ for(namep=name_list; namep && strcasecmp(name,namep->name); namep=namep->link); if(!namep) { /* new name--not found in names.txt */ printf("Team name not found in names.txt: %s\n",name); namep = (struct NAME *) mallocck(sizeof(struct NAME)); namep->name = mallocck(strlen(name)+1); strcpy(namep->name,name); namep->official = namep->name; namep->link = name_list; name_list = namep; } name = namep->official; /* look for a team by this name */ for(teamp=team_list; teamp && strcmp(name,teamp->name); teamp=teamp->link); if(!teamp) { teamp = (struct TEAM *) mallocck(sizeof(struct TEAM)); teamp->name = name; teamp->rating = 500.0; teamp->JWB = 500.0; teamp->link = team_list; team_list = teamp; } return teamp; } void read_JWB() { FILE *fp; char string[80],*name,*cp; float rating; int i; name = string+4; fp = fopen("JWB.txt","r"); if(fp) { printf("Reading JWB.txt...\n"); do { fgets(string,80,fp); } while(strncmp(string," 1 ",4) && !feof(fp)); do { i = sscanf(string+26,"%6f",&rating); if(i == 1) { cp = name+20; while(*cp == ' ' && cp > name) *cp-- = 0; find_team(name)->JWB = rating; } fgets(string,80,fp); } while(i == 1 && strlen(string) >= 32 && !feof(fp)); } fclose(fp); } void read_ratings() { FILE *fp; char string[80],name[18],*cp; float rating; int i; fp = fopen("../../byname.txt","r"); if(fp) { printf("Reading byname.txt...\n"); fgets(string,80,fp); fgets(string,80,fp); do { fgets(name,18,fp); i = fscanf(fp,"%*2d%*3d%*3d%11f\n",&rating); if(i == 1) { cp = name+16; while(*cp == ' ' && cp > name) *cp-- = 0; find_team(name)->rating = rating; } } while(i == 1); } fclose(fp); } void add_game(teamp, score1, opponentp, score2) struct TEAM *teamp, *opponentp; short int score1, score2; { float PerfEstimate, JWBestimate, Actual; float Perf2Estimate, JWB2estimate; if(teamp->JWB < 500.0 && opponentp->JWB < 500.0) { PerfEstimate = (teamp->rating - opponentp->rating)/100.0; JWBestimate = teamp->JWB - opponentp->JWB; Perf2Estimate = TwoOverPi*atan((double) PerfEstimate* (1.80 + 4.55*PerfEstimate*PerfEstimate)); JWB2estimate = TwoOverPi*atan((double) JWBestimate* (1.80 + 4.55*JWBestimate*JWBestimate)); if(PerfEstimate > 1.0) PerfEstimate = 1.0; if(PerfEstimate < -1.0) PerfEstimate = -1.0; if( JWBestimate > 1.0) JWBestimate = 1.0; if( JWBestimate < -1.0) JWBestimate = -1.0; if(score1 > score2) Actual = 1.0; else Actual = 0.0; PerfSumErrSq += (PerfEstimate-Actual)*(PerfEstimate-Actual); JWBsumErrSq += ( JWBestimate-Actual)*( JWBestimate-Actual); Perf2SumErrSq += (Perf2Estimate-Actual)*(Perf2Estimate-Actual); JWB2sumErrSq += ( JWB2estimate-Actual)*( JWB2estimate-Actual); } } void read_games() { short int bowl; /* set for bowl games */ char *name; /* start of name of team on input line */ short int score[2]; /* scores for current game */ char line[80]; /* input line */ char ch, ch2; /* a character from the input line */ short int which; /* 0 or 1 for which team in current game */ short int number; /* used to gather a score */ char *cp, *cp2; /* places in input line */ struct TEAM *pair[2]; FILE *gamesfp,*fp; gamesfp = fopen("../../games.txt","r"); if(!gamesfp) {printf("Can't open games.txt\n"); exit(1);} printf("Reading games.txt...\n"); bowl = 0; ngames = 0; /* read input file */ fgets(line, sizeof line, gamesfp); while(!feof(gamesfp)) { strcpy(save_line,line); if(!strncmp(line,"=====",5)) { bowl = 1; /* bowl games count double */ } else { /* parse input line */ cp = line-1; for(which=0; which<=1; which++) { while((ch = *++cp) && ch <= ' '); /* bypass leading blanks */ /* check for a date line or blank line */ if(!ch || (ch >= '0' && ch <= '9')) { if(ch) strncpy(date,cp,79); goto skip; } name = cp; /* start of the name */ do { while((ch = *++cp) > ' '); /* find ending blank */ if(! *cp) goto skip; /* check for header line */ cp2 = cp; /* possible end-of-name location */ while((ch = *++cp) && ch <= ' '); /* find non-blank */ if(!ch) goto skip; /* if it's not a digit, the name continues */ } while(ch < '0' || ch > '9'); *cp2 = 0; /* terminate the team name */ number = 0; /* gather up the score */ do { number = 10*number + ch - '0'; ch = *++cp; } while(ch >= '0' && ch <= '9'); if(ch == ',') ch = *++cp; if(ch > ' ') syntax_error(); score[which] = number; /* store the score */ pair[which] = find_team(name); } if(score[0] >= score[1]) add_game(pair[0], score[0], pair[1], score[1]); else add_game(pair[1], score[1], pair[0], score[0]); ngames++; } goto read; skip: if(which) syntax_error(); read: fgets(line, sizeof line, gamesfp); } fclose(gamesfp); printf("%ld games\n",ngames); } write_error() { printf("Sum Err Sq = %f (Perf) %f (JWB)\n %f (Perf2) %f (JWB2)\n", PerfSumErrSq,JWBsumErrSq,Perf2SumErrSq,JWB2sumErrSq); } int main() { TwoOverPi = 0.5/atan((double) 1.0); printf("%f\n",TwoOverPi); read_names(); read_ratings(); read_JWB(); read_games(); write_error(); return 0; }