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