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