Home | History | Annotate | Line # | Download | only in fish
fish.c revision 1.1
      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