xref: /netbsd-src/games/hack/hack.rumors.c (revision 3b01aba77a7a698587faaae455bbfe740923c1f5)
1 /*	$NetBSD: hack.rumors.c,v 1.4 1997/10/19 16:58:55 christos Exp $	*/
2 
3 /*
4  * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
5  */
6 
7 #include <sys/cdefs.h>
8 #ifndef lint
9 __RCSID("$NetBSD: hack.rumors.c,v 1.4 1997/10/19 16:58:55 christos Exp $");
10 #endif				/* not lint */
11 
12 #include "hack.h"	/* for RUMORFILE and BSD (strchr) */
13 #include "extern.h"
14 #define	CHARSZ	8		/* number of bits in a char */
15 int             n_rumors = 0;
16 int             n_used_rumors = -1;
17 char           *usedbits;
18 
19 void
20 init_rumors(rumf)
21 	FILE           *rumf;
22 {
23 	int             i;
24 	n_used_rumors = 0;
25 	while (skipline(rumf))
26 		n_rumors++;
27 	rewind(rumf);
28 	i = n_rumors / CHARSZ;
29 	usedbits = (char *) alloc((unsigned) (i + 1));
30 	for (; i >= 0; i--)
31 		usedbits[i] = 0;
32 }
33 
34 int
35 skipline(rumf)
36 	FILE           *rumf;
37 {
38 	char            line[COLNO];
39 	while (1) {
40 		if (!fgets(line, sizeof(line), rumf))
41 			return (0);
42 		if (strchr(line, '\n'))
43 			return (1);
44 	}
45 }
46 
47 void
48 outline(rumf)
49 	FILE           *rumf;
50 {
51 	char            line[COLNO];
52 	char           *ep;
53 	if (!fgets(line, sizeof(line), rumf))
54 		return;
55 	if ((ep = strchr(line, '\n')) != 0)
56 		*ep = 0;
57 	pline("This cookie has a scrap of paper inside! It reads: ");
58 	pline(line);
59 }
60 
61 void
62 outrumor()
63 {
64 	int             rn, i;
65 	FILE           *rumf;
66 	if (n_rumors <= n_used_rumors ||
67 	    (rumf = fopen(RUMORFILE, "r")) == (FILE *) 0)
68 		return;
69 	if (n_used_rumors < 0)
70 		init_rumors(rumf);
71 	if (!n_rumors)
72 		goto none;
73 	rn = rn2(n_rumors - n_used_rumors);
74 	i = 0;
75 	while (rn || used(i)) {
76 		(void) skipline(rumf);
77 		if (!used(i))
78 			rn--;
79 		i++;
80 	}
81 	usedbits[i / CHARSZ] |= (1 << (i % CHARSZ));
82 	n_used_rumors++;
83 	outline(rumf);
84 none:
85 	(void) fclose(rumf);
86 }
87 
88 int
89 used(i)
90 	int             i;
91 {
92 	return (usedbits[i / CHARSZ] & (1 << (i % CHARSZ)));
93 }
94