home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume11 / jotto / part01 / jotto.c < prev    next >
C/C++ Source or Header  |  1990-12-11  |  7KB  |  324 lines

  1. /*
  2.  *    Jotto.  G. L. Sicherman.  1990.
  3.  *    Translated to C from UNIX f77.
  4.  *    The UNIX f77 was ported from the original CDC FORTRAN IV
  5.  *    and COMPASS, which goes back to around 1975.
  6.  *
  7.  *    You may use this program and modify it as you like,
  8.  *    so long as you leave this message as it is and don't
  9.  *    try to make money off the program.
  10.  */
  11.  
  12. #include <ctype.h>
  13. #include <stdio.h>
  14. /*
  15.  *    The usual string incompatibility.
  16.  *    In SYSV, index() is an unrelated function in libPW.
  17.  */
  18. #ifdef BSD
  19. #include <strings.h>
  20. #define    strchr index
  21. #else
  22. #include <string.h>
  23. #endif
  24. #include "jotto.h"
  25.  
  26. #ifndef    DICT
  27. #define    DICT    "jotto.d"
  28. #endif
  29.  
  30. char    *bad[DICTLEN];            /* words eliminated by one answer */
  31. int    diagn = 0;
  32. char    dict[DICTLEN][WORDLEN*2+1];    /* all the words */
  33. char    *good[DICTLEN];            /* words not eliminated */
  34. int    gy[MAXGUESS];
  35. char    *iguess[MAXGUESS];
  36. int    ndict;
  37. int    ngood, nbad;
  38. FILE    *tape4;                /* Yep - it's CDC FORTRAN, all right */
  39. char    uguess[MAXGUESS][WORDLEN+1];
  40. int    uguessc, iresp[MAXGUESS];
  41.  
  42. extern    char    *getlogin();
  43. extern    int    legal();
  44. extern    char    *ord();
  45. extern    long    time();
  46.  
  47. main(argc, argv)
  48. int argc;
  49. char **argv;
  50. {
  51.     char    **use;        /* whichever we're using */
  52.     int    num;
  53.     int    igs;
  54.     int    *nuse;
  55.     char    mult[WORDLEN*10+1];
  56.     char    *foundpan;
  57.     int    guess;
  58.     int    ustart;
  59.     char    *login;
  60.     char    *pop;
  61.     int    wins[2];
  62.     int    over;
  63.     char    *you, *getword();
  64.     char    *mine;
  65.     char    *old;
  66.     char    *a;
  67.     long    best;
  68.     int    which;
  69.     int    iguessc;
  70.     int    i, n, i0;
  71.  
  72.     while (--argc) {
  73.         if ('-'==**++argv) switch(*++*argv) {
  74.         case 'd':        /* undocumented debugging option */
  75.             diagn = 1;
  76.             break;
  77.         default:
  78.             ;
  79.         }
  80.         else break;
  81.     }
  82.     printf(" Jotto 3.0\n");
  83.     for (i=0; i<2; i++) wins[i]=0;
  84.     tape4 = fopen(DICT, "r");
  85.     if (!tape4) {
  86.         printf("\nCannot read dictionary - aborted\n");
  87.         exit(1);
  88.     }
  89.     login = getlogin();
  90.     load();
  91.     srand(time((long *)0));
  92.     ustart = rand(0) >= 16384;
  93.     do {    /* loop over games */
  94.         printf("\n Think of a word of %d different letters.\n",
  95.             WORDLEN);
  96. /*
  97.  *        Pick a word.
  98.  */
  99.         mine = &dict[which=rand()%ndict][WORDLEN];
  100.         if (diagn) printf("l %5d\n", ndict);
  101. /*
  102.  *        Copy all the words into the good list
  103.  *        while the user is thinking.
  104.  */
  105.         for (i=0; i<ndict; i++) good[i] = dict[i];
  106.         ngood = ndict;
  107.         nbad=0;
  108.         while (!yes(" Ready? ")) ;
  109. /*
  110.  *        Pick a place in the dictionary to start guessing.
  111.  */
  112.         do guess = rand()%ndict;
  113.         while (guess == which);    /* don't guess our own word! */
  114.         printf(" Type a carriage-return for a list of my answers.\n");
  115.         iguessc = uguessc = 0;
  116.         foundpan = (char *)NULL;
  117.         for (over=0; !over; ) {
  118. /*
  119.  *            Loop over turns.
  120.  */
  121.             if (ustart && uguessc==0) goto getguess;
  122. /*
  123.  *            our turn to guess.
  124.  */
  125.             if (foundpan) {
  126. /*
  127.  *                Multiple anagrams!
  128.  */
  129.                 foundpan += WORDLEN;
  130.                 if (*foundpan) {
  131.                     old = foundpan;
  132.                     goto doguess;
  133.                 }
  134.                 /* otherwise we're stuck */
  135.                 goto giveup;
  136.             }
  137.             best = -999999;
  138.             use = good;
  139.             if (!*(nuse = &ngood)) {
  140.                 if (!*(nuse = &nbad)) goto giveup;
  141.                 use = bad;
  142.             }
  143.             if (*nuse == 1) old = &use[0][WORDLEN];
  144.             else for (igs=0; igs<50; igs++) {
  145.                 if ((guess += 31) >= ndict) guess -= ndict;
  146.     /*
  147.      *            Get the guess.
  148.      */
  149.                 a = &dict[guess][WORDLEN];
  150.                 if ((i=isis(a,use,*nuse)) >= best) {
  151.                     best = i;
  152.                     old = a;
  153.                 }
  154.                 if (diagn && igs<10)
  155.                     printf(" ?g %s %7d\n", a, i);
  156.                 if (best >= -1) break;
  157.             }
  158.             if (diagn && *nuse <= 10) {
  159.                 for (i=0; i<*nuse; i++)
  160.                 printf(" i %.*s\n", WORDLEN, use[i]+WORDLEN);
  161.             }
  162.             if (diagn) printf("%dg%d\n", igs, best);
  163. doguess:
  164.             printf("\n My %d%s guess is: %.*s.\n",
  165.                 iguessc+1, ord(iguessc+1), WORDLEN, old);
  166.             num = getnum(" How many letters? ");
  167.             iguess[iguessc] = old;
  168.             gy[iguessc++] = num;
  169.             if (num == WORDLEN) {
  170.                 if (yes(" Is that your word? ")) {
  171.                     printf("\n Your word is: %s\n", old);
  172.                     printf(" My word was: %s\n", mine);
  173.                     wins[0]++;
  174.                     over = 1;
  175.                     break;
  176.                 }
  177.                 if (!foundpan) {
  178.                     getmult(old-WORDLEN, mult);
  179.                     foundpan = mult;
  180.                 }
  181.             }
  182.             else revise(old, num);
  183. /*
  184.  *        Time for the user's guess.
  185.  */
  186. getguess:
  187.             do {
  188.                 printf("\n What is your %d%s guess? ",
  189.                     uguessc+1, ord(uguessc+1));
  190.                 you = getword();
  191.                 if (strlen(you)==0) {
  192.                     jsumm();
  193.                     continue;
  194.                 }
  195.             } while (!legal(you));
  196.             strcpy(uguess[uguessc] , you);
  197.             iresp[uguessc++] = i = inter(mine, you);
  198.             if (!strcmp(mine, you)) {
  199.                 printf(" ...you win.\n");
  200.                 goto beg;
  201.             }
  202.             answer(you, i);
  203.             continue;
  204. giveup:
  205.             printf("\n\n I give up.\n");
  206. beg:
  207.             printf(" What was your word? ");
  208.             pop = getword();
  209.             if (!legal(pop)) {
  210.                 printf("\n \"%s\" is not a legal word.\n", pop);
  211.                 wins[0]++;
  212.                 over = 1;
  213.                 break;
  214.             }
  215. /*
  216.  *        Check his answers.
  217.  */
  218.             for (i0 = 0; i0 < iguessc; i0++) {
  219.                 if (inter(iguess[i0],pop) != gy[i0]) {
  220.                     printf(
  221.             "\n You cheated\n You said \"%s\" had %d letters\n",
  222.                         iguess[i0], gy[i0]);
  223.                     wins[0]++;
  224.                     over = 1;
  225.                     break;
  226.                 }
  227.                 if (!strcmp(iguess[i0],pop)) {
  228.                     printf(
  229.                 " You cheated\n You said \"%s\" was not your word\n",
  230.                         iguess[i0]);
  231.                     wins[0]++;
  232.                     over = 1;
  233.                     break;
  234.                 }
  235.             }
  236.             if (over) break;
  237.             wins[1]++;
  238.             printf(" My word was: %s\n", mine);
  239.             over = 1;
  240.         }
  241.     } while (yes(" Another game? "));
  242.     printf("\n Final score\n %-8.8s %2d\n computer %2d\n",
  243.         login, wins[1], wins[0]);
  244.     exit(0);
  245. }
  246.  
  247. int
  248. yes(prompt)
  249. char *prompt;
  250. {
  251.     char *i, inline[80+1];
  252.  
  253.     printf(prompt);
  254.     if (!gets(inline)) {
  255.         printf("ERROR reading your answer\n");
  256.         return 0;
  257.     }
  258.     for (i=inline; *i && isspace(*i); i++) ;
  259.     return *i == 'y' || *i == 'Y';
  260. }
  261.  
  262. char *
  263. getword()
  264. {
  265.     static char wline[80];
  266.     char *w, *ww;
  267.  
  268.     if (!gets(wline)) {
  269.         printf("ERROR reading your answer\n");
  270.         return (char *)0;
  271.     }
  272.     for (w=wline; *w && isspace(*w); w++) ;
  273.     for (ww=w; !isspace(*ww); ww++) ;
  274.     *ww = '\0';
  275.     for (ww=w; *ww; ww++) if (isupper(*ww)) *ww=tolower(*ww);
  276.     return w;
  277. }
  278.  
  279. int
  280. getnum(pr)
  281. char *pr;
  282. {
  283.     char *n, nline[80+1];
  284.     do {
  285.         printf(pr);
  286.         if (!gets(nline)) return -1;
  287.         if (n = strchr(nline, '\n')) *n = 0;
  288.         for (n=nline; *n && isspace(*n); n++) ;
  289.     } while (!isdigit(*n));
  290.     return atoi(n);
  291. }
  292.  
  293. getmult(want, hold)
  294. char *want, *hold;
  295. {
  296.     char mline[80+1];
  297.     rewind(tape4);
  298.     while (fgets(mline, 80, tape4)) if (!strncmp(want,mline,WORDLEN)) {
  299.         *(strchr(mline,'\n')) = '\0';
  300.         strcpy(hold, mline+WORDLEN);
  301.         return;
  302.     }
  303. }
  304.  
  305. revise(word, num)
  306. char *word;
  307. int num;
  308. /*
  309.  *.... revise candidate lists. 
  310.  */
  311. {
  312.     int n;
  313.  
  314.     for (n=0; n<nbad; n++)
  315.         if (inter(bad[n], word) != num)
  316.             bad[n--] = bad[--nbad];
  317.     for (n=0; n<ngood; n++)
  318.         if (inter(good[n], word) != num) {
  319.             bad[nbad++] = good[n];    
  320.             good[n--] = good[--ngood];
  321.         }
  322.     if (diagn) printf(" w%5d%5d\n", ngood, nbad);
  323. }
  324.