my aborted rewrite (curses, structs, and tons of other changes)
[unix-history] / usr / src / games / fish / fish.c
CommitLineData
495d41aa
KB
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 * %sccs.include.redist.c%
e0bbfbf9
DF
9 */
10
11#ifndef lint
12char copyright[] =
495d41aa 13"@(#) Copyright (c) 1990 The Regents of the University of California.\n\
e0bbfbf9 14 All rights reserved.\n";
495d41aa 15#endif /* not lint */
e0bbfbf9
DF
16
17#ifndef lint
adccc0d2 18static char sccsid[] = "@(#)fish.c 5.4 (Berkeley) %G%";
495d41aa
KB
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
37char *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
43int promode;
44int asked[RANKS], comphand[RANKS], deck[RANKS];
45int userasked[RANKS], userhand[RANKS];
46
47main(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);
32029695
KM
62 }
63
495d41aa
KB
64 srandom(time((time_t *)NULL));
65 instructions();
66 init();
32029695 67
495d41aa
KB
68 if (nrandom(2) == 1) {
69 printplayer(COMPUTER);
70 (void)printf("get to start.\n");
71 goto istart;
32029695 72 }
495d41aa
KB
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;
32029695 84 }
32029695 85
495d41aa
KB
86istart: for (;;) {
87 move = compmove();
88 if (!userhand[move]) {
89 if (!gofish(move, COMPUTER, comphand))
90 break;
91 } else
92 goodmove(COMPUTER, move, comphand, userhand);
32029695
KM
93 }
94 }
495d41aa
KB
95 /* NOTREACHED */
96}
97
98usermove()
99{
100 register int n;
101 register char **p;
102 char buf[256];
103
adccc0d2 104 (void)printf("\nYour hand is:");
495d41aa
KB
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;
32029695 120 }
495d41aa
KB
121 buf[strlen(buf) - 1] = '\0';
122 if (!strcasecmp(buf, "p") && !promode) {
123 promode = 1;
124 (void)printf("Entering pro mode.\n");
125 continue;
32029695 126 }
495d41aa
KB
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");
32029695 134 continue;
32029695 135 }
495d41aa
KB
136 n = p - cards;
137 if (userhand[n]) {
138 userasked[n] = 1;
139 return(n);
32029695 140 }
495d41aa
KB
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");
32029695 148 }
495d41aa
KB
149 /* NOTREACHED */
150}
151
152compmove()
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;
32029695 164
495d41aa
KB
165 (void)printf("I ask you for: %s.\n", cards[lmove]);
166 return(lmove);
167}
32029695 168
495d41aa
KB
169promove()
170{
171 register int i, max;
32029695 172
495d41aa
KB
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);
32029695 178 }
495d41aa
KB
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);
32029695 195 }
495d41aa
KB
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;
32029695 203 }
495d41aa
KB
204 /* NOTREACHED */
205}
206
207drawcard(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");
32029695 225 }
495d41aa
KB
226 return(card);
227}
228
229gofish(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");
32029695 240 return(1);
32029695 241 }
495d41aa
KB
242 return(0);
243}
244
245goodmove(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);
32029695
KM
260 }
261
495d41aa
KB
262 chkwinner(OTHER(player), opphand);
263
264 printplayer(player);
265 (void)printf("get another guess!\n");
266}
267
268chkwinner(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");
32029695 294 exit(0);
495d41aa
KB
295}
296
297printplayer(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;
32029695 307 }
495d41aa
KB
308}
309
310printhand(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);
32029695 326 }
495d41aa
KB
327 (void)putchar('\n');
328}
329
330countcards(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
340countbooks(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);
32029695 349 }
495d41aa
KB
350 if (!count)
351 (void)printf(" none");
352 (void)putchar('\n');
353 return(count);
354}
355
356init()
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];
32029695 366 }
495d41aa
KB
367 for (i = 0; i < HANDSIZE; ++i) {
368 while (!deck[rank = nrandom(RANKS)]);
369 ++comphand[rank];
370 --deck[rank];
371 }
372}
373
374nrandom(n)
375 int n;
376{
377 long random();
378
379 return((int)random() % n);
380}
381
382instructions()
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
399usage()
400{
401 (void)fprintf(stderr, "usage: fish [-p]\n");
402 exit(1);
403}