NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
bin/52974: [hangman] fix several bugs with word selection
>Number: 52974
>Category: bin
>Synopsis: [hangman] fix several bugs with word selection
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Feb 02 11:35:00 +0000 2018
>Originator: Eitan Adler
>Release: HEAD
>Organization:
>Environment:
>Description:
There are several bugs in the current word selection for hangman:
- the first word will never be selected (as there are two fgets to find a complete word)
- if a minimum length that is longer than all words in the dictionary is selected hangman will... hang
- word selection is not uniformly random since longer words are less likely to be picked (and words after longer words are more likely to be picked)
>How-To-Repeat:
>Fix:
be aware: its 3:30am when I wrote this. There is a good chance I messed up:
Index: extern.c
===================================================================
RCS file: /cvsroot/src/games/hangman/extern.c,v
retrieving revision 1.8
diff -u -r1.8 extern.c
--- extern.c 7 Aug 2003 09:37:20 -0000 1.8
+++ extern.c 2 Feb 2018 11:33:41 -0000
@@ -42,7 +42,8 @@
bool Guessed[26];
-char Word[BUFSIZ], Known[BUFSIZ];
+char *Word;
+char Known[BUFSIZ];
const char *const Noose_pict[] = {
" ______",
" | |",
@@ -75,4 +76,6 @@
FILE *Dict = NULL;
-off_t Dict_size;
+char **Dict_array;
+
+int Dict_count;
Index: getword.c
===================================================================
RCS file: /cvsroot/src/games/hangman/getword.c,v
retrieving revision 1.10
diff -u -r1.10 getword.c
--- getword.c 19 Jun 2012 05:45:00 -0000 1.10
+++ getword.c 2 Feb 2018 11:33:41 -0000
@@ -47,27 +47,11 @@
void
getword(void)
{
- FILE *inf;
char *wp, *gp;
long pos;
- inf = Dict;
- for (;;) {
- pos = (double) rand() / (RAND_MAX + 1.0) * (double) Dict_size;
- fseek(inf, pos, SEEK_SET);
- if (fgets(Word, BUFSIZ, inf) == NULL)
- continue;
- if (fgets(Word, BUFSIZ, inf) == NULL)
- continue;
- Word[strlen(Word) - 1] = '\0';
- if (strlen(Word) < Minlen)
- continue;
- for (wp = Word; *wp; wp++)
- if (!islower((unsigned char)*wp))
- goto cont;
- break;
-cont: ;
- }
+ pos = (double) rand() / (RAND_MAX + 1.0) * (double) Dict_count;
+ Word = Dict_array[pos];
gp = Known;
wp = Word;
while (*wp) {
Index: hangman.h
===================================================================
RCS file: /cvsroot/src/games/hangman/hangman.h,v
retrieving revision 1.14
diff -u -r1.14 hangman.h
--- hangman.h 26 Aug 2011 06:18:17 -0000 1.14
+++ hangman.h 2 Feb 2018 11:33:41 -0000
@@ -65,7 +65,8 @@
extern bool Guessed[];
-extern char Word[], Known[];
+extern char *Word;
+extern char Known[];
extern const char *const Noose_pict[];
extern int Errors, Wordnum;
@@ -79,7 +80,9 @@
extern FILE *Dict;
-extern off_t Dict_size;
+extern char **Dict_array;
+
+extern int Dict_count;
void die(int) __dead;
void endgame(void);
Index: setup.c
===================================================================
RCS file: /cvsroot/src/games/hangman/setup.c,v
retrieving revision 1.11
diff -u -r1.11 setup.c
--- setup.c 19 Jun 2012 05:45:00 -0000 1.11
+++ setup.c 2 Feb 2018 11:33:41 -0000
@@ -50,6 +50,8 @@
setup(void)
{
const char *const *sp;
+ char line[BUFSIZ];
+ int nlines;
static struct stat sbuf;
noecho();
@@ -73,5 +75,16 @@
err(1, "fopen %s", Dict_name);
}
fstat(fileno(Dict), &sbuf);
- Dict_size = sbuf.st_size;
+ Dict_array = malloc(sizeof (char*) * (sbuf.st_size/2));
+ Dict_count = 0;
+
+ while(fgets(line, BUFSIZ, Dict) != NULL) {
+ if (strlen(line) >= Minlen) {
+ Dict_array[Dict_count] = strdup(line);
+ Dict_count++;
+ }
+ }
+ if (Dict_count == 0) {
+ errx(1, "no words with minimum length");
+ }
}
Home |
Main Index |
Thread Index |
Old Index