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