home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / games / fish / fish.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-20  |  9.1 KB  |  430 lines

  1. /*-
  2.  * Copyright (c) 1990 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Muffy Barkocy.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  */
  36.  
  37. #ifndef lint
  38. char copyright[] =
  39. "@(#) Copyright (c) 1990 The Regents of the University of California.\n\
  40.  All rights reserved.\n";
  41. #endif /* not lint */
  42.  
  43. #ifndef lint
  44. static char sccsid[] = "@(#)fish.c    5.4 (Berkeley) 1/18/91";
  45. #endif /* not lint */
  46.  
  47. #include <sys/types.h>
  48. #include <sys/errno.h>
  49. #include <fcntl.h>
  50. #include <stdio.h>
  51. #include <stdlib.h>
  52. #include <string.h>
  53. #include "pathnames.h"
  54.  
  55. #define    RANKS        13
  56. #define    HANDSIZE    7
  57. #define    CARDS        4
  58.  
  59. #define    USER        1
  60. #define    COMPUTER    0
  61. #define    OTHER(a)    (1 - (a))
  62.  
  63. char *cards[] = {
  64.     "A", "2", "3", "4", "5", "6", "7",
  65.     "8", "9", "10", "J", "Q", "K", NULL,
  66. };
  67. #define    PRC(card)    (void)printf(" %s", cards[card])
  68.  
  69. int promode;
  70. int asked[RANKS], comphand[RANKS], deck[RANKS];
  71. int userasked[RANKS], userhand[RANKS];
  72.  
  73. main(argc, argv)
  74.     int argc;
  75.     char **argv;
  76. {
  77.     int ch, move;
  78.  
  79.     while ((ch = getopt(argc, argv, "p")) != EOF)
  80.         switch(ch) {
  81.         case 'p':
  82.             promode = 1;
  83.             break;
  84.         case '?':
  85.         default:
  86.             (void)fprintf(stderr, "usage: fish [-p]\n");
  87.             exit(1);
  88.         }
  89.  
  90.     srandom(time((time_t *)NULL));
  91.     instructions();
  92.     init();
  93.  
  94.     if (nrandom(2) == 1) {
  95.         printplayer(COMPUTER);
  96.         (void)printf("get to start.\n");
  97.         goto istart;
  98.     }
  99.     printplayer(USER);
  100.     (void)printf("get to start.\n");
  101.     
  102.     for (;;) {
  103.         move = usermove();
  104.         if (!comphand[move]) {
  105.             if (gofish(move, USER, userhand))
  106.                 continue;
  107.         } else {
  108.             goodmove(USER, move, userhand, comphand);
  109.             continue;
  110.         }
  111.  
  112. istart:        for (;;) {
  113.             move = compmove();
  114.             if (!userhand[move]) {
  115.                 if (!gofish(move, COMPUTER, comphand))
  116.                     break;
  117.             } else
  118.                 goodmove(COMPUTER, move, comphand, userhand);
  119.         }
  120.     }
  121.     /* NOTREACHED */
  122. }
  123.  
  124. usermove()
  125. {
  126.     register int n;
  127.     register char **p;
  128.     char buf[256];
  129.  
  130.     (void)printf("\nYour hand is:");
  131.     printhand(userhand);
  132.  
  133.     for (;;) {
  134.         (void)printf("You ask me for: ");
  135.         (void)fflush(stdout);
  136.         if (fgets(buf, BUFSIZ, stdin) == NULL)
  137.             exit(0);
  138.         if (buf[0] == '\0')
  139.             continue;
  140.         if (buf[0] == '\n') {
  141.             (void)printf("%d cards in my hand, %d in the pool.\n",
  142.                 countcards(comphand), countcards(deck));
  143.             (void)printf("My books:");
  144.             (void)countbooks(comphand);
  145.             continue;
  146.         }
  147.         buf[strlen(buf) - 1] = '\0';
  148.         if (!strcasecmp(buf, "p") && !promode) {
  149.             promode = 1;
  150.             (void)printf("Entering pro mode.\n");
  151.             continue;
  152.         }
  153.         if (!strcasecmp(buf, "quit"))
  154.             exit(0);
  155.         for (p = cards; *p; ++p)
  156.             if (!strcasecmp(*p, buf))
  157.                 break;
  158.         if (!*p) {
  159.             (void)printf("I don't understand!\n");
  160.             continue;
  161.         }
  162.         n = p - cards;
  163.         if (userhand[n]) {
  164.             userasked[n] = 1;
  165.             return(n);
  166.         }
  167.         if (nrandom(3) == 1)
  168.             (void)printf("You don't have any of those!\n");
  169.         else
  170.             (void)printf("You don't have any %s's!\n", cards[n]);
  171.         if (nrandom(4) == 1)
  172.             (void)printf("No cheating!\n");
  173.         (void)printf("Guess again.\n");
  174.     }
  175.     /* NOTREACHED */
  176. }
  177.  
  178. compmove()
  179. {
  180.     static int lmove;
  181.  
  182.     if (promode)
  183.         lmove = promove();
  184.     else {
  185.         do {
  186.             lmove = (lmove + 1) % RANKS;
  187.         } while (!comphand[lmove] || comphand[lmove] == CARDS);
  188.     }
  189.     asked[lmove] = 1;
  190.  
  191.     (void)printf("I ask you for: %s.\n", cards[lmove]);
  192.     return(lmove);
  193. }
  194.  
  195. promove()
  196. {
  197.     register int i, max;
  198.  
  199.     for (i = 0; i < RANKS; ++i)
  200.         if (userasked[i] &&
  201.             comphand[i] > 0 && comphand[i] < CARDS) {
  202.             userasked[i] = 0;
  203.             return(i);
  204.         }
  205.     if (nrandom(3) == 1) {
  206.         for (i = 0;; ++i)
  207.             if (comphand[i] && comphand[i] != CARDS) {
  208.                 max = i;
  209.                 break;
  210.             }
  211.         while (++i < RANKS) 
  212.             if (comphand[i] != CARDS &&
  213.                 comphand[i] > comphand[max])
  214.                 max = i;
  215.         return(max);
  216.     } 
  217.     if (nrandom(1024) == 0723) {
  218.         for (i = 0; i < RANKS; ++i)
  219.             if (userhand[i] && comphand[i])
  220.                 return(i);
  221.     }
  222.     for (;;) {
  223.         for (i = 0; i < RANKS; ++i)
  224.             if (comphand[i] && comphand[i] != CARDS &&
  225.                 !asked[i])
  226.                 return(i);
  227.         for (i = 0; i < RANKS; ++i)
  228.             asked[i] = 0;
  229.     }
  230.     /* NOTREACHED */
  231. }
  232.  
  233. drawcard(player, hand)
  234.     int player;
  235.     int *hand;
  236. {
  237.     int card;
  238.  
  239.     while (deck[card = nrandom(RANKS)] == 0);
  240.     ++hand[card];
  241.     --deck[card];
  242.     if (player == USER || hand[card] == CARDS) {
  243.         printplayer(player);
  244.         (void)printf("drew %s", cards[card]);
  245.         if (hand[card] == CARDS) {
  246.             (void)printf(" and made a book of %s's!\n",
  247.                  cards[card]);
  248.             chkwinner(player, hand);
  249.         } else
  250.             (void)printf(".\n");
  251.     }
  252.     return(card);
  253. }
  254.  
  255. gofish(askedfor, player, hand)
  256.     int askedfor, player;
  257.     int *hand;
  258. {
  259.     printplayer(OTHER(player));
  260.     (void)printf("say \"GO FISH!\"\n");
  261.     if (askedfor == drawcard(player, hand)) {
  262.         printplayer(player);
  263.         (void)printf("drew the guess!\n");
  264.         printplayer(player);
  265.         (void)printf("get to ask again!\n");
  266.         return(1);
  267.     }
  268.     return(0);
  269. }
  270.  
  271. goodmove(player, move, hand, opphand)
  272.     int player, move;
  273.     int *hand, *opphand;
  274. {
  275.     printplayer(OTHER(player));
  276.     (void)printf("have %d %s%s.\n",
  277.         opphand[move], cards[move], opphand[move] == 1 ? "": "'s");
  278.  
  279.     hand[move] += opphand[move];
  280.     opphand[move] = 0;
  281.  
  282.     if (hand[move] == CARDS) {
  283.         printplayer(player);
  284.         (void)printf("made a book of %s's!\n", cards[move]);
  285.         chkwinner(player, hand);
  286.     }
  287.  
  288.     chkwinner(OTHER(player), opphand);
  289.  
  290.     printplayer(player);
  291.     (void)printf("get another guess!\n");
  292. }
  293.  
  294. chkwinner(player, hand)
  295.     int player;
  296.     register int *hand;
  297. {
  298.     register int cb, i, ub;
  299.  
  300.     for (i = 0; i < RANKS; ++i)
  301.         if (hand[i] > 0 && hand[i] < CARDS)
  302.             return;
  303.     printplayer(player);
  304.     (void)printf("don't have any more cards!\n");
  305.     (void)printf("My books:");
  306.     cb = countbooks(comphand);
  307.     (void)printf("Your books:");
  308.     ub = countbooks(userhand);
  309.     (void)printf("\nI have %d, you have %d.\n", cb, ub);
  310.     if (ub > cb) {
  311.         (void)printf("\nYou win!!!\n");
  312.         if (nrandom(1024) == 0723)
  313.             (void)printf("Cheater, cheater, pumpkin eater!\n");
  314.     } else if (cb > ub) {
  315.         (void)printf("\nI win!!!\n");
  316.         if (nrandom(1024) == 0723)
  317.             (void)printf("Hah!  Stupid peasant!\n");
  318.     } else
  319.         (void)printf("\nTie!\n");
  320.     exit(0);
  321. }
  322.  
  323. printplayer(player)
  324.     int player;
  325. {
  326.     switch (player) {
  327.     case COMPUTER:
  328.         (void)printf("I ");
  329.         break;
  330.     case USER:
  331.         (void)printf("You ");
  332.         break;
  333.     }
  334. }
  335.  
  336. printhand(hand)
  337.     int *hand;
  338. {
  339.     register int book, i, j;
  340.  
  341.     for (book = i = 0; i < RANKS; i++)
  342.         if (hand[i] < CARDS)
  343.             for (j = hand[i]; --j >= 0;) 
  344.                 PRC(i);
  345.         else
  346.             ++book;
  347.     if (book) {
  348.         (void)printf(" + Book%s of", book > 1 ? "s" : "");
  349.         for (i = 0; i < RANKS; i++)
  350.             if (hand[i] == CARDS)
  351.                 PRC(i);
  352.     }
  353.     (void)putchar('\n');
  354. }
  355.  
  356. countcards(hand)
  357.     register int *hand;
  358. {
  359.     register int i, count;
  360.  
  361.     for (count = i = 0; i < RANKS; i++)
  362.         count += *hand++;
  363.     return(count);
  364. }
  365.  
  366. countbooks(hand)
  367.     int *hand;
  368. {
  369.     int i, count;
  370.  
  371.     for (count = i = 0; i < RANKS; i++)
  372.         if (hand[i] == CARDS) {
  373.             ++count;
  374.             PRC(i);
  375.         }
  376.     if (!count)
  377.         (void)printf(" none");
  378.     (void)putchar('\n');
  379.     return(count);
  380. }
  381.  
  382. init()
  383. {
  384.     register int i, rank;
  385.  
  386.     for (i = 0; i < RANKS; ++i)
  387.         deck[i] = CARDS;
  388.     for (i = 0; i < HANDSIZE; ++i) {
  389.         while (!deck[rank = nrandom(RANKS)]);
  390.         ++userhand[rank];
  391.         --deck[rank];
  392.     }
  393.     for (i = 0; i < HANDSIZE; ++i) {
  394.         while (!deck[rank = nrandom(RANKS)]);
  395.         ++comphand[rank];
  396.         --deck[rank];
  397.     }
  398. }
  399.  
  400. nrandom(n)
  401.     int n;
  402. {
  403.     long random();
  404.  
  405.     return((int)random() % n);
  406. }
  407.  
  408. instructions()
  409. {
  410.     int input;
  411.     char buf[1024];
  412.  
  413.     (void)printf("Would you like instructions (y or n)? ");
  414.     input = getchar();
  415.     while (getchar() != '\n');
  416.     if (input != 'y')
  417.         return;
  418.  
  419.     (void)sprintf(buf, "%s %s", _PATH_MORE, _PATH_INSTR);
  420.     (void)system(buf);
  421.     (void)printf("Hit return to continue...\n");
  422.     while ((input = getchar()) != EOF && input != '\n');
  423. }
  424.  
  425. usage()
  426. {
  427.     (void)fprintf(stderr, "usage: fish [-p]\n");
  428.     exit(1);
  429. }
  430.