get_rnd_text() for rumors and other stuff
Solve the uneven distribution situation that has been present for picking random rumors for a long time and for random engravings, epitaphs, and hallucinatory monster names since 3.6.0. This relies on the previous partial solution where short lines have been padded to a longer length. When that length is N and random seek lands in a long line of length L, retry if the position is in the first L-N characters. Put differently, it if takes more than N characters to reach the next newline, reject that random seek and try again. This effectively makes long lines behave as if they had the same length of N as the short lines have been padded to and when all lines are the same length, all entries have the same chance to be chosen.
This commit is contained in:
@@ -104,21 +104,6 @@ static const char SCCS_Id[] UNUSED = "@(#)makedefs.c\t3.7\t2020/01/18";
|
||||
#endif /* else !MAC */
|
||||
#endif /* else !AMIGA */
|
||||
|
||||
/*
|
||||
* For files where entries are selected by seeking to a random position,
|
||||
* skipping to newline, and then using the next line, lines that follow
|
||||
* long ones are more likely to be selected than average and lines that
|
||||
* follow short ones are less likely to be selected than average.
|
||||
* We make selection be more evenly distributed by padding the shortest
|
||||
* lines, at the cost of making the data files bigger. The larger these
|
||||
* values are, the more uniform the selection will become but the more
|
||||
* space will be needed for data used for something which is relatively
|
||||
* inconsequential to actual game play. A value of 0 would suppress the
|
||||
* padding because every line is already at least that long.
|
||||
*/
|
||||
#define PAD_RUMORS_TO 60u /* also used for epitaphs and engravings */
|
||||
#define PAD_BOGONS_TO 20u /* hallucinatory monsters */
|
||||
|
||||
static const char
|
||||
*Dont_Edit_Code =
|
||||
"/* This source file is generated by 'makedefs'. Do not edit. */\n",
|
||||
@@ -329,16 +314,16 @@ do_makedefs(char *options)
|
||||
do_rnd_access_file(EPITAPHFILE,
|
||||
/* default epitaph: parody of the default engraving */
|
||||
"No matter where I went, here I am.",
|
||||
PAD_RUMORS_TO);
|
||||
MD_PAD_RUMORS); /* '_RUMORS' is correct here */
|
||||
do_rnd_access_file(ENGRAVEFILE,
|
||||
/* default engraving: popularized by "The Adventures of
|
||||
Buckaroo Bonzai Across the 8th Dimenstion" but predates
|
||||
that 1984 movie; some attribute it to Confucius */
|
||||
"No matter where you go, there you are.",
|
||||
PAD_RUMORS_TO);
|
||||
MD_PAD_RUMORS); /* '_RUMORS' used here too */
|
||||
do_rnd_access_file(BOGUSMONFILE,
|
||||
/* default bogusmon: iconic monster that isn't in nethack */
|
||||
"grue", PAD_BOGONS_TO);
|
||||
"grue", MD_PAD_BOGONS);
|
||||
break;
|
||||
case 'h':
|
||||
case 'H':
|
||||
@@ -896,6 +881,8 @@ padline(char *line, unsigned padlength)
|
||||
* follow short-line rumors are least likely to be chosen.
|
||||
* We ameliorate the latter by padding the shortest lines,
|
||||
* increasing the chance of the random seek landing in them.
|
||||
* The core's get_rnd_text() handles long lines in a way
|
||||
* that results in even selection distribution.
|
||||
*
|
||||
* Random epitaphs, engravings, and hallucinatory monster
|
||||
* names are in the same boat.
|
||||
@@ -1059,13 +1046,13 @@ do_rumors(void)
|
||||
|
||||
false_rumor_offset = read_rumors_file(".tru", &true_rumor_count,
|
||||
&true_rumor_size, true_rumor_offset,
|
||||
PAD_RUMORS_TO);
|
||||
MD_PAD_RUMORS);
|
||||
if (!false_rumor_offset)
|
||||
goto rumors_failure;
|
||||
|
||||
eof_offset = read_rumors_file(".fal", &false_rumor_count,
|
||||
&false_rumor_size, false_rumor_offset,
|
||||
PAD_RUMORS_TO);
|
||||
MD_PAD_RUMORS);
|
||||
if (!eof_offset)
|
||||
goto rumors_failure;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user