#include /* Golf Statistics Program * Copyright (C) Warren Montgomery (1996) */ /* No warrantee of accuracy is offered, use at your own risk */ /* This program allows you to log rounds on your favorite courses * and automatically computes statistics on your play. Input is * taken from standard in, output produced on standard out (sorry, * nothing fancy, just a classic pipeline utility. The input file * contains lines describing courses and lines describing rounds in * any order (except that a course description must preceed the * first round played on it to compute course statistics. The * course description lines begin with '%', followed by a unique * idenitfier for the course (letters and numbers, no spaces", * followed by a colon, followed by a listing of par on each hole: * %RH:4,4,5,3,4,5,3,4,4,3,3,4,4,4,4,5,5,4 *The round descriptions each begin with a line starting with a '#', *a date, and the course identifier: * #3/30 RH *One line is entered for each hole played. Each has a listing of shots, separated by commas. For each shot other than a putt, the listing is a club name: 1W, 3W, 5W -- woods 2I-9I, -- irons W -- wedge (use for all wedges, all shots) S -- sand (use for greenside shots only) C -- chip X -- penalty R -- Recovery (use for any abnormal shot made with a club, including layups, punches, partial shots, etc) Followed by any number of letters indicating what happened: T -- topped F -- fat r -- a little right R -- way right l -- a little left L -- way left h -- hit the fairway (use on first shot only) m -- missed the fairway (use on first shot only. If neither h or m is used on the first shot it assumes the hole is not to be included in fairway statistics (e.g. par 3's) For putts, use the letter "P", and the number of feet (1-99). Examples: 1Wh,6IFr,W,P8,P1 1Wtm,3WFR,5IR,X,9I,Ct,P15,P2 5I,P50,P3 Invoke the program with the description file as standard input. To limit results to rounds occurring on or after a date, give the date (same format as in the description file) as argument to the program (the date must match a date on which a round was played). The program produces the following For each club, total shots, percentage of all shots hit with the club, percentage of shots hitting the green and average distance from the pin. Average number of shots required to hole out (including the one made with the club and any afterwards), and the percentage of up and down (holed out on the shot following the one made with the club). A matrix is shown with percentages of shots left, right, topped, and fat witht he club (ideal is 100% in the middle). Percentages of greens in regulation and fairways hit (only counting holes you designated a hit or miss on) are shown. For putts, number, percentage sunk, and average number of putts to hole out are shown in each 5 foot range, as well as the average putts per hole and puts per round, and the percentage of strokes made with the putter. Numbers and percentages of eagles, birdies, pars, bogies, etc are shown. For each course it shows the average score on each hole, the ringer (lowest) on each hole, as well as average total and ringer total. */ /* 0 - straight 1 - draw 2 - hook 3 - fade 4 - slice +5 - top +10 - fat 0 - sand 1-5 - woods 6-14 irons */ #define WOODS 0 #define SAND 0 #define RECOVER 2 #define PENALTY 16 #define CHIP 15 #define WEDGE 14 #define IRONS 4 #define NCLUBS IRONS+13 #define NRESULT 16 #define NHOLES 18 #define NCOURSE 50 #define CNAME 10 char courses[NCOURSE][CNAME]; int ncourse = 0; char cpar[NCOURSE][NHOLES]; char ringer[NCOURSE][NHOLES]; char nplay[NCOURSE][NHOLES]; int ringshot[NCOURSE][NHOLES]; int results[NCLUBS] [NRESULT]; char *clubnames[NCLUBS] = {"Sand","Driver","Recovery","Three Wood","","Five Wood", "Two Iron","Three Iron","Four Iron","Five Iron","Six Iron", "Seven Iron","Eight Iron","Nine Iron","Wedge","Chip","Penalty"}; int ongreen[NCLUBS]; int pdist[NCLUBS]; int nputs[21]; int nsunk[21]; int pshots[21]; int cshots[NCLUBS]; int csaves[NCLUBS]; int psaves[21]; int *slist[20]; int *vlist[20]; int hscore[10]; int pr(x,y) int x,y; { return((x*100+y/2)/y); } main(argc,argv) char **argv; { char buf[100]; char *bp; int club; int result; int i,j; int pd; int **sptr = slist; int **vptr = vlist; int holes,tputs; int hole,score; int cscore; int gir,fhit,fmiss; int course; int process; float tshots,ashots; club = -1; pd = 100; score=0; tputs = holes = 0; tshots=cscore=0; gir=fhit=fmiss=0; if (argc>1) process=0; else process = 1; while(gets(buf)) { if (score) { tshots += score; cscore+= score; hscore[score+2-cpar[course][hole]]++; nplay[course][hole]++; ringshot[course][hole]+= score; if(ringer[course][hole]==0 || score1 && (strncmp(argv[1],buf+1,strlen(argv[1])) == 0)) process=1; hole= -1; for (i=1;buf[i]&& buf[i]!=' ';i++); if (buf[i]) i++; if (buf[i] == '9') { hole+=9; i++; } for (course=0;course1 && (strncmp(argv[1],buf+1,strlen(argv[1])) == 0)) process=1; for (j=1;buf[j]&& buf[j]!=' ';j++); if (buf[j]) j++; if (buf[j] == '9') { hole+=9; j++; } for (i = j; buf[i] && buf[i]!= ':'; i++); buf[i] = 0; for (course=0;course='0'&&buf[i]<='1') { score=10*score+buf[i++]-'0'; } if (buf[i]) i++; tshots += score; cscore+= score; hscore[score+2-cpar[course][hole]]++; nplay[course][hole]++; ringshot[course][hole]+= score; if(ringer[course][hole]==0 || score= 0) ongreen[club]++; else nsunk[pd/5]++; pd = 100; i = 1; while (sptr > slist) { --sptr; (**sptr) += (i++); } if (vptr>vlist) { --vptr; (**vptr)++; if (vptr > vlist) { --vptr; (**vptr)++; vptr=vlist; } } holes++; hole++; club = -1; bp = buf; while (*bp != '\000') { if (*bp == ',') bp++; if (*bp >= '0' && *bp <= '9') { club = *bp++ - '0'; if (*bp == 'I'|| *bp == 'i') club = club + IRONS; } else if (*bp == 'S'|| *bp== 's') club = SAND; else if (*bp == 'W' || *bp == 'w') club = WEDGE; else if (*bp == 'C' || *bp == 'c') club = CHIP; else if (*bp == 'R' || *bp == 'r') club = RECOVER; else if (*bp == 'X' || *bp == 'x') club = PENALTY; else if (*bp == 'P'|| *bp == 'p' ){ if (cpar[course][hole]-score==2) gir++; score++; pd = 0; bp++; while (*bp != ',' && *bp != '\000') { if (*bp < '0' || *bp > '9') printf ("Bad putt: %s\n",buf); pd = pd*10+(*bp-'0'); bp++; } nputs[pd/5]++; (*sptr) = (&(pshots[pd/5])); sptr++; (*vptr) = (&(psaves[pd/5])); vptr++; if (club >= 0) { ongreen[club]++; pdist[club] += pd; club = -1; } continue; } else printf ("unknown club: %s\n",buf); result = 0; score++; bp++; *(sptr) = (&(cshots[club])); sptr++; *(vptr) = (&(csaves[club])); vptr++; while (*bp != ',' && *bp != '\000') { switch (*bp++) { case 'R': result += 4; break; case 'r': result += 3; break; case 'L': result += 2; break; case 'l': result += 1; break; case 't': case 'T': result += 5; break; case 'f': case 'F': result += 10; break; case 'h': case 'H': fhit++; break; case 'm': case 'M': fmiss++; break; } } if (result >= NRESULT) printf ("Bad club: %s\n",buf); results[club][result]++; } } if (score) { tshots += score; cscore+= score; hscore[score+2-cpar[course][hole]]++; nplay[course][hole]++; ringshot[course][hole]+= score; if(ringer[course][hole]==0 || score= 0) ongreen[club]++; else nsunk[pd/5]++; i = 1; while (sptr > slist) { --sptr; (**sptr) += (i++); } if (vptr>vlist) { --vptr; (**vptr)++; if (vptr > vlist) { --vptr; (**vptr)++; vptr=vlist; } } for (club = 0; club < NCLUBS; club++) { for (i = 0, result = 0; i < NRESULT; i++) result += results[club][i]; if (result) { if (ongreen[club]) pdist[club]/= ongreen[club]; printf (" %s: %4d shots(%4.1f%%), %3d%% on green (%2d feet), %3.2f to sink, %2d%% up/down\n", clubnames[club],result,(result*100.0)/tshots,pr(ongreen[club],result),pdist[club],((float)cshots[club])/result,pr(csaves[club],result)); printf ("%3d %3d %3d %3d %3d\n",pr(results[club][7],result),pr(results[club][6],result),pr(results[club][5],result),pr(results[club][8],result),pr(results[club][9],result)); printf ("%3d %3d %3d %3d %3d\n",pr(results[club][2],result),pr(results[club][1],result),pr(results[club][0],result),pr(results[club][3],result),pr(results[club][4],result)); printf ("%3d %3d %3d %3d %3d\n\n",pr(results[club][12],result),pr(results[club][11],result),pr(results[club][10],result),pr(results[club][13],result),pr(results[club][14],result)); } } printf ("%2d%% Greens in regulation\n",pr(gir,holes)); if (fmiss+fhit==0) fmiss++; printf ("%2d%% Fairways hit\n",pr(fhit,(fhit+fmiss))); printf ("Putts\n\n"); for (i = 0; i < 20; i++) { if (nputs[i]) printf ("%2d-%2d feet: %4d putts, %2d%%sunk, %3.2f avg putts\n", i*5,(i+1)*5,nputs[i],pr(nsunk[i],nputs[i]),((float) pshots[i])/nputs[i]); tputs += nputs[i]; } printf ("%3.2f putts/hole, %4.2f putts/round (%4.1f%%)\n",((float)tputs)/holes,18*((float)tputs)/holes,((float)tputs)*100.0/tshots); for (i=0;i<10;i++) { printf("par+ %d %4d (%2d%%)\n", i-2,hscore[i],pr(hscore[i],holes)); } for (course=0;course