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