1 /**
2  * \file wiz-stats.c
3  * \brief Statistics collection on dungeon generation
4  *
5  * Copyright (c) 2008 Andi Sidwell
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  *  * Redistributions of source code must retain the above copyright notice,
11  *    this list of conditions and the following disclaimer.
12  *
13  *  * Redistributions in binary form must reproduce the above copyright notice,
14  *    this list of conditions and the following disclaimer in the documentation
15  *    and/or other materials provided with the distribution.
16  */
17 #include "math.h"
18 #include "angband.h"
19 #include "cave.h"
20 #include "cmds.h"
21 #include "effects.h"
22 #include "game-input.h"
23 #include "generate.h"
24 #include "init.h"
25 #include "mon-make.h"
26 #include "monster.h"
27 #include "obj-init.h"
28 #include "obj-pile.h"
29 #include "obj-randart.h"
30 #include "obj-tval.h"
31 #include "obj-util.h"
32 #include "object.h"
33 #include "ui-command.h"
34 #include "wizard.h"
35 
36 /**
37  * The stats programs here will provide information on the dungeon, the monsters
38  * in it, and the items that they drop.  Statistics are gotten from a given
39  * level by generating a new level, collecting all the items (noting if they
40  * were generated in a vault).  Then all non-unique monsters are killed and
41  * their stats are tracked.
42  * The items from these monster drops are then collected and analyzed.  Lastly,
43  * all unique monsters are killed, and their drops are analyzed.  In this way,
44  * it is possible to separate unique drops and normal monster drops.
45  *
46  * There are two options for simulating the entirety of the dungeon.  There is
47  * a "diving" option that begins each level with all artifacts and uniques
48  * available; and there is a "level-clearing" option that simulates all 100
49  * levels of the dungeon, removing artifacts and uniques as they are
50  * discovered/killed.  "diving" option only catalogues every 5 levels.
51  *
52  * At the end of the "level-clearing" log file, extra post-processing is done
53  * to find the mean and standard deviation for the level you are likely to
54  * first gain an item with a key resistance or item.
55  *
56  * In addition to these sims there is a shorter sim that tests for dungeon
57  * connectivity.
58 */
59 
60 #ifdef USE_STATS
61 
62 /*** Statsgen ***/
63 
64 /* Logfile to store results in */
65 static ang_file *stats_log = NULL;
66 
67  /* this is the size of arrays used to calculate mean and std_dev.
68   * these values will be calculated over the first TRIES_SIZE attempts
69   * or less if TRIES_SIZE is less than tries
70   */
71  #define TRIES_SIZE 100
72  #define MAX_LVL 101
73 
74  /* default for number of tries */
75 int tries=50;
76 /* the simulation number that we are on */
77 int iter;
78 /* amount to add each time an item comes up */
79 static double addval;
80 /* flag for whether we are in clearing mode */
81 bool clearing = false;
82 /* flag for regenning randart */
83 bool regen = false;
84 
85 /*** These are items to track for each iteration ***/
86 /* total number of artifacts found */
87 static int art_it[TRIES_SIZE];
88 
89 /*** handle gold separately ***/
90 /* gold */
91 static double gold_total[MAX_LVL], gold_floor[MAX_LVL], gold_mon[MAX_LVL];
92 
93 
94 typedef enum stat_code
95 {
96 	ST_BEGIN,
97 	ST_EQUIPMENT,
98 	ST_FA_EQUIPMENT,
99 	ST_SI_EQUIPMENT,
100 	ST_RESIST_EQUIPMENT,
101 	ST_RBASE_EQUIPMENT,
102 	ST_RPOIS_EQUIPMENT,
103 	ST_RNEXUS_EQUIPMENT,
104 	ST_RBLIND_EQUIPMENT,
105 	ST_RCONF_EQUIPMENT,
106 	ST_SPEED_EQUIPMENT,
107 	ST_TELEP_EQUIPMENT,
108 	ST_ARMORS,
109 	ST_BAD_ARMOR,
110 	ST_AVERAGE_ARMOR,
111 	ST_GOOD_ARMOR,
112 	ST_STR_ARMOR,
113 	ST_INT_ARMOR,
114 	ST_WIS_ARMOR,
115 	ST_DEX_ARMOR,
116 	ST_CON_ARMOR,
117 	ST_CURSED_ARMOR,
118 	ST_WEAPONS,
119 	ST_BAD_WEAPONS,
120 	ST_AVERAGE_WEAPONS,
121 	ST_GOOD_WEAPONS,
122 	ST_SLAY_WEAPONS,
123 	ST_SLAYEVIL_WEAPONS,
124 	ST_KILL_WEAPONS,
125 	ST_BRAND_WEAPONS,
126 	ST_WESTERNESSE_WEAPONS,
127 	ST_DEFENDER_WEAPONS,
128 	ST_GONDOLIN_WEAPONS,
129 	ST_HOLY_WEAPONS,
130 	ST_XTRABLOWS_WEAPONS,
131 	ST_TELEP_WEAPONS,
132 	ST_HUGE_WEAPONS,
133 	ST_ENDGAME_WEAPONS,
134 	ST_MORGUL_WEAPONS,
135 	ST_BOWS,
136 	ST_BAD_BOWS,
137 	ST_AVERAGE_BOWS,
138 	ST_GOOD_BOWS,
139 	ST_VERYGOOD_BOWS,
140 	ST_XTRAMIGHT_BOWS,
141 	ST_XTRASHOTS_BOWS,
142 	ST_BUCKLAND_BOWS,
143 	ST_TELEP_BOWS,
144 	ST_CURSED_BOWS,
145 	ST_POTIONS,
146 	ST_GAINSTAT_POTIONS,
147 	ST_HEALING_POTIONS,
148 	ST_BIGHEAL_POTIONS,
149 	ST_RESTOREMANA_POTIONS,
150 	ST_SCROLLS,
151 	ST_ENDGAME_SCROLLS,
152 	ST_ACQUIRE_SCROLLS,
153 	ST_RODS,
154 	ST_UTILITY_RODS,
155 	ST_TELEPOTHER_RODS,
156 	ST_DETECTALL_RODS,
157 	ST_ENDGAME_RODS,
158 	ST_STAVES,
159 	ST_SPEED_STAVES,
160 	ST_DESTRUCTION_STAVES,
161 	ST_KILL_STAVES,
162 	ST_ENDGAME_STAVES,
163 	ST_WANDS,
164 	ST_TELEPOTHER_WANDS,
165 	ST_RINGS,
166 	ST_SPEEDS_RINGS,
167 	ST_STAT_RINGS,
168 	ST_RPOIS_RINGS,
169 	ST_FA_RINGS,
170 	ST_SI_RINGS,
171 	ST_BRAND_RINGS,
172 	ST_ELVEN_RINGS,
173 	ST_ONE_RINGS,
174 	ST_CURSED_RINGS,
175 	ST_AMULETS,
176 	ST_WIS_AMULETS,
177 	ST_TELEP_AMULETS,
178 	ST_ENDGAME_AMULETS,
179 	ST_CURSED_AMULETS,
180 	ST_AMMO,
181 	ST_BAD_AMMO,
182 	ST_AVERAGE_AMMO,
183 	ST_GOOD_AMMO,
184 	ST_BRANDSLAY_AMMO,
185 	ST_VERYGOOD_AMMO,
186 	ST_AWESOME_AMMO,
187 	ST_SLAYEVIL_AMMO,
188 	ST_HOLY_AMMO,
189 	ST_BOOKS,
190 	ST_1ST_BOOKS,
191 	ST_2ND_BOOKS,
192 	ST_3RD_BOOKS,
193 	ST_4TH_BOOKS,
194 	ST_5TH_BOOKS,
195 	ST_6TH_BOOKS,
196 	ST_7TH_BOOKS,
197 	ST_8TH_BOOKS,
198 	ST_9TH_BOOKS,
199 	ST_END
200 }
201 stat_code;
202 
203 
204 struct stat_data
205 {
206 	stat_code st;
207 	char *name;
208 };
209 
210 static const struct stat_data stat_message[] =
211 {
212 	{ST_BEGIN, ""},
213 	{ST_EQUIPMENT, "\n ***EQUIPMENT*** \n All:       "},
214 	{ST_FA_EQUIPMENT, " Free Action "},
215 	{ST_SI_EQUIPMENT, " See Invis   "},
216 	{ST_RESIST_EQUIPMENT, " Low Resist  "},
217 	{ST_RBASE_EQUIPMENT, " Resist Base "},
218 	{ST_RPOIS_EQUIPMENT, " Resist Pois "},
219 	{ST_RNEXUS_EQUIPMENT, " Res. Nexus  "},
220 	{ST_RBLIND_EQUIPMENT, " Res. Blind  "},
221 	{ST_RCONF_EQUIPMENT, " Res. Conf.  "},
222 	{ST_SPEED_EQUIPMENT, " Speed       "},
223 	{ST_TELEP_EQUIPMENT, " Telepathy   "},
224 	{ST_ARMORS,  "\n ***ARMOR***      \n All:      "},
225 	{ST_BAD_ARMOR, " Bad         "},
226 	{ST_AVERAGE_ARMOR, " Average     "},
227 	{ST_GOOD_ARMOR, " Good        "},
228 	{ST_STR_ARMOR, " +Strength   "},
229 	{ST_INT_ARMOR, " +Intel.     "},
230 	{ST_WIS_ARMOR, " +Wisdom     "},
231 	{ST_DEX_ARMOR, " +Dexterity  "},
232 	{ST_CON_ARMOR, " +Const.     "},
233 	{ST_CURSED_ARMOR, " Cursed       "},
234 	{ST_WEAPONS, "\n ***WEAPONS***   \n All:       "},
235 	{ST_BAD_WEAPONS, " Bad         "},
236 	{ST_AVERAGE_WEAPONS, " Average     "},
237 	{ST_GOOD_WEAPONS, " Good        "},
238 	{ST_SLAY_WEAPONS, " Weak Slay   "},
239 	{ST_SLAYEVIL_WEAPONS, " Slay evil   "},
240 	{ST_KILL_WEAPONS, " *Slay*      "},
241 	{ST_BRAND_WEAPONS, " Brand       "},
242 	{ST_WESTERNESSE_WEAPONS, " Westernesse "},
243 	{ST_DEFENDER_WEAPONS, " Defender    "},
244 	{ST_GONDOLIN_WEAPONS, " Gondolin    "},
245 	{ST_HOLY_WEAPONS, " Holy Avengr "},
246 	{ST_XTRABLOWS_WEAPONS, " Extra Blows "},
247 	{ST_TELEP_WEAPONS, " Telepathy   "},
248 	{ST_HUGE_WEAPONS, " Huge        "},//MoD, SoS and BoC
249 	{ST_ENDGAME_WEAPONS, " Endgame     "},//MoD, SoS and BoC with slay evil or x2B
250 	{ST_MORGUL_WEAPONS, " Morgul      "},
251 	{ST_BOWS, "\n ***LAUNCHERS*** \n All:        "},
252 	{ST_BAD_BOWS, " Bad         "},
253 	{ST_AVERAGE_BOWS, " Average     "},
254 	{ST_GOOD_BOWS, " Good        "},
255 	{ST_VERYGOOD_BOWS, " Very Good   "},//Power > 15
256 	{ST_XTRAMIGHT_BOWS, " Extra might "},
257 	{ST_XTRASHOTS_BOWS, " Extra shots "},
258 	{ST_BUCKLAND_BOWS, " Buckland    "},
259 	{ST_TELEP_BOWS, " Telepathy   "},
260 	{ST_CURSED_BOWS, " Cursed      "},
261 	{ST_POTIONS, "\n ***POTIONS***   \n All:        "},
262 	{ST_GAINSTAT_POTIONS, " Gain stat   "},//includes *enlight*
263 	{ST_HEALING_POTIONS, " Healing     "},
264 	{ST_BIGHEAL_POTIONS, " Big heal    "},//*heal* and life
265 	{ST_RESTOREMANA_POTIONS, " Rest. Mana  "},
266 	{ST_SCROLLS, "\n ***SCROLLS***   \n All:        "},
267 	{ST_ENDGAME_SCROLLS, " Endgame     "},// destruction, banish, mass banish, rune
268 	{ST_ACQUIRE_SCROLLS, " Acquire.    "},
269 	{ST_RODS, "\n ***RODS***      \n All:        "},
270 	{ST_UTILITY_RODS, " Utility     "},//dtrap, dstairs, dobj, light, illum
271 	{ST_TELEPOTHER_RODS, " Tele Other  "},
272 	{ST_DETECTALL_RODS, " Detect all  "},
273 	{ST_ENDGAME_RODS, " Endgame     "},//speed, healing
274 	{ST_STAVES, "\n ***STAVES***    \n All:        "},
275 	{ST_SPEED_STAVES, " Speed       "},
276 	{ST_DESTRUCTION_STAVES, " Destruction "},
277 	{ST_KILL_STAVES, " Kill        "},//dispel evil, power, holiness
278 	{ST_ENDGAME_STAVES, " Endgame     "},//healing, magi, banishment
279 	{ST_WANDS, "\n ***WANDS***     \n All:        "},
280 	{ST_TELEPOTHER_WANDS, " Tele Other  "},
281 	{ST_RINGS, "\n ***RINGS***     \n All:        "},
282 	{ST_SPEEDS_RINGS, " Speed       "},
283 	{ST_STAT_RINGS, " Stat        "},//str, dex, con, int
284 	{ST_RPOIS_RINGS, " Res. Pois.  "},
285 	{ST_FA_RINGS, " Free Action "},
286 	{ST_SI_RINGS, " See Invis.  "},
287 	{ST_BRAND_RINGS, " Brand       "},
288 	{ST_ELVEN_RINGS, " Elven       "},
289 	{ST_ONE_RINGS, " The One     "},
290 	{ST_CURSED_RINGS, " Cursed      "},
291 	{ST_RINGS, "\n ***AMULETS***   \n All:        "},
292 	{ST_WIS_AMULETS, " Wisdom      "},
293 	{ST_TELEP_AMULETS, " Telepathy   "},
294 	{ST_ENDGAME_AMULETS, " Endgame     "},//Trickery, weaponmastery, magi
295 	{ST_CURSED_AMULETS, " Cursed      "},
296 	{ST_AMMO, "\n ***AMMO***      \n All:        "},
297 	{ST_BAD_AMMO, " Bad         "},
298 	{ST_AVERAGE_AMMO, " Average     "},
299 	{ST_GOOD_AMMO, " Good        "},
300 	{ST_BAD_AMMO, " Brand       "},
301 	{ST_VERYGOOD_AMMO, " Very Good   "},//seeker or mithril
302 	{ST_AWESOME_AMMO, " Awesome     "},//seeker, mithril + brand
303 	{ST_SLAYEVIL_AMMO, " Slay evil   "},
304 	{ST_HOLY_AMMO, " Holy might  "},
305 	{ST_BOOKS, "\n ***BOOKS***     \n All:        "},
306 	{ST_1ST_BOOKS, " Book 1      "},
307 	{ST_2ND_BOOKS, " Book 2      "},
308 	{ST_3RD_BOOKS, " Book 3      "},
309 	{ST_4TH_BOOKS, " Book 4      "},
310 	{ST_5TH_BOOKS, " Book 5      "},
311 	{ST_6TH_BOOKS, " Book 6      "},
312 	{ST_7TH_BOOKS, " Book 7      "},
313 	{ST_8TH_BOOKS, " Book 8      "},
314 	{ST_9TH_BOOKS, " Book 9      "},
315 };
316 
317 double stat_all[ST_END][3][MAX_LVL];
318 
319 /* Values for things we want to find the level where it's
320  * most likely to be first found */
321 typedef enum stat_first_find
322 {
323 	ST_FF_BEGIN,
324 	ST_FF_FA,
325 	ST_FF_SI,
326 	ST_FF_RPOIS,
327 	ST_FF_RNEXUS,
328 	ST_FF_RCONF,
329 	ST_FF_RBLIND,
330 	ST_FF_TELEP,
331 	ST_FF_BOOK1,
332 	ST_FF_BOOK2,
333 	ST_FF_BOOK3,
334 	ST_FF_BOOK4,
335 	ST_FF_BOOK5,
336 	ST_FF_BOOK6,
337 	ST_FF_BOOK7,
338 	ST_FF_BOOK8,
339 	ST_FF_BOOK9,
340 	ST_FF_END
341 }
342 stat_first_find;
343 
344 struct stat_ff_data
345 {
346 	stat_first_find st_ff;
347 	stat_code st;
348 	char *name;
349 };
350 
351 static const struct stat_ff_data stat_ff_message[] =
352 {
353 	{ST_FF_BEGIN,ST_BEGIN,""},
354 	{ST_FF_FA,	ST_FA_EQUIPMENT,		"FA     \t"},
355 	{ST_FF_SI,	ST_SI_EQUIPMENT,		"SI     \t"},
356 	{ST_FF_RPOIS,	ST_RPOIS_EQUIPMENT,	"Rpois  \t"},
357 	{ST_FF_RNEXUS,	ST_RNEXUS_EQUIPMENT,  "Rnexus \t"},
358 	{ST_FF_RCONF,	ST_RCONF_EQUIPMENT,	"Rconf  \t"},
359 	{ST_FF_RBLIND,	ST_RBLIND_EQUIPMENT,	"Rblind \t"},
360 	{ST_FF_TELEP,	ST_TELEP_EQUIPMENT,	"Telep  \t"},
361 	{ST_FF_BOOK1,	ST_1ST_BOOKS,	"Book1  \t"},
362 	{ST_FF_BOOK2,	ST_2ND_BOOKS, 	"Book2  \t"},
363 	{ST_FF_BOOK3,	ST_3RD_BOOKS,	"Book3  \t"},
364 	{ST_FF_BOOK4,	ST_4TH_BOOKS,	"Book4  \t"},
365 	{ST_FF_BOOK5,	ST_5TH_BOOKS,	"Book5  \t"},
366 	{ST_FF_BOOK6,	ST_6TH_BOOKS,	"Book6  \t"},
367 	{ST_FF_BOOK7,	ST_7TH_BOOKS,	"Book7  \t"},
368 	{ST_FF_BOOK8,	ST_8TH_BOOKS,	"Book8	\t"},
369 	{ST_FF_BOOK9,	ST_9TH_BOOKS,	"Book9  \t"},
370 };
371 
372 int stat_ff_all[ST_FF_END][TRIES_SIZE];
373 
374 
375 
376 /* basic artifact info */
377 static double art_total[MAX_LVL], art_spec[MAX_LVL], art_norm[MAX_LVL];
378 
379 /* artifact level info */
380 static double art_shal[MAX_LVL], art_ave[MAX_LVL], art_ood[MAX_LVL];
381 
382 /* where normal artifacts come from */
383 static double art_mon[MAX_LVL], art_uniq[MAX_LVL], art_floor[MAX_LVL], art_vault[MAX_LVL], art_mon_vault[MAX_LVL];
384 
385 
386 
387 /* monster info */
388 static double mon_total[MAX_LVL], mon_ood[MAX_LVL], mon_deadly[MAX_LVL];
389 
390 /* unique info */
391 static double uniq_total[MAX_LVL], uniq_ood[MAX_LVL], uniq_deadly[MAX_LVL];
392 
393 
394 /* set everything to 0.0 to begin */
init_stat_vals()395 static void init_stat_vals()
396 {
397 	int i,j,k;
398 
399 	for (i = 0; i < ST_END;i++)
400 		for (j = 0; j < 3; k = j++)
401 			for (k = 0; k < MAX_LVL; k++)
402 				stat_all[i][j][k] = 0.0;
403 
404 	for (i = 1; i < TRIES_SIZE; i++)
405 		art_it[i] = 0;
406 
407 	for (i = 0; i < ST_FF_END; i++)
408 		for (j = 0; j < TRIES_SIZE; j++)
409 			stat_ff_all[i][j] = 0.0;
410 }
411 
412 /*
413  *	Record the first level we find something
414  */
first_find(stat_first_find st)415 static bool first_find(stat_first_find st)
416 {
417 	/* make sure we're not on an iteration above our array limit */
418 	if (iter >= TRIES_SIZE) return false;
419 
420 	/* make sure we haven't found it earlier on this iteration */
421 	if (stat_ff_all[st][iter] > 0) return false;
422 
423 	/* assign the depth to this value */
424 	stat_ff_all[st][iter] = player->depth;
425 
426 	/* success */
427 	return true;
428 }
429 
430 /*
431  * Add the number of drops for a specifci stat
432  */
add_stats(stat_code st,bool vault,bool mon,int number)433 static void add_stats(stat_code st, bool vault, bool mon, int number)
434 {
435 	int lvl;
436 
437 	/* get player level */
438 	lvl=player->depth;
439 
440 	/* be careful about bounds */
441 	if ((lvl > MAX_LVL) || (lvl < 0)) return;
442 
443 	/* add to the total */
444 	stat_all[st][0][lvl] += addval * number;
445 
446 	/* add to the total from vaults */
447 	if ((!mon) && (vault)) stat_all[st][2][lvl] += addval * number;
448 
449 	/* add to the total from monsters */
450 	if (mon) stat_all[st][1][lvl] += addval * number;
451 
452 }
453 
454 /*
455  * This will get data on an object
456  * It gets a lot of stuff, pretty much everything that I
457  * thought was reasonable to get.  However, you might have
458  * a much different opinion.  Luckily, I tried to make it
459  * trivial to add new items to log.
460 */
get_obj_data(const struct object * obj,int y,int x,bool mon,bool uniq)461 static void get_obj_data(const struct object *obj, int y, int x, bool mon,
462 						 bool uniq)
463 {
464 
465 	bool vault = square_isvault(cave, loc(x, y));
466 	int number = obj->number;
467 	static int lvl;
468 	struct artifact *art;
469 
470 	double gold_temp = 0;
471 
472 	assert(obj->kind);
473 
474 	/* get player depth */
475 	lvl = player->depth;
476 
477 	/* check for some stuff that we will use regardless of type */
478 	/* originally this was armor, but I decided to generalize it */
479 
480 	/* has free action (hack: don't include Inertia)*/
481 	if (of_has(obj->flags, OF_FREE_ACT) &&
482 		!((obj->tval == TV_AMULET) &&
483 		  (!strstr(obj->kind->name, "Inertia")))) {
484 
485 			/* add the stats */
486 			add_stats(ST_FA_EQUIPMENT, vault, mon, number);
487 
488 			/* record first level */
489 			first_find(ST_FF_FA);
490 		}
491 
492 
493 	/* has see invis */
494 	if (of_has(obj->flags, OF_SEE_INVIS)){
495 
496 		add_stats(ST_SI_EQUIPMENT, vault, mon, number);
497 		first_find(ST_FF_SI);
498 	}
499 	/* has at least one basic resist */
500  	if ((obj->el_info[ELEM_ACID].res_level == 1) ||
501 		(obj->el_info[ELEM_ELEC].res_level == 1) ||
502 		(obj->el_info[ELEM_COLD].res_level == 1) ||
503 		(obj->el_info[ELEM_FIRE].res_level == 1)){
504 
505 			add_stats(ST_RESIST_EQUIPMENT, vault, mon, number);
506 	}
507 
508 	/* has rbase */
509 	if ((obj->el_info[ELEM_ACID].res_level == 1) &&
510 		(obj->el_info[ELEM_ELEC].res_level == 1) &&
511 		(obj->el_info[ELEM_COLD].res_level == 1) &&
512 		(obj->el_info[ELEM_FIRE].res_level == 1))
513 		add_stats(ST_RBASE_EQUIPMENT, vault, mon, number);
514 
515 	/* has resist poison */
516 	if (obj->el_info[ELEM_POIS].res_level == 1){
517 
518 		add_stats(ST_RPOIS_EQUIPMENT, vault, mon, number);
519 		first_find(ST_FF_RPOIS);
520 
521 	}
522 	/* has resist nexus */
523 	if (obj->el_info[ELEM_NEXUS].res_level == 1){
524 
525 		add_stats(ST_RNEXUS_EQUIPMENT, vault, mon, number);
526 		first_find(ST_FF_RNEXUS);
527 	}
528 	/* has resist blind */
529 	if (of_has(obj->flags, OF_PROT_BLIND)){
530 
531 		add_stats(ST_RBLIND_EQUIPMENT, vault, mon, number);
532 		first_find(ST_FF_RBLIND);
533 	}
534 
535 	/* has resist conf */
536 	if (of_has(obj->flags, OF_PROT_CONF)){
537 
538 		add_stats(ST_RCONF_EQUIPMENT, vault, mon, number);
539 		first_find(ST_FF_RCONF);
540 	}
541 
542 	/* has speed */
543 	if (obj->modifiers[OBJ_MOD_SPEED] != 0)
544 		add_stats(ST_SPEED_EQUIPMENT, vault, mon, number);
545 
546 	/* has telepathy */
547 	if (of_has(obj->flags, OF_TELEPATHY)){
548 
549 		add_stats(ST_TELEP_EQUIPMENT, vault, mon, number);
550 		first_find(ST_FF_TELEP);
551 	}
552 
553 	switch(obj->tval){
554 
555 		/* armor */
556 		case TV_BOOTS:
557 		case TV_GLOVES:
558 		case TV_HELM:
559 		case TV_CROWN:
560 		case TV_SHIELD:
561 		case TV_CLOAK:
562 		case TV_SOFT_ARMOR:
563 		case TV_HARD_ARMOR:
564 		case TV_DRAG_ARMOR:{
565 
566 			/* do not include artifacts */
567 			if (obj->artifact) break;
568 
569 			/* add to armor total */
570 			add_stats(ST_ARMORS, vault, mon, number);
571 
572 			/* check if bad, good, or average */
573 			if (obj->to_a < 0)
574 				add_stats(ST_BAD_ARMOR, vault, mon, number);
575 			if (obj->to_h == 0)
576 				add_stats(ST_AVERAGE_ARMOR, vault, mon, number);
577 			if (obj->to_h > 0)
578 				add_stats(ST_GOOD_ARMOR, vault, mon, number);
579 
580 			/* has str boost */
581 			if (obj->modifiers[OBJ_MOD_STR] != 0)
582 				add_stats(ST_STR_ARMOR, vault, mon, number);
583 
584 			/* has dex boost */
585 			if (obj->modifiers[OBJ_MOD_DEX] != 0)
586 				add_stats(ST_DEX_ARMOR, vault, mon, number);
587 
588 			/* has int boost */
589 			if (obj->modifiers[OBJ_MOD_INT] != 0)
590 				add_stats(ST_INT_ARMOR, vault, mon, number);
591 
592 			if (obj->modifiers[OBJ_MOD_WIS] != 0)
593 				add_stats(ST_WIS_ARMOR, vault, mon, number);
594 
595 			if (obj->modifiers[OBJ_MOD_CON] != 0)
596 				add_stats(ST_CON_ARMOR, vault, mon, number);
597 
598 			if (obj->curses)
599 				add_stats(ST_CURSED_ARMOR, vault, mon, number);
600 
601 			break;
602 		}
603 
604 		/* weapons */
605 		case TV_DIGGING:
606 		case TV_HAFTED:
607 		case TV_POLEARM:
608 		case TV_SWORD:{
609 
610 			/* do not include artifacts */
611 			if (obj->artifact) break;
612 
613 			/* add to weapon total */
614 			add_stats(ST_WEAPONS, vault, mon, number);
615 
616 			/* check if bad, good, or average */
617 			if ((obj->to_h < 0)  && (obj->to_d < 0))
618 				add_stats(ST_BAD_WEAPONS, vault, mon, number);
619 			if ((obj->to_h == 0) && (obj->to_d == 0))
620 				add_stats(ST_AVERAGE_WEAPONS, vault, mon, number);
621 			if ((obj->to_h > 0) && (obj->to_d > 0))
622 				add_stats(ST_GOOD_WEAPONS, vault, mon, number);
623 
624 			/* Egos by name - changes results a little */
625 			if (obj->ego) {
626 				/* slay evil */
627 				if (strstr(obj->ego->name, "of Slay Evil"))
628 					add_stats(ST_SLAYEVIL_WEAPONS, vault, mon, number);
629 
630 				/* slay weapons */
631 				else if (strstr(obj->ego->name, "of Slay"))
632 					add_stats(ST_SLAY_WEAPONS, vault, mon, number);
633 				/* kill flag */
634 				if (strstr(obj->ego->name, "of *Slay"))
635 					add_stats(ST_KILL_WEAPONS, vault, mon, number);
636 
637 				/* determine westernesse by flags */
638 				if (strstr(obj->ego->name, "Westernesse"))
639 					add_stats(ST_WESTERNESSE_WEAPONS, vault, mon, number);
640 
641 				/* determine defender by flags */
642 				if (strstr(obj->ego->name, "Defender"))
643 					add_stats(ST_DEFENDER_WEAPONS, vault, mon, number);
644 
645 				/* determine gondolin by flags */
646 				if (strstr(obj->ego->name, "Gondolin"))
647 					add_stats(ST_GONDOLIN_WEAPONS, vault, mon, number);
648 
649 				/* determine holy avenger by flags */
650 				if (strstr(obj->ego->name, "Avenger"))
651 					add_stats(ST_HOLY_WEAPONS, vault, mon, number);
652 
653 				/* is morgul */
654 				if (strstr(obj->ego->name, "Morgul"))
655 					add_stats(ST_MORGUL_WEAPONS, vault, mon, number);
656 			}
657 
658 			/* branded weapons */
659 			if (obj->brands)
660 				add_stats(ST_BRAND_WEAPONS, vault, mon, number);
661 
662 			/* extra blows */
663 			if (obj->modifiers[OBJ_MOD_BLOWS] > 0)
664 				add_stats(ST_XTRABLOWS_WEAPONS, vault, mon, number);
665 
666 			/* telepathy */
667 			if (of_has(obj->flags, OF_TELEPATHY))
668 				add_stats(ST_TELEP_WEAPONS, vault, mon, number);
669 
670 			/* is a top of the line weapon */
671 			if (((obj->tval == TV_HAFTED) &&
672 				 (!strstr(obj->kind->name, "Disruption"))) ||
673 				((obj->tval == TV_POLEARM) &&
674 				 (!strstr(obj->kind->name, "Slicing"))) ||
675 				((obj->tval == TV_SWORD) &&
676 				 (!strstr(obj->kind->name, "Chaos")))) {
677 				add_stats(ST_HUGE_WEAPONS, vault, mon, number);
678 
679 				/* is uber need to fix ACB
680 				if ((of_has(obj->flags, OF_SLAY_EVIL)) || (obj->modifiers[OBJ_MOD_BLOWS] > 0))
681 				add_stats(ST_UBWE, vault, mon, number); */
682 
683 			}
684 
685 			break;
686 		}
687 
688 		/* launchers */
689 		case TV_BOW:{
690 
691 			/* do not include artifacts */
692 			if (obj->artifact) break;
693 
694 			/* add to launcher total */
695 			add_stats(ST_BOWS, vault, mon, number);
696 
697 			/* check if bad, average, good, or very good */
698 			if ((obj->to_h < 0) && (obj->to_d < 0))
699 				add_stats(ST_BAD_BOWS, vault, mon, number);
700 			if ((obj->to_h == 0) && (obj->to_d == 0))
701 				add_stats(ST_AVERAGE_BOWS, vault, mon, number);
702 			if ((obj->to_h > 0) && (obj->to_d > 0))
703 				add_stats(ST_GOOD_BOWS, vault, mon, number);
704 			if ((obj->to_h > 15) || (obj->to_d > 15))
705 				add_stats(ST_VERYGOOD_BOWS, vault, mon, number);
706 
707 			/* check long bows and xbows for xtra might and/or shots */
708 			if (obj->pval > 2)
709 			{
710 				if (obj->modifiers[OBJ_MOD_SHOTS] > 0)
711 					add_stats(ST_XTRASHOTS_BOWS, vault, mon, number);
712 
713 				if (obj->modifiers[OBJ_MOD_MIGHT] > 0)
714 					add_stats(ST_XTRAMIGHT_BOWS, vault, mon, number);
715 			}
716 
717 			/* check for buckland */
718 			if ((obj->pval == 2) &&
719 				kf_has(obj->kind->kind_flags, KF_SHOOTS_SHOTS) &&
720 				(obj->modifiers[OBJ_MOD_MIGHT] > 0) &&
721 				(obj->modifiers[OBJ_MOD_SHOTS] > 0))
722 					add_stats(ST_BUCKLAND_BOWS, vault, mon, number);
723 
724 			/* has telep */
725 			if (of_has(obj->flags, OF_TELEPATHY))
726 				add_stats(ST_TELEP_BOWS, vault, mon, number);
727 
728 			/* is cursed */
729 			if (obj->curses)
730 				add_stats(ST_CURSED_BOWS, vault, mon, number);
731 			break;
732 		}
733 
734 		/* potion */
735 		case TV_POTION:{
736 
737 			/* Add total amounts */
738 			add_stats(ST_POTIONS, vault, mon, number);
739 
740 			/* Stat gain */
741 			if (strstr(obj->kind->name, "Strength") ||
742 				strstr(obj->kind->name, "Intelligence") ||
743 				strstr(obj->kind->name, "Wisdom") ||
744 				strstr(obj->kind->name, "Dexterity") ||
745 				strstr(obj->kind->name, "Constitution")) {
746 				add_stats(ST_GAINSTAT_POTIONS, vault, mon, number);
747 			} else if (strstr(obj->kind->name, "Augmentation")) {
748 				/* Augmentation counts as 5 stat gain pots */
749 				add_stats(ST_GAINSTAT_POTIONS, vault, mon, number * 5);
750 			} else if (strstr(obj->kind->name, "*Enlightenment*")) {
751 				/* *Enlight* counts as 2 stat pots */
752 				add_stats(ST_GAINSTAT_POTIONS, vault, mon, number * 2);
753 			} else if (strstr(obj->kind->name, "Restore Mana")) {
754 				add_stats(ST_RESTOREMANA_POTIONS, vault, mon, number);
755 			} else if ((strstr(obj->kind->name, "Life")) ||
756 					   (strstr(obj->kind->name, "*Healing*"))) {
757 				add_stats(ST_ELVEN_RINGS, vault, mon, number);
758 			} else if (strstr(obj->kind->name, "Healing")) {
759 				add_stats(ST_HEALING_POTIONS, vault, mon, number);
760 			}
761 			break;
762 		}
763 
764 		/* scrolls */
765 		case TV_SCROLL:{
766 
767 			/* add total amounts */
768 			add_stats(ST_SCROLLS, vault, mon, number);
769 
770 			if (strstr(obj->kind->name, "Banishment") ||
771 				strstr(obj->kind->name, "Mass Banishment") ||
772 				strstr(obj->kind->name, "Rune of Protection") ||
773 				strstr(obj->kind->name, "*Destruction*")) {
774 				add_stats(ST_ENDGAME_SCROLLS, vault, mon, number);
775 			} else if (strstr(obj->kind->name, "Acquirement")) {
776 				add_stats(ST_ACQUIRE_SCROLLS, vault, mon, number);
777 			} else if (strstr(obj->kind->name, "*Acquirement*")) {
778 				/* do the effect of 2 acquires */
779 				add_stats(ST_ACQUIRE_SCROLLS, vault, mon, number * 2);
780 			}
781 			break;
782 		}
783 
784 		/* rods */
785 		case TV_ROD:{
786 
787 			/* add to total */
788 			add_stats(ST_RODS, vault, mon, number);
789 
790 			if (strstr(obj->kind->name, "Trap Detection") ||
791 				strstr(obj->kind->name, "Treasure Detection") ||
792 				strstr(obj->kind->name, "Door/Stair Location") ||
793 				strstr(obj->kind->name, "Illumination") ||
794 				strstr(obj->kind->name, "Light")) {
795 				add_stats(ST_UTILITY_RODS, vault, mon, number);
796 			} else if (strstr(obj->kind->name, "Teleport Other")) {
797 				add_stats(ST_TELEPOTHER_RODS, vault, mon, number);
798 			} else if (strstr(obj->kind->name, "Detection")) {
799 				add_stats(ST_DETECTALL_RODS, vault, mon, number);
800 			} else if (strstr(obj->kind->name, "Speed") ||
801 					   strstr(obj->kind->name, "Healing")) {
802 				add_stats(ST_ENDGAME_RODS, vault, mon, number);
803 			}
804 			break;
805 		}
806 
807 		/* staves */
808 		case TV_STAFF:{
809 
810 			add_stats(ST_STAVES, vault, mon, number);
811 
812 			if (strstr(obj->kind->name, "Speed")) {
813 				add_stats(ST_SPEED_STAVES, vault, mon, number);
814 			} else if (strstr(obj->kind->name, "*Destruction*")) {
815 				add_stats(ST_DESTRUCTION_STAVES, vault, mon, number);
816 			} else if (strstr(obj->kind->name, "Dispel Evil") ||
817 					   strstr(obj->kind->name, "Power") ||
818 					   strstr(obj->kind->name, "Holiness")) {
819 				add_stats(ST_KILL_STAVES, vault, mon, number);
820 			} else if (strstr(obj->kind->name, "Healing") ||
821 					   strstr(obj->kind->name, "Banishment") ||
822 					   strstr(obj->kind->name, "the Magi")) {
823 				add_stats(ST_ENDGAME_STAVES, vault, mon, number);
824 			}
825 			break;
826 		}
827 
828 		case TV_WAND:{
829 
830 			add_stats(ST_WANDS, vault, mon, number);
831 
832 			if (strstr(obj->kind->name, "Teleport Other"))
833 				add_stats(ST_TELEPOTHER_WANDS, vault, mon, number);
834 			break;
835 		}
836 
837 		case TV_RING:{
838 
839 			add_stats(ST_RINGS, vault, mon, number);
840 
841 			/* is it cursed */
842 			if (obj->curses)
843 				add_stats(ST_CURSED_RINGS, vault, mon, number);
844 
845 			if (strstr(obj->kind->name, "Speed")) {
846 				add_stats(ST_SPEEDS_RINGS, vault, mon, number);
847 			} else if ((strstr(obj->kind->name, "Strength")) ||
848 					   (strstr(obj->kind->name, "Intelligence")) ||
849 					   (strstr(obj->kind->name, "Dexterity")) ||
850 					   (strstr(obj->kind->name, "Constitution"))) {
851 				add_stats(ST_STAT_RINGS, vault, mon, number);
852 			} else if (strstr(obj->kind->name, "Resist Poison")) {
853 				add_stats(ST_RPOIS_RINGS, vault, mon, number);
854 			} else if (strstr(obj->kind->name, "Free Action")) {
855 				add_stats(ST_FA_RINGS, vault, mon, number);
856 			} else if (strstr(obj->kind->name, "See invisible")) {
857 				add_stats(ST_SI_RINGS, vault, mon, number);
858 			} else if ((strstr(obj->kind->name, "Flames")) ||
859 					   (strstr(obj->kind->name, "Ice")) ||
860 					   (strstr(obj->kind->name, "Acid")) ||
861 					   (strstr(obj->kind->name, "Lightning"))) {
862 				add_stats(ST_BRAND_RINGS, vault, mon, number);
863 			} else if ((strstr(obj->kind->name, "Fire")) ||
864 					   (strstr(obj->kind->name, "Adamant")) ||
865 					   (strstr(obj->kind->name, "Firmament"))) {
866 				add_stats(ST_ELVEN_RINGS, vault, mon, number);
867 			} else if (strstr(obj->kind->name, "Power")) {
868 				add_stats(ST_ONE_RINGS, vault, mon, number);
869 			}
870 
871 
872 			break;
873 		}
874 
875 		case TV_AMULET:{
876 
877 			add_stats(ST_AMULETS, vault, mon, number);
878 
879 			if (strstr(obj->kind->name, "Wisdom")) {
880 				add_stats(ST_WIS_AMULETS, vault, mon, number);
881 			} else if ((strstr(obj->kind->name, "Magi")) ||
882 					   (strstr(obj->kind->name, "Trickery")) ||
883 					   (strstr(obj->kind->name, "Weaponmastery"))) {
884 				add_stats(ST_ENDGAME_AMULETS, vault, mon, number);
885 			} else if (strstr(obj->kind->name, "ESP")) {
886 				add_stats(ST_TELEP_AMULETS, vault, mon, number);
887 			}
888 
889 			/* is cursed */
890 			if (obj->curses)
891 				add_stats(ST_CURSED_AMULETS, vault, mon, number);
892 
893 			break;
894 		}
895 
896 		case TV_SHOT:
897 		case TV_ARROW:
898 		case TV_BOLT:{
899 
900 			add_stats(ST_AMMO, vault, mon, number);
901 
902 			/* check if bad, average, good */
903 			if ((obj->to_h < 0) && (obj->to_d < 0))
904 				add_stats(ST_BAD_AMMO, vault, mon, number);
905 			if ((obj->to_h == 0) && (obj->to_d == 0))
906 				add_stats(ST_AVERAGE_AMMO, vault, mon, number);
907 			if ((obj->to_h > 0) && (obj->to_d > 0))
908 				add_stats(ST_GOOD_AMMO, vault, mon, number);
909 
910 			if (obj->ego)
911 				add_stats(ST_BRANDSLAY_AMMO, vault, mon, number);
912 
913 			if (strstr(obj->kind->name, "Seeker") ||
914 				strstr(obj->kind->name, "Mithril")) {
915 
916 				/* Mithril and seeker ammo */
917 				add_stats(ST_VERYGOOD_AMMO, vault, mon, number);
918 
919 				/* Ego mithril and seeker ammo */
920 				if (obj->ego) {
921 					add_stats(ST_AWESOME_AMMO, vault, mon, number);
922 
923 					if (strstr(obj->ego->name, "of Slay Evil"))
924 						add_stats(ST_SLAYEVIL_AMMO, vault, mon, number);
925 
926 					if (strstr(obj->ego->name, "of Holy Might"))
927 						add_stats(ST_HOLY_AMMO, vault, mon, number);
928 				}
929 			}
930 			break;
931 		}
932 
933 		/* books have the same probability, only track one realm of them */
934 		case TV_MAGIC_BOOK:{
935 
936 			switch(obj->sval){
937 
938 				/* svals begin at 0 and end at 8 */
939 				case 0:{
940 
941 					add_stats(ST_1ST_BOOKS, vault, mon, number);
942 					first_find(ST_FF_BOOK1);
943 					break;
944 				}
945 
946 				case 1:{
947 
948 					add_stats(ST_2ND_BOOKS, vault, mon, number);
949 					first_find(ST_FF_BOOK2);
950 					break;
951 				}
952 
953 				case 2:{
954 
955 					add_stats(ST_3RD_BOOKS, vault, mon, number);
956 					first_find(ST_FF_BOOK3);
957 					break;
958 				}
959 
960 				case 3:{
961 
962 					add_stats(ST_4TH_BOOKS, vault, mon, number);
963 					first_find(ST_FF_BOOK4);
964 					break;
965 				}
966 
967 				case 4:{
968 
969 					add_stats(ST_5TH_BOOKS, vault, mon, number);
970 					first_find(ST_FF_BOOK5);
971 					break;
972 				}
973 
974 				case 5:{
975 
976 					add_stats(ST_6TH_BOOKS, vault, mon, number);
977 					first_find(ST_FF_BOOK6);
978 					break;
979 				}
980 
981 				case 6:{
982 
983 					add_stats(ST_7TH_BOOKS, vault, mon, number);
984 					first_find(ST_FF_BOOK7);
985 					break;
986 				}
987 
988 				case 7:{
989 
990 					add_stats(ST_8TH_BOOKS, vault, mon, number);
991 					first_find(ST_FF_BOOK8);
992 					break;
993 				}
994 
995 				case 8:{
996 
997 					add_stats(ST_9TH_BOOKS, vault, mon, number);
998 					first_find(ST_FF_BOOK9);
999 					break;
1000 				}
1001 
1002 
1003 			}
1004 			break;
1005 		}
1006 	}
1007 	/* check to see if we have an artifact */
1008 	if (obj->artifact){
1009 
1010 		/* add to artifact level total */
1011 		art_total[lvl] += addval;
1012 
1013 		/* add to the artifact iteration total */
1014 		if (iter < TRIES_SIZE) art_it[iter]++;
1015 
1016 		/* Obtain the artifact info */
1017 		art = obj->artifact;
1018 
1019 		//debugging, print out that we found the artifact
1020 		//msg_format("Found artifact %s",art->name);
1021 
1022 		/* artifact is shallow */
1023 		if (art->alloc_min < (player->depth - 20)) art_shal[lvl] += addval;
1024 
1025 		/* artifact is close to the player depth */
1026 		if ((art->alloc_min >= player->depth - 20) &&
1027 			(art->alloc_min <= player->depth )) art_ave[lvl] += addval;
1028 
1029 		/* artifact is out of depth */
1030 		if (art->alloc_min > (player->depth)) art_ood[lvl] += addval;
1031 
1032 		/* check to see if it's a special artifact */
1033 		if ((obj->tval == TV_LIGHT) || (obj->tval == TV_AMULET)
1034 			|| (obj->tval == TV_RING)){
1035 
1036 			/* increment special artifact counter */
1037 			art_spec[lvl] += addval;
1038 		} else {
1039 			/* increment normal artifacts */
1040 			art_norm[lvl] += addval;
1041 
1042 			/* did it come from a monster? */
1043 			if (mon) art_mon[lvl] += addval;
1044 
1045 			/* did it come from a unique? */
1046 			if (uniq) art_uniq[lvl] += addval;
1047 
1048 			/* was it in a vault? */
1049 			if (vault){
1050 
1051 				/* did a monster drop it ?*/
1052 				if ((mon) || (uniq)) art_mon_vault[lvl] += addval;
1053 				else art_vault[lvl] += addval;
1054 			} else {
1055 				/* was it just lyin' on the floor? */
1056 				if ((!uniq) && (!mon)) art_floor[lvl] += addval;
1057 			}
1058 		}
1059 		/* preserve the artifact */
1060 		if (!(clearing)) art->created = false;
1061 	}
1062 
1063 	/* Get info on gold. */
1064 	if (obj->tval == TV_GOLD){
1065 
1066 		int temp = obj->pval;
1067 		gold_temp = temp;
1068 	    gold_total[lvl] += (gold_temp / tries);
1069 
1070 		/*From a monster? */
1071 		if ((mon) || (uniq)) gold_mon[lvl] += (gold_temp / tries);
1072 		else gold_floor[lvl] += (gold_temp / tries);
1073 	}
1074 
1075 }
1076 
1077 
1078 
1079 /*
1080  * A rewrite of monster death that gets rid of some features
1081  * That we don't want to deal with.  Namely, no notifying the
1082  * player and no generation of Morgoth artifacts
1083  *
1084  * It also replaces drop near with a new function that drops all
1085  * the items on the exact square that the monster was on.
1086  */
monster_death_stats(int m_idx)1087 void monster_death_stats(int m_idx)
1088 {
1089 	struct object *obj;
1090 	struct monster *mon;
1091 	bool uniq;
1092 
1093 	assert(m_idx > 0);
1094 	mon = cave_monster(cave, m_idx);
1095 
1096 	/* Check if monster is UNIQUE */
1097 	uniq = rf_has(mon->race->flags,RF_UNIQUE);
1098 
1099 	/* Mimicked objects will have already been counted as floor objects */
1100 	mon->mimicked_obj = NULL;
1101 
1102 	/* Drop objects being carried */
1103 	obj = mon->held_obj;
1104 	while (obj) {
1105 		struct object *next = obj->next;
1106 
1107 		/* Object no longer held */
1108 		obj->held_m_idx = 0;
1109 
1110 		/* Get data */
1111 		get_obj_data(obj, mon->grid.y, mon->grid.x, true, uniq);
1112 
1113 		/* Delete the object */
1114 		delist_object(cave, obj);
1115 		object_delete(&obj);
1116 
1117 		/* Next */
1118 		obj = next;
1119 	}
1120 
1121 	/* Forget objects */
1122 	mon->held_obj = NULL;
1123 }
1124 
1125 
1126 
1127 /**
1128  * This will collect stats on a monster avoiding all unique monsters.
1129  * Afterwards it will kill the monsters.
1130  */
stats_monster(struct monster * mon,int i)1131 static bool stats_monster(struct monster *mon, int i)
1132 {
1133 	static int lvl;
1134 
1135 	/* get player depth */
1136 	lvl = player->depth;
1137 
1138 
1139 	/* Increment monster count */
1140 	mon_total[lvl] += addval;
1141 
1142 	/* Increment unique count if appropriate */
1143 	if (rf_has(mon->race->flags, RF_UNIQUE)){
1144 
1145 		/* add to total */
1146 		uniq_total[lvl] += addval;
1147 
1148 		/* kill the unique if we're in clearing mode */
1149 		if (clearing) mon->race->max_num = 0;
1150 
1151 		/* debugging print that we killed it
1152 		   msg_format("Killed %s",race->name); */
1153 	}
1154 
1155 	/* Is it mostly dangerous (10 levels ood or less?)*/
1156 	if ((mon->race->level > player->depth) &&
1157 		(mon->race->level <= player->depth + 10)) {
1158 
1159 			mon_ood[lvl] += addval;
1160 
1161 			/* Is it a unique */
1162 			if (rf_has(mon->race->flags, RF_UNIQUE))
1163 				uniq_ood[lvl] += addval;
1164 	}
1165 
1166 
1167 	/* Is it deadly? */
1168 	if (mon->race->level > player->depth + 10){
1169 
1170 		mon_deadly[lvl] += addval;
1171 
1172 		/* Is it a unique? */
1173 		if (rf_has(mon->race->flags, RF_UNIQUE))
1174 			uniq_deadly[lvl] += addval;
1175 	}
1176 
1177 	/* Generate treasure */
1178 	monster_death_stats(i);
1179 
1180 	/* remove the monster */
1181 	delete_monster_idx(i);
1182 
1183 	/* success */
1184 	return true;
1185 }
1186 
1187 
1188 /**
1189  * Print heading infor for the file
1190  */
print_heading(void)1191 static void print_heading(void)
1192 {
1193 	/* PRINT INFO STUFF */
1194 	file_putf(stats_log," This is a Monte Carlo simulation, results are arranged by level \n");
1195 	file_putf(stats_log," Monsters:  OOD means between 1 and 10 levels deep, deadly is more than \n");
1196 	file_putf(stats_log,"            10 levels deep \n");
1197 	file_putf(stats_log," Artifacts: info on artifact location (vault, floor, etc) \n");
1198 	file_putf(stats_log,"		     do not include special artifacts, only weapons and armor \n");
1199 	file_putf(stats_log," Weapons  : Big dice weapons are either BoC, SoS, or Mod.  Uber \n");
1200 	file_putf(stats_log,"            weapons, are one of the above with xblows or slay evil\n");
1201 	file_putf(stats_log," Launchers: xtra shots and xtra might are only logged for x3 or\n");
1202 	file_putf(stats_log,"            better.  Very good has +to hit or + to dam > 15\n");
1203 	file_putf(stats_log," Amulets:   Endgame amulets are trickery, weaponmaster and magi\n");
1204 	file_putf(stats_log," Armor:     Low resist armor may have more than one basic resist (acid, \n");
1205 	file_putf(stats_log,"		     elec, fire, cold) but not all. \n");
1206 	file_putf(stats_log," Books:     Prayer and Magic books have the same probability. \n");
1207 	file_putf(stats_log," Potions:   Aug counts as 5 potions, *enlight* as 2.  Healing potions are \n");
1208 	file_putf(stats_log,"			 only *Healing* and Life\n");
1209 	file_putf(stats_log," Scrolls:   Endgame scrolls include *Dest*, Rune, MBan and Ban \n");
1210 	file_putf(stats_log,"    		 *Acq* counts as two Acq scrolls");
1211 	file_putf(stats_log," Rods: 	 Utility rods: d-obj, d-stairs, d-traps, light, illum \n");
1212 	file_putf(stats_log,"    		 Endgame rods: Speed, Healing \n");
1213 	file_putf(stats_log," Staves: 	 Kill staves: dispel evil, power, holiness. \n");
1214 	file_putf(stats_log,"    		 Power staves: healing, magi, banishment \n");
1215 }
1216 
1217 /**
1218  * Print all the stats for each level
1219  */
print_stats(int lvl)1220 static void print_stats(int lvl)
1221 {
1222 
1223 	int i;
1224 
1225 	/* check bounds on lvl */
1226 	if ((lvl < 0) || (lvl > 100)) return;
1227 
1228 	/* print level heading */
1229 	file_putf(stats_log,"\n");
1230 	file_putf(stats_log,"******** LEVEL %d , %d tries********* \n",lvl, tries);
1231 	file_putf(stats_log,"\n");
1232 
1233 	/* print monster heading */
1234 	file_putf(stats_log," MONSTER INFO \n");
1235 	file_putf(stats_log," Total monsters: %f OOD: %f Deadly: %f \n",
1236 				mon_total[lvl], mon_ood[lvl], mon_deadly[lvl]);
1237 	file_putf(stats_log," Unique monsters: %f OOD: %f Deadly: %f \n",
1238 				uniq_total[lvl], uniq_ood[lvl], uniq_deadly[lvl]);
1239 	/* print artifact heading */
1240 
1241 
1242 
1243 	file_putf(stats_log,"\n ARTIFACT INFO \n");
1244 
1245 	/* basic artifact info */
1246 	file_putf(stats_log,"Total artifacts: %f  Special artifacts: %f  Weapons/armor: %f \n",
1247 		art_total[lvl], art_spec[lvl], art_norm[lvl]);
1248 
1249 	/* artifact depth info */
1250 	file_putf(stats_log,"Shallow: %f  Average: %f  Ood: %f \n",
1251 		art_shal[lvl],art_ave[lvl],art_ood[lvl]);
1252 
1253 	/* more advanced info */
1254 	file_putf(stats_log,"From vaults: %f  From floor (no vault): %f \n",
1255 		art_vault[lvl],art_floor[lvl]);
1256 	file_putf(stats_log,"Uniques: %f  Monsters: %f  Vault denizens: %f \n",
1257 		art_uniq[lvl], art_mon[lvl], art_mon_vault[lvl]);
1258 
1259 
1260 	for (i=ST_BEGIN; i<ST_END; i++){
1261 		file_putf(stats_log, "%s%f From Monsters: %f In Vaults: %f \n",	stat_message[i].name, stat_all[i][0][lvl], stat_all[i][1][lvl], stat_all[i][2][lvl]);
1262 	}
1263 
1264 
1265 }
1266 
1267 /**
1268  *Compute and print the mean and standard deviation for an array of known size
1269  */
mean_and_stdv(int array[TRIES_SIZE])1270 static void mean_and_stdv(int array[TRIES_SIZE])
1271 {
1272 	int k, maxiter;
1273 	double tot = 0, mean, stdev, temp = 0;
1274 
1275 	/* Get the maximum iteration value */
1276 	maxiter = MIN(tries, TRIES_SIZE);
1277 
1278 	/* Sum the array */
1279 	for (k = 0; k < maxiter; k++)
1280 		tot += array[k];
1281 
1282 	/* Compute the mean */
1283 	mean = tot / maxiter;
1284 
1285 	/* Sum up the squares */
1286 	for (k = 0; k < maxiter; k++) temp += (array[k] - mean) * (array[k] - mean);
1287 
1288 	/* Compute standard dev */
1289 	stdev = sqrt(temp / tries);
1290 
1291 	/* Print to file */
1292 	file_putf(stats_log," mean: %f  std-dev: %f \n",mean,stdev);
1293 
1294 }
1295 
1296 /**
1297  * Calculated the probability of finding an item by a specific level,
1298  * and print it to the output file
1299  */
1300 
prob_of_find(double stat[MAX_LVL])1301 static void prob_of_find(double stat[MAX_LVL])
1302 {
1303 	static int lvl, tmpcount;
1304 	double find = 0.0, tmpfind = 0.0;
1305 
1306 	/* Skip town level */
1307 	for (lvl = 1; lvl < MAX_LVL ; lvl++) {
1308 
1309 		/* Calculate the probability of not finding the stat */
1310 		tmpfind=(1 - stat[lvl]);
1311 
1312 		/* Maximum probability is 98% */
1313 		if (tmpfind < 0.02) tmpfind = 0.02;
1314 
1315 		/* Multiply probabilities of not finding */
1316 		if (find <= 0) find = tmpfind; else find *= tmpfind;
1317 
1318 		/* Increase count to 5 */
1319 		tmpcount++;
1320 
1321 		/* Print output every 5 levels */
1322 		if (tmpcount == 5) {
1323 
1324 			/* print it */
1325 			file_putf(stats_log,"%f \t",1-find);
1326 
1327 			/* reset temp counter */
1328 			tmpcount=0;
1329 		}
1330 	}
1331 
1332 	/* Put a new line in prep of next entry */
1333 	file_putf(stats_log,"\n");
1334  }
1335 
1336 #if 0
1337 /**
1338  * Left this function unlinked for now
1339  */
1340 static double total(double stat[MAX_LVL])
1341 {
1342 	int k;
1343 	double out = 0;
1344 
1345 	for (k = 0; k < MAX_LVL; k++)
1346 		out += stat[k];
1347 
1348 	return out;
1349 }
1350 #endif
1351 
1352 /**
1353  * Post process select items
1354  */
post_process_stats(void)1355 static void post_process_stats(void)
1356 {
1357 	double arttot;
1358 	int i,k;
1359 
1360 	/* Output a title */
1361 	file_putf(stats_log,"\n");
1362 	file_putf(stats_log,"***** POST PROCESSING *****\n");
1363 	file_putf(stats_log,"\n");
1364 	file_putf(stats_log,"Item \t5\t\t\t10\t\t\t15\t\t\t20\t\t\t25\t\t\t");
1365 	file_putf(stats_log,"30\t\t\t35\t\t\t40\t\t\t45\t\t\t50\t\t\t");
1366 	file_putf(stats_log,"55\t\t\t60\t\t\t65\t\t\t70\t\t\t75\t\t\t");
1367 	file_putf(stats_log,"80\t\t\t85\t\t\t90\t\t\t95\t\t\t100\n");
1368 
1369 	for (i = 1; i < ST_FF_END; i++) {
1370 			file_putf(stats_log, stat_ff_message[i].name);
1371 			prob_of_find(stat_all[stat_ff_message[i].st][0]);
1372 			mean_and_stdv(stat_ff_all[i]);
1373 	}
1374 
1375 	/* Print artifact total */
1376 	arttot = 0;
1377 
1378 	for (k = 0; k < MAX_LVL; k++)
1379 		arttot += art_total[k];
1380 
1381 	file_putf(stats_log,"\n");
1382 	file_putf(stats_log,"Total number of artifacts found %f \n",arttot);
1383 	mean_and_stdv(art_it);
1384 
1385 	/* Temporary stuff goes here */
1386 	/* Dungeon book totals for Eddie
1387 	file_putf(stats_log,"mb5: %f\n",total(b5_total));
1388 	file_putf(stats_log,"mb6: %f\n",total(b6_total));
1389 	file_putf(stats_log,"mb7: %f\n",total(b7_total));
1390 	file_putf(stats_log,"mb8: %f\n",total(b8_total));
1391 	file_putf(stats_log,"mb9: %f\n",total(b9_total));
1392 	*/
1393 }
1394 
1395 
1396 
1397 /**
1398  * Scans the dungeon for objects
1399  */
scan_for_objects(void)1400 static void scan_for_objects(void)
1401 {
1402 	int y, x;
1403 
1404 	for (y = 1; y < cave->height - 1; y++) {
1405 		for (x = 1; x < cave->width - 1; x++) {
1406 			struct loc grid = loc(x, y);
1407 			struct object *obj;
1408 
1409 			while ((obj = square_object(cave, grid))) {
1410 				/* Get data on the object */
1411 				get_obj_data(obj, y, x, false, false);
1412 
1413 				/* Delete the object */
1414 				square_delete_object(cave, grid, obj, false, false);
1415 			}
1416 		}
1417 	}
1418 }
1419 
1420 /**
1421  * This will scan the dungeon for monsters and then kill each
1422  * and every last one.
1423  */
scan_for_monsters(void)1424 static void scan_for_monsters(void)
1425 {
1426 	int i;
1427 
1428 	/* Go through the monster list */
1429 	for (i = 1; i < cave_monster_max(cave); i++) {
1430 		struct monster *mon = cave_monster(cave, i);
1431 
1432 		/* Skip dead monsters */
1433 		if (!mon->race) continue;
1434 
1435 		stats_monster(mon, i);
1436 	}
1437 }
1438 
1439 /**
1440  * This is the entry point for generation statistics.
1441  */
stats_collect_level(void)1442 static void stats_collect_level(void)
1443 {
1444 	/* Make a dungeon */
1445 	prepare_next_level(&cave, player);
1446 
1447 	/* Scan for objects, these are floor objects */
1448 	scan_for_objects();
1449 
1450 	/* Get stats (and kill) all non-unique monsters */
1451 	scan_for_monsters();
1452 
1453 }
1454 
1455 /**
1456  * This code will go through the artifact list and make each artifact
1457  * uncreated so that our sim player can find them again!
1458  */
uncreate_artifacts(void)1459 static void uncreate_artifacts(void)
1460 {
1461 	int i;
1462 
1463 	/* Loop through artifacts */
1464 	for (i = 0; z_info && i < z_info->a_max; i++) {
1465 		struct artifact *art = &a_info[i];
1466 
1467 		/* Uncreate */
1468 		art->created = false;
1469 	}
1470 }
1471 
1472 /**
1473  * This will revive all the uniques so the sim player
1474  * can kill them again.
1475  */
revive_uniques(void)1476 static void revive_uniques(void)
1477 {
1478 	int i;
1479 
1480 	for (i = 1; i < z_info->r_max - 1; i++) {
1481 		/* Get the monster info */
1482 		struct monster_race *race = &r_info[i];
1483 
1484 		/* Revive the unique monster */
1485 		if (rf_has(race->flags, RF_UNIQUE)) race->max_num = 1;
1486 	}
1487 }
1488 
1489 /**
1490  * This function loops through the level and does N iterations of
1491  * the stat calling function, assuming diving style.
1492  */
diving_stats(void)1493 static void diving_stats(void)
1494 {
1495 	int depth;
1496 
1497 	/* Iterate through levels */
1498 	for (depth = 0; depth < MAX_LVL; depth += 5) {
1499 		player->depth = depth;
1500 		if (player->depth == 0) player->depth = 1;
1501 
1502 		/* Do many iterations of each level */
1503 		for (iter = 0; iter < tries; iter++)
1504 		     stats_collect_level();
1505 
1506 		/* Print the output to the file */
1507 		print_stats(depth);
1508 
1509 		/* Show the level to check on status */
1510 		do_cmd_redraw();
1511 	}
1512 }
1513 
1514 /**
1515  * This function loops through the level and does N iterations of
1516  * the stat calling function, assuming clearing style.
1517  */
clearing_stats(void)1518 static void clearing_stats(void)
1519 {
1520 	int depth;
1521 
1522 	/* Do many iterations of the game */
1523 	for (iter = 0; iter < tries; iter++) {
1524 		/* Move all artifacts to uncreated */
1525 		uncreate_artifacts();
1526 
1527 		/* Move all uniques to alive */
1528 		revive_uniques();
1529 
1530 		/* Do randart regen */
1531 		if ((regen) && (iter<tries)) {
1532 			/* Get seed */
1533 			int seed_randart = randint0(0x10000000);
1534 
1535 			/* Restore the standard artifacts */
1536 			cleanup_parser(&randart_parser);
1537 			deactivate_randart_file();
1538 			run_parser(&artifact_parser);
1539 
1540 			/* regen randarts */
1541 			do_randart(seed_randart, false);
1542 		}
1543 
1544 		/* Do game iterations */
1545 		for (depth = 1 ; depth < MAX_LVL; depth++) {
1546 			/* Debug
1547 			msg_format("Attempting level %d",depth); */
1548 
1549 			/* Move player to that depth */
1550 			player->depth = depth;
1551 
1552 			/* Get stats */
1553 			stats_collect_level();
1554 
1555 			/* Debug
1556 			msg_format("Finished level %d,depth"); */
1557 		}
1558 
1559 		msg("Iteration %d complete",iter);
1560 	}
1561 
1562 	/* Restore original artifacts */
1563 	if (regen) {
1564 		cleanup_parser(&randart_parser);
1565 		if (OPT(player, birth_randarts)) {
1566 			activate_randart_file();
1567 			run_parser(&randart_parser);
1568 			deactivate_randart_file();
1569 		} else {
1570 			run_parser(&artifact_parser);
1571 		}
1572 	}
1573 
1574 	/* Print to file */
1575 	for (depth = 0 ;depth < MAX_LVL; depth++)
1576 		print_stats(depth);
1577 
1578 	/* Post processing */
1579 	post_process_stats();
1580 
1581 	/* Display the current level */
1582 	do_cmd_redraw();
1583 }
1584 
1585 /**
1586  * Prompt the user for sim type and number of sims for a stats run
1587  */
stats_prompt(void)1588 static int stats_prompt(void)
1589 {
1590 	static int temp,simtype = 1;
1591 	static char tmp_val[100];
1592 	static char prompt[50];
1593 
1594 	/* This is the prompt for no. of tries*/
1595 	strnfmt(prompt, sizeof(prompt), "Num of simulations: ");
1596 
1597 	/* This is the default value (50) */
1598 	strnfmt(tmp_val, sizeof(tmp_val), "%d", tries);
1599 
1600 	/* Ask for the input */
1601 	if (!get_string(prompt, tmp_val, 7)) return 0;
1602 
1603 	/* Get the new value */
1604 	temp = atoi(tmp_val);
1605 
1606 	/* Convert */
1607 	if (temp < 1) temp = 1;
1608 
1609 	/* Save */
1610 	tries = temp;
1611 
1612 	/* Set 'value to add' for arrays */
1613 	addval = 1.0 / tries;
1614 
1615 	/* Get info on what type of run to do */
1616 	strnfmt(prompt, sizeof(prompt), "Type of Sim: Diving (1) or Clearing (2) ");
1617 
1618 	/* Set default */
1619 	strnfmt(tmp_val, sizeof(tmp_val), "%d", simtype);
1620 
1621 	/* Get the input */
1622 	if (!get_string(prompt, tmp_val, 4)) return 0;
1623 
1624 	temp = atoi(tmp_val);
1625 
1626 	/* Make sure that the type is good */
1627 	if ((temp == 1) || (temp == 2))
1628 		simtype = temp;
1629 	else
1630 		return 0;
1631 
1632 	/* For clearing sim, check for randart regen */
1633 	if (temp == 2) {
1634 		/* Prompt */
1635 		strnfmt(prompt, sizeof(prompt), "Regen randarts? (warning SLOW)");
1636 
1637 		regen = get_check(prompt) ? true : false;
1638 	}
1639 
1640 	return simtype;
1641 }
1642 
1643 /**
1644  * This is the function called from wiz-debug.c.
1645  */
stats_collect(void)1646 void stats_collect(void)
1647 {
1648 	static int simtype;
1649 	static bool auto_flag;
1650 	char buf[1024];
1651 
1652 	/* Prompt the user for sim params */
1653 	simtype = stats_prompt();
1654 
1655 	/* Make sure the results are good! */
1656 	if (!((simtype == 1) || (simtype == 2)))
1657 		return;
1658 
1659 	/* Are we in diving or clearing mode */
1660 	if (simtype == 2)
1661 		clearing = true;
1662 	else
1663 		clearing = false;
1664 
1665 	/* Open log file */
1666 	path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "stats.log");
1667 	stats_log = file_open(buf, MODE_WRITE, FTYPE_TEXT);
1668 
1669 	/* Logging didn't work */
1670 	if (!stats_log) {
1671 		msg("Error - can't open stats.log for writing.");
1672 		exit(1);
1673 	}
1674 
1675 	/* Turn on auto-more.  This will clear prompts for items
1676 	 * that drop under the player, or that can't fit on the
1677 	 * floor due to too many items.  This is a very small amount
1678 	 * of items, even on deeper levels, so it's not worth worrying
1679 	 * too much about.
1680 	 */
1681 	 auto_flag = false;
1682 
1683 	 if (!OPT(player, auto_more)) {
1684 		/* Remember that we turned off auto_more */
1685 		auto_flag = true;
1686 
1687 		/* Turn on auto-more */
1688 		option_set(option_name(OPT_auto_more),true);
1689 	}
1690 
1691 	/* Print heading for the file */
1692 	print_heading();
1693 
1694 	/* Make sure all stats are 0 */
1695 	init_stat_vals();
1696 
1697 	/* Select diving option */
1698 	if (!clearing) diving_stats();
1699 
1700 	/* Select clearing option */
1701 	if (clearing) clearing_stats();
1702 
1703 	/* Turn auto-more back off */
1704 	if (auto_flag) option_set(option_name(OPT_auto_more), false);
1705 
1706 	/* Close log file */
1707 	if (!file_close(stats_log)) {
1708 		msg("Error - can't close stats.log file.");
1709 		exit(1);
1710 	}
1711 }
1712 
1713 #define DIST_MAX 10000
1714 
calc_cave_distances(int ** cave_dist)1715 void calc_cave_distances(int **cave_dist)
1716 {
1717 	int dist;
1718 
1719 	/* Squares with distance from player of n - 1 */
1720 	struct loc *ogrids;
1721 	int n_old, cap_old;
1722 
1723 	/* Squares with distance from player of n */
1724 	struct loc *ngrids;
1725 	int n_new, cap_new;
1726 
1727 	/*
1728 	 * The perimeter of the cave should overestimate the space needed so
1729 	 * there's fewer reallocations within the loop.
1730 	 */
1731 	cap_old = 2 * (cave->width + cave->height - 1);
1732 	ogrids = mem_alloc(cap_old * sizeof(*ogrids));
1733 	cap_new = cap_old;
1734 	ngrids = mem_alloc(cap_new * sizeof(*ngrids));
1735 
1736 	/* The player's location is the first one to test. */
1737 	ogrids[0] = player->grid;
1738 	n_old = 1;
1739 
1740 	/* Distance from player starts at 0 */
1741 	dist = 0;
1742 
1743 	/* Assign the distance value to the first square (player) */
1744 	cave_dist[ogrids[0].y][ogrids[0].x] = dist;
1745 
1746 	do {
1747 		int i, n_tmp;
1748 		struct loc *gtmp;
1749 
1750 		n_new = 0;
1751 		dist++;
1752 
1753 		/* Loop over all visited squares of the previous iteration */
1754 		for (i = 0; i < n_old; i++){
1755 			int d;
1756 			/* Get the square we want to look at */
1757 			int oy = ogrids[i].y;
1758 			int ox = ogrids[i].x;
1759 
1760 			/* debug
1761 			msg("x: %d y: %d dist: %d %d ",ox,oy,dist-1,i); */
1762 
1763 			/* Get all adjacent squares */
1764 			for (d = 0; d < 8; d++) {
1765 				/* Adjacent square location */
1766 				int ty = oy + ddy_ddd[d];
1767 				int tx = ox + ddx_ddd[d];
1768 
1769 				if (!(square_in_bounds_fully(cave, loc(tx, ty)))) continue;
1770 
1771 				/* Have we been here before? */
1772 				if (cave_dist[ty][tx] >= 0) continue;
1773 
1774 				/*
1775 				 * Impassable terrain which isn't a door or
1776 				 * rubble blocks progress.
1777 				 */
1778 				if (!square_ispassable(cave, loc(tx, ty)) &&
1779 					!square_isdoor(cave, loc(tx, ty)) &&
1780 					!square_isrubble(cave, loc(tx, ty))) continue;
1781 
1782 				/* Add the new location */
1783 				if (n_new == cap_new - 1) {
1784 					cap_new *= 2;
1785 					ngrids = mem_realloc(ngrids,
1786 						cap_new * sizeof(ngrids));
1787 				}
1788 				ngrids[n_new].y = ty;
1789 				ngrids[n_new].x = tx;
1790 				++n_new;
1791 
1792 				/* Assign the distance to that spot */
1793 				cave_dist[ty][tx] = dist;
1794 
1795 				/* debug
1796 				msg("x: %d y: %d dist: %d ",tx,ty,dist); */
1797 			}
1798 		}
1799 
1800 		/* Swap the lists; do not need to preserve n_old. */
1801 		gtmp = ogrids;
1802 		ogrids = ngrids;
1803 		ngrids = gtmp;
1804 		n_tmp = cap_old;
1805 		cap_old = cap_new;
1806 		cap_new = n_tmp;
1807 		n_old = n_new;
1808 	} while (n_old > 0 && dist < DIST_MAX);
1809 
1810 	mem_free(ngrids);
1811 	mem_free(ogrids);
1812 }
1813 
pit_stats(void)1814 void pit_stats(void)
1815 {
1816 	int tries = 1000;
1817 	int depth = 0;
1818 	int hist[z_info->pit_max];
1819 	int j, p;
1820 	int type = 1;
1821 
1822 	char tmp_val[100];
1823 
1824 	/* Initialize hist */
1825 	for (p = 0; p < z_info->pit_max; p++)
1826 		hist[p] = 0;
1827 
1828 	/* Format default value */
1829 	strnfmt(tmp_val, sizeof(tmp_val), "%d", tries);
1830 
1831 	/* Ask for the input - take the first 7 characters*/
1832 	if (!get_string("Num of simulations: ", tmp_val, 7)) return;
1833 
1834 	/* Get the new value */
1835 	tries = atoi(tmp_val);
1836 	if (tries < 1) tries = 1;
1837 
1838 	/* Format second default value */
1839 	strnfmt(tmp_val, sizeof(tmp_val), "%d", type);
1840 
1841 	/* Ask for the input - take the first 7 characters*/
1842 	if (!get_string("Pit type: ", tmp_val, 7)) return;
1843 
1844 	/* get the new value */
1845 	type = atoi(tmp_val);
1846 	if (type < 1) type = 1;
1847 
1848 	/* Format second default value */
1849 	strnfmt(tmp_val, sizeof(tmp_val), "%d", player->depth);
1850 
1851 	/* Ask for the input - take the first 7 characters*/
1852 	if (!get_string("Depth: ", tmp_val, 7)) return;
1853 
1854 	/* get the new value */
1855 	depth = atoi(tmp_val);
1856 	if (depth < 1) depth = 1;
1857 
1858 	for (j = 0; j < tries; j++) {
1859 		int i;
1860 		int pit_idx = 0;
1861 		int pit_dist = 999;
1862 
1863 		for (i = 0; i < z_info->pit_max; i++) {
1864 			int offset, dist;
1865 			struct pit_profile *pit = &pit_info[i];
1866 
1867 			if (!pit->name || pit->room_type != type) continue;
1868 
1869 			offset = Rand_normal(pit->ave, 10);
1870 			dist = ABS(offset - depth);
1871 
1872 			if (dist < pit_dist && one_in_(pit->rarity)) {
1873 				pit_idx = i;
1874 				pit_dist = dist;
1875 			}
1876 		}
1877 
1878 		hist[pit_idx]++;
1879 	}
1880 
1881 	for (p = 0; p < z_info->pit_max; p++) {
1882 		struct pit_profile *pit = &pit_info[p];
1883 		if (pit->name)
1884 			msg("Type: %s, Number: %d.", pit->name, hist[p]);
1885 	}
1886 
1887 	return;
1888 }
1889 
1890 
1891 /**
1892  * Gather whether the dungeon has disconnects in it and whether the player
1893  * is disconnected from the stairs
1894  */
disconnect_stats(void)1895 void disconnect_stats(void)
1896 {
1897 	int i, y, x;
1898 
1899 	int **cave_dist;
1900 
1901 	bool has_dsc, has_dsc_from_stairs;
1902 
1903 	static int temp;
1904 	static char tmp_val[100];
1905 	static char prompt[50];
1906 
1907 	long dsc_area = 0, dsc_from_stairs = 0;
1908 	bool stop_for_dis;
1909 	char path[1024];
1910 	ang_file *disfile;
1911 
1912 	/* This is the prompt for no. of tries */
1913 	strnfmt(prompt, sizeof(prompt), "Num of simulations: ");
1914 
1915 	/* This is the default value (50) */
1916 	strnfmt(tmp_val, sizeof(tmp_val), "%d", tries);
1917 
1918 	/* Ask for the input */
1919 	if (!get_string(prompt,tmp_val,7)) return;
1920 
1921 	/* Get the new value */
1922 	temp = atoi(tmp_val);
1923 
1924 	/* Try at least once */
1925 	if (temp < 1)
1926 		temp = 1;
1927 
1928 	/* Save */
1929 	tries = temp;
1930 
1931 	stop_for_dis = get_check("Stop if disconnected level found? ");
1932 
1933 	path_build(path, sizeof(path), ANGBAND_DIR_USER, "disconnect.html");
1934 	disfile = file_open(path, MODE_WRITE, FTYPE_TEXT);
1935 	if (disfile) {
1936 		dump_level_header(disfile, "Disconnected Levels");
1937 	}
1938 
1939 	for (i = 1; i <= tries; i++) {
1940 		/* Assume no disconnected areas */
1941 		has_dsc = false;
1942 
1943 		/* Assume you can't get to stairs */
1944 		has_dsc_from_stairs = true;
1945 
1946 		/* Make a new cave */
1947 		prepare_next_level(&cave, player);
1948 
1949 		/* Allocate the distance array */
1950 		cave_dist = mem_zalloc(cave->height * sizeof(int*));
1951 		for (y = 0; y < cave->height; y++)
1952 			cave_dist[y] = mem_zalloc(cave->width * sizeof(int));
1953 
1954 		/* Set all cave spots to inaccessible */
1955 		for (y = 0; y < cave->height; y++)
1956 			for (x = 1; x < cave->width; x++)
1957 				cave_dist[y][x] = -1;
1958 
1959 		/* Fill the distance array with the correct distances */
1960 		calc_cave_distances(cave_dist);
1961 
1962 		/* Cycle through the dungeon */
1963 		for (y = 1; y < cave->height - 1; y++) {
1964 			for (x = 1; x < cave->width - 1; x++) {
1965 				struct loc grid = loc(x, y);
1966 
1967 				/*
1968 				 * Don't care about impassable terrain that's
1969 				 * not a closed or secret door or impassable
1970 				 * rubble.
1971 				 */
1972 				if (!square_ispassable(cave, grid) &&
1973 					!square_isdoor(cave, grid) &&
1974 					!square_isrubble(cave, grid)) continue;
1975 
1976 				/* Can we get there? */
1977 				if (cave_dist[y][x] >= 0) {
1978 
1979 					/* Is it a  down stairs? */
1980 					if (square_isdownstairs(cave, grid)) {
1981 
1982 						has_dsc_from_stairs = false;
1983 
1984 						/* debug
1985 						msg("dist to stairs: %d",cave_dist[y][x]); */
1986 					}
1987 					continue;
1988 				}
1989 
1990 				/* Ignore vaults as they are often disconnected */
1991 				if (square_isvault(cave, grid)) continue;
1992 
1993 				/* We have a disconnected area */
1994 				has_dsc = true;
1995 			}
1996 		}
1997 
1998 		if (has_dsc_from_stairs) dsc_from_stairs++;
1999 
2000 		if (has_dsc) dsc_area++;
2001 
2002 		if (has_dsc || has_dsc_from_stairs) {
2003 			if (disfile) {
2004 				dump_level_body(disfile, "Disconnected Level",
2005 					cave, cave_dist);
2006 			}
2007 			if (stop_for_dis) i = tries;
2008 		}
2009 
2010 		/* Free arrays */
2011 		for (y = 0; y < cave->height; y++)
2012 			mem_free(cave_dist[y]);
2013 		mem_free(cave_dist);
2014 	}
2015 
2016 	msg("Total levels with disconnected areas: %ld",dsc_area);
2017 	msg("Total levels isolated from stairs: %ld",dsc_from_stairs);
2018 	if (disfile) {
2019 		dump_level_footer(disfile);
2020 		if (file_close(disfile)) {
2021 			msg("Map is in disconnect.html.");
2022 		}
2023 	}
2024 
2025 	/* Redraw the level */
2026 	do_cmd_redraw();
2027 }
2028 
2029 
2030 #else /* USE_STATS */
2031 
stats_collect(void)2032 void stats_collect(void)
2033 {
2034 	msg("Statistics generation not turned on in this build.");
2035 }
2036 
disconnect_stats(void)2037 void disconnect_stats(void)
2038 {
2039 	msg("Statistics generation not turned on in this build.");
2040 }
2041 
pit_stats(void)2042 void pit_stats(void)
2043 {
2044 	msg("Statistics generation not turned on in this build.");
2045 }
2046 #endif /* USE_STATS */
2047