home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume10 / tourney / part01 / tourney.c < prev   
C/C++ Source or Header  |  1990-03-06  |  19KB  |  854 lines

  1. /***********************************************************************
  2.  * tourney - a curses-based program to keep track of the NCAA Basketball
  3.  *    tournament.
  4.  *
  5.  * Author: Jack Alexander
  6.  *         jack@jimi.cs.unlv.edu
  7.  *
  8.  * (c) 1989, by the author.  Feel free to hack this code up as long as
  9.  *    you don't remove the author's name or the copyright notice.
  10.  *    I will attempt to maintain a current version based on valid
  11.  *    changes sent to me at the above email address.
  12.  *
  13.  *    Please send me any WORTHWHILE changes.
  14.  *      
  15.  * 
  16.  * WARNING:  There is absolutely NO WARRANTY OF ANY KIND associated with
  17.  * this program, even for fitness of purpose.  If you choose to run this
  18.  * software, it is at your own risk.
  19.  *
  20.  */
  21. #include <stdio.h>
  22. #include <curses.h>
  23. #include <fcntl.h>
  24. #include <errno.h>
  25.  
  26. #include "get.h"
  27.  
  28. #define STANDINGS_FILE    "standings"    /* file used to output standings */
  29. #define MASTER_FILE    "#MASTER"    /* file of results */
  30. #define ENTRY_FILE    "players/#ENTRIES"  /* list of people in contest */
  31. #define TEAM_FILE    "teams"     /* Name of the file for list of teams */
  32. #define PLAYER_DIR    "players"    /* Directory for people's picks */
  33. #define PLAYER_FILE    "players/%s"     /* Where to put people's picks */
  34. #define TEAMS        64         /* Number of teams in tournament */
  35. #define ROUNDS        7        /* results levels */
  36. #define NAMESZ        20        /* Length of team names */
  37. #define PATHSZ        14        /* max filename */
  38.  
  39. /* Main menu option values: */
  40. #define MAIN_MENU_NAME    " NCAA Basketball Tournament Tracker "
  41. #define SETUP        1
  42. #define UPDATE        2
  43. #define SHOW_STANDINGS    3
  44. #define EXIT        4
  45.  
  46. /* Setup menu option values: */
  47. #define SETUP_MENU_NAME    " Tournament Setup menu "
  48. #define ENTER_TEAMS    1
  49. #define ENTER_PERSON    2
  50. #define PRINT_PERSON    3
  51. #define REMOVE_PERSON    4
  52. #define RETURN        5
  53.  
  54. int    games[ROUNDS] = { 64, 32, 16, 8, 4, 2, 1 };    /* teams per round */
  55. int    points[ROUNDS] = { 0, 1, 2, 4, 8, 16, 32 };    /* points per round */
  56.  
  57. static    char    *region_name[] = {
  58.     "West", "East", "Midwest", "Southeast"
  59.     };
  60.  
  61. typedef struct menu_list {
  62.     char     entry[50];
  63.     int    value;
  64. };
  65.  
  66. typedef struct    entry {
  67.     char    name[NAMESZ+1];
  68.     unsigned char    round[ROUNDS][TEAMS];
  69. };
  70.  
  71. struct    menu_list mainmenu[EXIT] = {
  72.     "Setup tournament database", SETUP,
  73.     "Edit game results", UPDATE,
  74.     "Show pool standings", SHOW_STANDINGS,
  75.     "QUIT", EXIT,
  76. };
  77.  
  78. struct    menu_list setupmenu[RETURN] = {
  79.     "Edit list of teams in the tournament", ENTER_TEAMS,
  80.     "Enter a person into the pool, or edit their entry", ENTER_PERSON,
  81.     "Create a printable file of a person's entry", PRINT_PERSON,
  82.     "Remove an entry from the tournament", REMOVE_PERSON,
  83.     "RETURN to main menu", RETURN,
  84. };
  85.  
  86. main()
  87. {
  88.     int    done=FALSE;
  89.  
  90.     tourney_init();
  91.     while(!done)
  92.         switch(main_menu()) {
  93.             case SETUP:
  94.                 setup_menu();
  95.                 break;
  96.             case UPDATE:
  97.                 enter_updates();
  98.                 break;
  99.             case SHOW_STANDINGS:
  100.                 show_standings();
  101.                 break;
  102.             case EXIT:
  103.                 cleanup();
  104.                 done=TRUE;
  105.                 break;
  106.         }
  107. }
  108.  
  109. tourney_init()
  110. {
  111.     initscr();
  112. }
  113.  
  114. cleanup()
  115. {
  116.     endwin();
  117. }
  118.  
  119. enter_updates()
  120. {
  121.     struct    entry    tr;
  122.     int    rnd;
  123.     char    title[80];
  124.  
  125.     if(read_entry(MASTER_FILE,&tr,0))
  126.         return;
  127.     init();
  128.     while(1) {
  129.         clear();
  130.         printw("Enter the round that you want to edit.  ESC to abort.");
  131.         printw("\n\nRound: ");
  132.         if(get_num(8,2,1,1,6,&rnd)==GET_ESCAPE) {
  133.             de_init();
  134.             return;
  135.         }
  136.         sprintf(title," Enter the results for round %d ",rnd);
  137.         if(edit_round(title,"The winner was ",rnd,games[rnd],&tr,1)) {
  138.             printw("\n Do you want to save this update (y/n)? ");
  139.             refresh();
  140.             if(getch()=='y')
  141.                 save_entry(&tr);
  142.         }
  143.         else
  144.             save_entry(&tr);
  145.     }
  146. }
  147.  
  148. show_standings()
  149. {
  150.     FILE    *fpin, *fpout, *fopen();
  151.     struct    entry    master, this_guy;
  152.     char    name[NAMESZ+1], errmsg[80], sort[80];
  153.     int    score, i, count=0;
  154.  
  155.     if((fpin=fopen(ENTRY_FILE,"r"))==NULL) {
  156.         terror("ERROR opening entry master file");
  157.         return;
  158.     }
  159.     if((fpout=fopen(STANDINGS_FILE,"w"))==NULL) {
  160.         terror("ERROR opening standings output file");
  161.         return;
  162.     }
  163.     if(read_entry(MASTER_FILE,&master,0)) {
  164.         terror("ERROR opening results file");
  165.         return;
  166.     }
  167.  
  168.     clear();
  169.     printw("Processing entries...");
  170.     move(5,0);
  171.     refresh();
  172.     while(fgets(name,NAMESZ,fpin)!=NULL) {
  173.         for(i=0;i<strlen(name);i++)
  174.             if(name[i]=='\n')
  175.                 name[i]='\0';
  176.         if(read_entry(name,&this_guy,1)) {
  177.             move(5,0);
  178.             continue;
  179.         }
  180.         if((score = calculate_score(&master,&this_guy))<0)
  181.             fprintf(fpout,"*** %-20.20s ***** incomplete entry *****\n",name);
  182.         else
  183.             fprintf(fpout,"%3d %-20.20s\n",score,name);
  184.         count++;
  185.     }
  186.     fclose(fpin);
  187.     fclose(fpout);
  188.  
  189.     if(count>1) {
  190.         sprintf(sort,"/bin/sort %s -o %s",STANDINGS_FILE,STANDINGS_FILE);
  191.         system(sort);
  192.     }
  193.     sprintf(errmsg,"Output is in '%s'",STANDINGS_FILE);
  194.     terror(errmsg);
  195. }
  196.  
  197. calculate_score(master,cur)
  198. struct    entry *master, *cur;
  199. {
  200.     int    i, j, score=0;
  201.  
  202.     for(i=1;i<ROUNDS;i++)
  203.         for(j=0;j<games[i];j++)
  204.             if(cur->round[i][j]==TEAMS+1)
  205.                 return(-1); /* incomplete entry */
  206.             else if(master->round[i][j] == cur->round[i][j])
  207.                 score += points[i];
  208.     return(score);
  209. }
  210.  
  211. setup_menu()
  212. {
  213.     int    rcode;
  214.  
  215.     while(rcode!=RETURN)
  216.         switch(rcode=menu(setupmenu,RETURN,SETUP_MENU_NAME)) {
  217.             case ENTER_TEAMS:
  218.                 enter_teams();
  219.                 break;
  220.             case ENTER_PERSON:
  221.                 enter_picks();
  222.                 break;
  223.             case PRINT_PERSON:
  224.                 print_picks("");
  225.                 break;
  226.             case REMOVE_PERSON:
  227.                 remove_pick();
  228.                 break;
  229.             case RETURN:
  230.                 break;
  231.         }
  232. }
  233.  
  234. main_menu()
  235. {
  236.     return(menu(mainmenu,EXIT,MAIN_MENU_NAME));
  237. }
  238.  
  239. menu(sels,q,name)
  240. struct    menu_list    sels[];
  241. int    q;
  242. char    name[];
  243. {
  244.     int    i;
  245.  
  246.     clear();
  247.     standout();
  248.     printw(name);
  249.     standend();
  250.     printw("\n\n");
  251.     for(i=0;i<q;i++)
  252.         printw("%2d. %s\n",i+1,sels[i].entry);
  253.     for(i=0;i<1 || i>q;) {
  254.         move(q+4,0);
  255.         printw("Which ?");
  256.         refresh();
  257.         i=getch()-'0';
  258.     }
  259.     return(sels[i-1].value);
  260. }
  261.  
  262. remove_pick()
  263. {
  264.     char    entrant[PATHSZ+1], filename[80], tmp[80];
  265.     FILE    *fpin, *fpout, *fopen();
  266.     int    i;
  267.  
  268.     init();
  269.     clear();
  270.     printw("Enter the name of the entrant you want to REMOVE\n\n");
  271.     printw("Name: ");
  272.     entrant[0]='\0';
  273.     if(getst(PATHSZ,7,2,entrant,PATHSZ+1,NULL,LETTER_ONLY,NULL)==GET_ESCAPE) {
  274.         de_init();
  275.         return;
  276.     }
  277.     de_init();    /* input is over for this routine */
  278.     for(i=0;i<NAMESZ;i++)
  279.         tmp[i]= (entrant[i]==' ')? '_':entrant[i];
  280.     sprintf(filename,PLAYER_FILE,tmp);
  281.     if(unlink(filename)<0) {
  282.         terror("ERROR unlinking entry file");
  283.         return;
  284.     }
  285.     sprintf(filename,"%stourney.XXXXXX",PLAYER_FILE);
  286.     mktemp(filename);
  287.     if((fpout=fopen(filename,"w"))==NULL) {
  288.         terror("ERROR opening temporary file");
  289.         return;
  290.     }
  291.     if((fpin=fopen(ENTRY_FILE,"r"))==NULL) {
  292.         terror("ERROR opening entry file (list of people)");
  293.         return;
  294.     }
  295.     while(fgets(tmp,NAMESZ,fpin)!=NULL) {
  296.         for(i=strlen(tmp);i>=0;i--)
  297.             if(tmp[i]=='\n') {
  298.                 tmp[i]='\0';
  299.                 break;
  300.             }
  301.         if(strcmp(tmp,entrant))
  302.             fprintf(fpout,"%s\n",tmp);
  303.     }
  304.     fclose(fpout);
  305.     fclose(fpin);
  306.     if(unlink(ENTRY_FILE)<0) {    /* remove old entry file */
  307.         terror("ERROR unlinking old entry file");
  308.         return;
  309.     }
  310.     link(filename,ENTRY_FILE);    /* link to new version */
  311.     unlink(filename);    /* remove temporary file */
  312. }
  313.  
  314. print_picks(name)
  315. char    name[];
  316. {
  317.     char    entrant[NAMESZ+1], errmsg[80], teams[TEAMS][NAMESZ+1],
  318.         filename[PATHSZ+1];
  319.     struct    entry    tr;
  320.     int    i, j;
  321.     FILE    *fp, *fopen();
  322.  
  323.     clear();
  324.     if(read_teams(teams)) {
  325.         terror("ERROR opening teams file");
  326.         return;
  327.     }
  328.     init();
  329.     if(name[0]=='\0') {
  330.         printw("Enter the name of the entrant\n\n");
  331.         printw("Name: ");
  332.         entrant[0]='\0';
  333.         if(getst(PATHSZ,7,2,entrant,PATHSZ+1,NULL,LETTER_ONLY,NULL)==GET_ESCAPE) {
  334.             de_init();
  335.             return;
  336.         }
  337.     }
  338.     else
  339.         strcpy(entrant,name);
  340.  
  341.     if(read_entry(entrant,&tr,1)) {
  342.         sprintf(errmsg,"There is no '%s' on file.",entrant);
  343.         de_init();
  344.         return;
  345.         }
  346.  
  347.     for(i=0;i<ROUNDS;i++)
  348.         for(j=0;j<games[i];j++)
  349.             if(tr.round[i][j] >= TEAMS) {
  350.                 terror("ERROR this entry has not been completly entered");
  351.                 de_init();
  352.                 return;
  353.             }
  354.     clear();
  355.     filename[0]='\0';
  356.     printw("Enter the name of the output file.\n\n");
  357.     printw("File Name: ");
  358.     if(getst(PATHSZ,11,2,filename,PATHSZ+1,NULL,LETTER_ONLY,NULL)==GET_ESCAPE) {
  359.         de_init();
  360.         return;
  361.     }
  362.     de_init();
  363.  
  364.     for(i=0;i<strlen(filename);i++)
  365.         if(filename[i]==' ')
  366.             filename[i]='_';
  367.     if((fp=fopen(filename,"w"))==NULL) {
  368.         sprintf(errmsg,"ERROR opening file '%s', errno=%d",filename,errno);
  369.         terror(errmsg);
  370.         return;
  371.     }
  372.     for(i=0;i<4;i++) {
  373.         fprintf(fp,"==============================================================================\n");
  374.         fprintf(fp,"SELECTIONS FOR ENTRANT: %-12.12s     %12.12s Region            page %d\n",entrant,region_name[i],i+1);
  375.         fprintf(fp,"==============================================================================\n");
  376.         /* This code is a little ugly, but a fancy little
  377.             loop would have been more time consuming that
  378.                 I felt it was worth... */
  379.         fprintf(fp,"%s\n",teams[tr.round[0][16*i]]);
  380.         fprintf(fp,"             %s\n",teams[tr.round[1][8*i]]);
  381.         fprintf(fp,"%s\n",teams[tr.round[0][16*i + 1]]);
  382.         fprintf(fp,"                          %s\n",teams[tr.round[2][4*i]]);
  383.         fprintf(fp,"%s\n",teams[tr.round[0][16*i + 2]]);
  384.         fprintf(fp,"             %s\n",teams[tr.round[1][8*i + 1]]);
  385.         fprintf(fp,"%s\n",teams[tr.round[0][16*i + 3]]);
  386.         fprintf(fp,"                                       %s\n",
  387.             teams[tr.round[3][2*i]]);
  388.         fprintf(fp,"%s\n",teams[tr.round[0][16*i + 4]]);
  389.         fprintf(fp,"             %s\n",teams[tr.round[1][8*i + 2]]);
  390.         fprintf(fp,"%s\n",teams[tr.round[0][16*i + 5]]);
  391.         fprintf(fp,"                          %s\n",teams[tr.round[2][4*i+1]]);
  392.         fprintf(fp,"%s\n",teams[tr.round[0][16*i + 6]]);
  393.         fprintf(fp,"             %s\n",teams[tr.round[1][8*i + 3]]);
  394.         fprintf(fp,"%s\n",teams[tr.round[0][16*i + 7]]);
  395.  
  396.         fprintf(fp,"                                       Final Four:  %-s\n",
  397.             teams[tr.round[4][i]]);
  398.  
  399.         fprintf(fp,"%s\n",teams[tr.round[0][16*i + 8]]);
  400.         fprintf(fp,"             %s\n",teams[tr.round[1][8*i + 4]]);
  401.         fprintf(fp,"%s\n",teams[tr.round[0][16*i + 9]]);
  402.         fprintf(fp,"                          %s\n",teams[tr.round[2][4*i+2]]);
  403.         fprintf(fp,"%s\n",teams[tr.round[0][16*i + 10]]);
  404.         fprintf(fp,"             %s\n",teams[tr.round[1][8*i + 5]]);
  405.         fprintf(fp,"%s\n",teams[tr.round[0][16*i + 11]]);
  406.         fprintf(fp,"                                       %s\n",
  407.             teams[tr.round[3][2*i+1]]);
  408.         fprintf(fp,"%s\n",teams[tr.round[0][16*i + 12]]);
  409.         fprintf(fp,"             %s\n",teams[tr.round[1][8*i + 6]]);
  410.         fprintf(fp,"%s\n",teams[tr.round[0][16*i + 13]]);
  411.         fprintf(fp,"                          %s\n",teams[tr.round[2][4*i+3]]);
  412.         fprintf(fp,"%s\n",teams[tr.round[0][16*i + 14]]);
  413.         fprintf(fp,"             %s\n",teams[tr.round[1][8*i + 7]]);
  414.         fprintf(fp,"%s\n",teams[tr.round[0][16*i + 15]]);
  415.         if(i!=3)
  416.             fprintf(fp,"%c",12);    /* form feed at all but last */
  417.     }
  418.     fprintf(fp,"\n\n\n\nFinal four on down to champion:");
  419.     fprintf(fp,"-------------------------------\n\n\n");
  420.     fprintf(fp,"%-s\n",teams[tr.round[4][0]]);
  421.     fprintf(fp,"             %s\n",teams[tr.round[5][0]]);
  422.     fprintf(fp,"%-s\n",teams[tr.round[4][1]]);
  423.     fprintf(fp,"                          %s **** NATIONAL CHAMPION ****\n",
  424.         teams[tr.round[6][0]]);
  425.     fprintf(fp,"%-s\n",teams[tr.round[4][2]]);
  426.     fprintf(fp,"             %s\n",teams[tr.round[5][1]]);
  427.     fprintf(fp,"%-s\n",teams[tr.round[4][3]]);
  428.     
  429.     fclose(fp);
  430.  
  431. }
  432.  
  433. enter_picks()
  434. {
  435.     char    teams[TEAMS][NAMESZ+1], entrant[NAMESZ+1], title[80],
  436.         blurb[80];
  437.     int    round, game, p, i, save_flag=0, print_flag=1;
  438.     struct    entry    tr;
  439.  
  440.     clear();
  441.     init();
  442.     printw("Enter the name of the entrant (must be a unique name)\n\n");
  443.     printw("Name: ");
  444.     if(getst(PATHSZ,7,2,entrant,PATHSZ+1,NULL,LETTER_ONLY,NULL)==GET_ESCAPE)
  445.         return;
  446.     if(!read_entry(entrant,&tr,1)) {
  447.         printw("\n\n\nThis person is already on file.  Do you wish to edit their entry (y/n)?");
  448.         refresh();
  449.         if(getch()!='y') {
  450.             de_init();
  451.             return;
  452.         }
  453.     }
  454.     else {
  455.         save_flag = 1;
  456.         clear_entry(&tr);
  457.         sprintf(tr.name,entrant);
  458.     }
  459.     sprintf(blurb,"%s picks ",entrant);
  460.     for(i=1;i<ROUNDS;i++) {
  461.         sprintf(title," Enter round %d picks for entrant '%s' ",
  462.             i,entrant);
  463.         if(edit_round(title,blurb,i,games[i],&tr,0)) {
  464.             printw("\n\n Do you want to save this entry (y/n)? ");
  465.             refresh();
  466.             if(getch()=='y')
  467.                 save_entry(&tr);
  468.             else
  469.                 print_flag=save_flag=0;
  470.             i=ROUNDS+1;
  471.         }
  472.     }
  473.     if(i==ROUNDS)
  474.         save_entry(&tr);
  475.     if(save_flag)
  476.         update_entry_list(entrant);
  477.     if(print_flag) {
  478.         printw("\nThe entry for '%s' has been saved.\n",entrant);
  479.         printw("\nDo you want to create a printable file of this entry (y/n)?");
  480.         refresh();
  481.         if(getch()=='y')
  482.             print_picks(entrant);
  483.     }
  484.     de_init();
  485. }
  486.  
  487. save_teams(teams)
  488. char    teams[TEAMS][NAMESZ+1];
  489. {
  490.     int    i;
  491.     FILE    *fp, *fopen();
  492.     
  493.  
  494.     if((fp=fopen(TEAM_FILE,"w"))==NULL) {
  495.         clear();
  496.         terror("ERROR opening teams file");
  497.         return;
  498.     }
  499.     for(i=0;i<TEAMS;i++)
  500.         fprintf(fp,"%s\n",(teams[i][0]=='\0')? "#":teams[i]);
  501.     fclose(fp);
  502. }
  503.  
  504. read_teams(teams)
  505. char    teams[TEAMS][NAMESZ+1];
  506. {
  507.     FILE    *fp, *fopen();
  508.     int    i, j;
  509.  
  510.     if((fp=fopen(TEAM_FILE,"r"))<0) {
  511.         return(1);
  512.     }
  513.     for(i=0;i<TEAMS;i++) {
  514.         if(fgets(teams[i],NAMESZ,fp)==NULL)
  515.             break;
  516.         else if(teams[i][0]=='#')
  517.             teams[i][0]='\0';
  518.         else
  519.             for(j=0;j<NAMESZ;j++) 
  520.                 if(teams[i][j]=='\n') {
  521.                     teams[i][j] = '\0';
  522.                     break;
  523.                 }
  524.     }
  525.     for(;i<TEAMS;i++)
  526.         teams[i][0]='\0';
  527.  
  528.     fclose(fp);
  529.     return(0);
  530. }
  531.  
  532. terror(s)
  533. char    s[];
  534. {
  535.     char    dummy[11];
  536.  
  537.     standout();
  538.     printw("\n\n%s\n\n",s);
  539.     standend();
  540.     printw("Press RETURN to continue...");
  541.     refresh();
  542.     scanw("%10.10s",dummy);
  543. }
  544.  
  545. enter_teams()
  546. {
  547.     char    teams[TEAMS][NAMESZ+1], the_header[80];
  548.     static char    *headers[] = {
  549.         " ENTER TEAMS IN %s ",
  550.         " ENTER TEAMS IN %s ",
  551.         " ENTER TEAMS IN %s ",
  552.         " ENTER TEAMS IN %s ",
  553.     };
  554.     int    i=0, done=0, r;
  555.  
  556.     read_teams(teams);    /* get currently saved team info */
  557.     i=0;
  558.     while(!done) {
  559.         sprintf(the_header, headers[i], region_name[i]);
  560.         switch(r=editlist(the_header,i*16,(i+1)*16,teams)) {
  561.             case GET_DOWN:
  562.             case GET_RIGHT:
  563.                 if(i!=3)
  564.                     i++;
  565.                 else {
  566.                     done=1;
  567.                     save_teams(teams);
  568.                     init_standings();
  569.                 }
  570.                 break;
  571.             case GET_UP:
  572.             case GET_LEFT:
  573.                 if(i)
  574.                     i--;
  575.                 break;
  576.             case -1:        /* ABORT! */
  577.                 move(21,0);
  578.                 printw("Are you sure you want to abort (y/n)?");
  579.                 refresh();
  580.                 if(getch()=='y')
  581.                     done = 1;
  582.                 break;
  583.             default:
  584.                 move(21,0);
  585.                 printw("editlist returns %d\n",r);
  586.                 break;
  587.         }
  588.     }
  589.     return;
  590. }
  591.  
  592. editlist(title,i1,i2,names)
  593. char    title[], names[TEAMS][NAMESZ+1];
  594. int    i1, i2;
  595. {
  596.     int    state = 0, i, j, game, rval, done=0, rcode=0, y;
  597.     
  598.     clear();
  599.     standout();
  600.     printw(title);
  601.     standend();
  602.     edit_msg();
  603.  
  604.     init();
  605.     for(i=i1,j=2;i!=i2;i++,j++) {
  606.         move(j,0);
  607.         if((i%2) == 0) {
  608.             game = i/2 + 1;
  609.             printw("Game #%02d,  team #1:  ", game);
  610.         }
  611.         else
  612.             printw("           team #2:  ");
  613.         getst(NAMESZ,21,j,names[i],NAMESZ+1,NULL,SHOW,NULL);
  614.     }
  615.     refresh();
  616.     i=0;
  617.     while(!done) {
  618.         y = 2+i;
  619.         switch(getst(NAMESZ,21,y,names[i+i1],NAMESZ+1,NULL,ALL_ALPHA,NULL))
  620.         {
  621.             case GET_ESCAPE:
  622.                 done=1;
  623.                 rcode= -1;
  624.                 break;
  625.             case GET_RETURN:
  626.             case GET_RIGHT:
  627.             case GET_DOWN:
  628.                 i++;
  629.                 if(i+i1 == i2) {
  630.                     done=1;
  631.                     rcode = GET_DOWN;
  632.                 }
  633.                 break;
  634.             case GET_UP:
  635.             case GET_LEFT:
  636.                 i--;
  637.                 if(i<0) {
  638.                     i=0;
  639.                     done=1;    
  640.                     rcode=GET_LEFT;
  641.                 }
  642.                 break;
  643.             default:
  644.                 break;
  645.         }
  646.     }
  647.     de_init();
  648.     return(rcode);
  649. }
  650.  
  651. edit_msg()
  652. {
  653.     standout();
  654.  
  655.     move(22,0);
  656.     printw(" To change regions, scroll off the top and bottom ends of current region.  ");
  657.     move(23,0);
  658.     printw(" Use arrow keys for cursor movement, ESC to abort, and control-x to delete ");
  659.     standend();
  660. }
  661.  
  662. init_standings()
  663. {
  664.     struct    entry    tr;
  665.  
  666.     clear_entry(&tr);
  667.     sprintf(tr.name,MASTER_FILE);
  668.     save_entry(&tr);
  669. }
  670.  
  671. clear_entry(e)
  672. struct    entry *e;
  673. {
  674.     int    i, j;
  675.  
  676.     for(i=0;i<ROUNDS;i++)
  677.         for(j=0;j<TEAMS;j++)
  678.             e->round[i][j]= (i==0)? j: TEAMS+1;
  679. }
  680.  
  681. read_entry(name,e,flag)
  682. char    name[];
  683. struct    entry    *e;
  684. int    flag;        /* if set, no error messages */
  685. {
  686.     char    filename[80],tmp[NAMESZ+1], errmsg[80];
  687.     int    fd, i;
  688.  
  689.     for(i=0;i<NAMESZ;i++)
  690.         tmp[i]= (name[i]==' ')? '_':name[i];
  691.     sprintf(filename,PLAYER_FILE,tmp);
  692.     if((fd=open(filename,O_RDONLY))<0) {
  693.         if(!flag) {
  694.             sprintf(errmsg,"ERROR reading entry '%s', errno=%d",
  695.                 filename,errno);
  696.             terror(errmsg);
  697.         }
  698.         return(1);
  699.     }
  700.     read(fd,e,sizeof(struct entry));
  701.     close(fd);
  702.     return(0);
  703. }
  704.  
  705. save_entry(e)
  706. struct    entry    *e;
  707. {
  708.     char    filename[80],tmp[NAMESZ+1], errmsg[80];
  709.     int    fd, i;
  710.  
  711.     for(i=0;i<NAMESZ;i++)
  712.         tmp[i]= (e->name[i]==' ')? '_':e->name[i];
  713.     sprintf(filename,PLAYER_FILE,tmp);
  714.     if((fd=open(filename,O_CREAT|O_WRONLY,0600))<0) {
  715.         sprintf(errmsg,"ERROR saving entry, errno=%d",errno);
  716.         terror(errmsg);
  717.         return(1);
  718.     }
  719.     if(write(fd,e,sizeof(struct entry))!=sizeof(struct entry)) {
  720.         sprintf(errmsg,"ERROR in write of entry, errno=%d",errno);
  721.         terror(errmsg);
  722.     }
  723.     close(fd);
  724. }
  725.  
  726. /* title is the line on top of the screen.
  727.  * prompt is the message to display prior to showing current selection
  728.  * rnd in the round number (1-6)
  729.  * entires is the number of games this round
  730.  * e is this person's entry structure (pointer to)
  731.  * non is flag, if set then person can select neither team (results not in)
  732.  */
  733. edit_round(title,prompt,rnd,entries,e,non)
  734. char    title[], prompt[];
  735. int    entries, rnd,non;
  736. struct    entry    *e;
  737. {
  738.     int    i, winner1, winner2, c, done, toggle, x, x2;
  739.     char    teams[TEAMS][NAMESZ+1], *p;
  740.     static    char    neither[] = "neither -- Game not played yet";
  741.  
  742.     if(read_teams(teams)) {
  743.         terror("ERROR: have to enter tournament teams before results");
  744.         return(1);
  745.     }
  746.     clear();
  747.     standout();
  748.     printw(title);
  749.     standend();
  750.  
  751.     if(rnd!=1)     /* check to see if previous round is complete */
  752.         for(i=0;i<games[rnd-1];i++)
  753.             if(e->round[rnd-1][i]== TEAMS+1) {
  754.                 clear();
  755.                 terror("ERROR: previous round incomplete");
  756.                 return(1);
  757.             }
  758.  
  759.     move(22,0);
  760.     standout();
  761.     printw(" Use the space bar to select advancing team, RETURN once the correct team is  \n");
  762.     printw(" displayed.   Use left arrow to go to a previously entered game. ESC to abort ");
  763.     standend();
  764.     for(i=0;i<games[rnd];i++) {
  765.         move(3,0);
  766.         printw("Game %d:\n------------\n\n",i+1);
  767.         printw("%s\n vs                %s\n%s\n",
  768.             teams[e->round[rnd-1][i*2]], prompt,
  769.             teams[e->round[rnd-1][i*2+1]]);
  770.         winner1 = e->round[rnd-1][i*2];
  771.         winner2 = e->round[rnd-1][i*2+1];
  772.         done = toggle = 0;
  773.         if(e->round[rnd][i] == winner1)
  774.             toggle = 0;
  775.         else if(non) {
  776.             if(e->round[rnd][i] == winner2)
  777.                 toggle = 1;
  778.             else
  779.                 toggle = 2;
  780.         }
  781.         else
  782.             toggle = 1;
  783.         x = strlen(prompt) + 19;
  784.         while(!done) {
  785.             move(7,x);
  786.             standout();
  787.             switch(toggle) {
  788.                 case 0:
  789.                     p = teams[winner1];
  790.                     break;
  791.                 case 1:
  792.                     p = teams[winner2];
  793.                     break;
  794.                 case 2:
  795.                     p = neither;
  796.                     break;
  797.             }
  798.             printw("%s\n",p);
  799.             standend();
  800.             x2 = x + strlen(p) +1;
  801.             move(7,x2);
  802.             clrtoeol();    /* get rid of "standend" char on some terminals */
  803.             refresh();
  804.             switch(c = getch()) {
  805.                 case ' ':
  806.                     if(non)
  807.                         toggle = ++toggle % 3;
  808.                     else
  809.                         toggle = ++toggle % 2;
  810.                     break;
  811.                 case GET_RETURN:
  812.                 case GET_DOWN:
  813.                     done=1;
  814.                     break;
  815.                 case GET_LEFT:
  816.                     if(i==0)
  817.                         break;
  818.                     done = 2;
  819.                     break;
  820.                 case GET_ESCAPE:
  821.                     return(1);
  822.             }
  823.             if(done==2)
  824.                 i-=2;
  825.             else
  826.                 switch(toggle) {
  827.                     case 0:
  828.                         e->round[rnd][i] = winner1;
  829.                         break;
  830.                     case 1:
  831.                         e->round[rnd][i] = winner2;
  832.                         break;
  833.                     case 2:
  834.                         e->round[rnd][i] = TEAMS+1;
  835.                         break;
  836.                 }
  837.         }
  838.     }
  839.     return(0);
  840. }
  841.  
  842. update_entry_list(name)
  843. char    name[];
  844. {
  845.     FILE    *fp, *fopen();
  846.  
  847.     if((fp=fopen(ENTRY_FILE,"a"))==NULL) {
  848.         terror("ERROR opening entry file (list of people)");
  849.         return;
  850.     }
  851.     fprintf(fp,"%s\n",name);
  852.     fclose(fp);
  853. }
  854.