NetBSD Problem Report #52974
From www@NetBSD.org Fri Feb 2 11:34:09 2018
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id 675EC7A1CC
for <gnats-bugs@gnats.NetBSD.org>; Fri, 2 Feb 2018 11:34:09 +0000 (UTC)
Message-Id: <20180202113408.584E27A224@mollari.NetBSD.org>
Date: Fri, 2 Feb 2018 11:34:08 +0000 (UTC)
From: lists@eitanadler.com
Reply-To: lists@eitanadler.com
To: gnats-bugs@NetBSD.org
Subject: [hangman] fix several bugs with word selection
X-Send-Pr-Version: www-1.0
>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
>Last-Modified: Wed Feb 20 05:24:16 +0000 2019
>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");
+ }
}
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: bin-bug-people->eadler
Responsible-Changed-By: eadler@NetBSD.org
Responsible-Changed-When: Sun, 04 Mar 2018 21:43:56 +0000
Responsible-Changed-Why:
Responsible-Changed-From-To: eadler->bin-bug-people
Responsible-Changed-By: eadler@NetBSD.org
Responsible-Changed-When: Wed, 20 Feb 2019 05:24:16 +0000
Responsible-Changed-Why:
I don't time right now
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.43 2018/01/16 07:36:43 maya Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2017
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.