hack.o_init.c revision 1.5 1 1.5 christos /* $NetBSD: hack.o_init.c,v 1.5 1997/10/19 16:58:37 christos Exp $ */
2 1.5 christos
3 1.2 mycroft /*
4 1.2 mycroft * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
5 1.2 mycroft */
6 1.2 mycroft
7 1.5 christos #include <sys/cdefs.h>
8 1.2 mycroft #ifndef lint
9 1.5 christos __RCSID("$NetBSD: hack.o_init.c,v 1.5 1997/10/19 16:58:37 christos Exp $");
10 1.5 christos #endif /* not lint */
11 1.1 cgd
12 1.5 christos #include <string.h>
13 1.5 christos #include "hack.h"
14 1.5 christos #include "extern.h"
15 1.5 christos #include "def.objects.h"
16 1.5 christos #include "hack.onames.h" /* for LAST_GEM */
17 1.1 cgd
18 1.1 cgd int
19 1.5 christos letindex(let)
20 1.5 christos char let;
21 1.5 christos {
22 1.5 christos int i = 0;
23 1.5 christos char ch;
24 1.5 christos while ((ch = obj_symbols[i++]) != 0)
25 1.5 christos if (ch == let)
26 1.5 christos return (i);
27 1.5 christos return (0);
28 1.1 cgd }
29 1.1 cgd
30 1.5 christos void
31 1.5 christos init_objects()
32 1.5 christos {
33 1.5 christos int i, j, first, last, sum, end;
34 1.5 christos char let, *tmp;
35 1.5 christos /*
36 1.5 christos * init base; if probs given check that they add up to 100, otherwise
37 1.5 christos * compute probs; shuffle descriptions
38 1.5 christos */
39 1.1 cgd end = SIZE(objects);
40 1.1 cgd first = 0;
41 1.5 christos while (first < end) {
42 1.1 cgd let = objects[first].oc_olet;
43 1.5 christos last = first + 1;
44 1.5 christos while (last < end && objects[last].oc_olet == let
45 1.5 christos && objects[last].oc_name != NULL)
46 1.1 cgd last++;
47 1.1 cgd i = letindex(let);
48 1.5 christos if ((!i && let != ILLOBJ_SYM) || bases[i] != 0)
49 1.1 cgd error("initialization error");
50 1.1 cgd bases[i] = first;
51 1.1 cgd
52 1.5 christos if (let == GEM_SYM)
53 1.1 cgd setgemprobs();
54 1.5 christos check:
55 1.1 cgd sum = 0;
56 1.5 christos for (j = first; j < last; j++)
57 1.5 christos sum += objects[j].oc_prob;
58 1.5 christos if (sum == 0) {
59 1.5 christos for (j = first; j < last; j++)
60 1.5 christos objects[j].oc_prob = (100 + j - first) / (last - first);
61 1.1 cgd goto check;
62 1.1 cgd }
63 1.5 christos if (sum != 100)
64 1.1 cgd error("init-prob error for %c", let);
65 1.1 cgd
66 1.5 christos if (objects[first].oc_descr != NULL && let != TOOL_SYM) {
67 1.1 cgd /* shuffle, also some additional descriptions */
68 1.5 christos while (last < end && objects[last].oc_olet == let)
69 1.1 cgd last++;
70 1.1 cgd j = last;
71 1.5 christos while (--j > first) {
72 1.5 christos i = first + rn2(j + 1 - first);
73 1.1 cgd tmp = objects[j].oc_descr;
74 1.1 cgd objects[j].oc_descr = objects[i].oc_descr;
75 1.1 cgd objects[i].oc_descr = tmp;
76 1.1 cgd }
77 1.1 cgd }
78 1.1 cgd first = last;
79 1.1 cgd }
80 1.1 cgd }
81 1.1 cgd
82 1.5 christos int
83 1.5 christos probtype(let)
84 1.5 christos char let;
85 1.5 christos {
86 1.5 christos int i = bases[letindex(let)];
87 1.5 christos int prob = rn2(100);
88 1.5 christos while ((prob -= objects[i].oc_prob) >= 0)
89 1.5 christos i++;
90 1.5 christos if (objects[i].oc_olet != let || !objects[i].oc_name)
91 1.1 cgd panic("probtype(%c) error, i=%d", let, i);
92 1.5 christos return (i);
93 1.1 cgd }
94 1.1 cgd
95 1.5 christos void
96 1.1 cgd setgemprobs()
97 1.1 cgd {
98 1.5 christos int j, first;
99 1.1 cgd
100 1.1 cgd first = bases[letindex(GEM_SYM)];
101 1.1 cgd
102 1.5 christos for (j = 0; j < 9 - dlevel / 3; j++)
103 1.5 christos objects[first + j].oc_prob = 0;
104 1.1 cgd first += j;
105 1.5 christos if (first >= LAST_GEM || first >= SIZE(objects) ||
106 1.1 cgd objects[first].oc_olet != GEM_SYM ||
107 1.1 cgd objects[first].oc_name == NULL)
108 1.1 cgd printf("Not enough gems? - first=%d j=%d LAST_GEM=%d\n",
109 1.5 christos first, j, LAST_GEM);
110 1.5 christos for (j = first; j < LAST_GEM; j++)
111 1.5 christos objects[j].oc_prob = (20 + j - first) / (LAST_GEM - first);
112 1.1 cgd }
113 1.1 cgd
114 1.5 christos void
115 1.5 christos oinit()
116 1.5 christos { /* level dependent initialization */
117 1.1 cgd setgemprobs();
118 1.1 cgd }
119 1.1 cgd
120 1.5 christos void
121 1.5 christos savenames(fd)
122 1.5 christos int fd;
123 1.5 christos {
124 1.5 christos int i;
125 1.5 christos unsigned len;
126 1.1 cgd bwrite(fd, (char *) bases, sizeof bases);
127 1.1 cgd bwrite(fd, (char *) objects, sizeof objects);
128 1.5 christos /*
129 1.5 christos * as long as we use only one version of Hack/Quest we need not save
130 1.5 christos * oc_name and oc_descr, but we must save oc_uname for all objects
131 1.5 christos */
132 1.5 christos for (i = 0; i < SIZE(objects); i++) {
133 1.5 christos if (objects[i].oc_uname) {
134 1.5 christos len = strlen(objects[i].oc_uname) + 1;
135 1.1 cgd bwrite(fd, (char *) &len, sizeof len);
136 1.1 cgd bwrite(fd, objects[i].oc_uname, len);
137 1.1 cgd }
138 1.1 cgd }
139 1.1 cgd }
140 1.1 cgd
141 1.5 christos void
142 1.5 christos restnames(fd)
143 1.5 christos int fd;
144 1.5 christos {
145 1.5 christos int i;
146 1.5 christos unsigned len;
147 1.1 cgd mread(fd, (char *) bases, sizeof bases);
148 1.1 cgd mread(fd, (char *) objects, sizeof objects);
149 1.5 christos for (i = 0; i < SIZE(objects); i++)
150 1.5 christos if (objects[i].oc_uname) {
151 1.5 christos mread(fd, (char *) &len, sizeof len);
152 1.5 christos objects[i].oc_uname = (char *) alloc(len);
153 1.5 christos mread(fd, objects[i].oc_uname, len);
154 1.5 christos }
155 1.1 cgd }
156 1.1 cgd
157 1.5 christos int
158 1.5 christos dodiscovered()
159 1.5 christos { /* free after Robert Viduya */
160 1.5 christos int i, end;
161 1.5 christos int ct = 0;
162 1.5 christos
163 1.5 christos cornline(0, "Discoveries");
164 1.5 christos
165 1.5 christos end = SIZE(objects);
166 1.5 christos for (i = 0; i < end; i++) {
167 1.5 christos if (interesting_to_discover(i)) {
168 1.5 christos ct++;
169 1.5 christos cornline(1, typename(i));
170 1.5 christos }
171 1.1 cgd }
172 1.5 christos if (ct == 0) {
173 1.5 christos pline("You haven't discovered anything yet...");
174 1.5 christos cornline(3, (char *) 0);
175 1.5 christos } else
176 1.5 christos cornline(2, (char *) 0);
177 1.1 cgd
178 1.5 christos return (0);
179 1.1 cgd }
180 1.1 cgd
181 1.5 christos int
182 1.1 cgd interesting_to_discover(i)
183 1.5 christos int i;
184 1.1 cgd {
185 1.5 christos return (
186 1.5 christos objects[i].oc_uname != NULL ||
187 1.5 christos (objects[i].oc_name_known && objects[i].oc_descr != NULL)
188 1.5 christos );
189 1.1 cgd }
190