Sun Jul 25 02:00:42 2021 UTC ()
Flush input to EOL correctly in games/fish.

PR 54885 from Mouse, with a somewhat different patch.


(dholland)
diff -r1.26 -r1.27 src/games/fish/fish.c

cvs diff -r1.26 -r1.27 src/games/fish/fish.c (switch to unified diff)

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