Fixed random word to use whole file.
authorPat Thoyts <patthoyts@users.sourceforge.net>
Sat, 19 Jun 2010 23:48:14 +0000 (00:48 +0100)
committerPat Thoyts <patthoyts@users.sourceforge.net>
Sat, 19 Jun 2010 23:48:14 +0000 (00:48 +0100)
The getrandomword function did not use the whole file. Changed to seek
to a random location and then read the next full word that is 7 chars.
Checked for memleaks using valgrind and added cleanup for the word
tree and answers list. No more leaks reported.

Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
makefile.linux
src/ag.c
src/ag_test.c

index ae02e3c7c98047d1cb06a7c5b94835ea7de24da5..c426e707d57d72425194f84aa926e73c56e51827 100644 (file)
@@ -3,13 +3,12 @@
 CC=gcc
 LD=gcc
 CFLAGS  =-g -Wall `sdl-config --cflags`
-#CFLAGS +=-O9 -funroll-loops -fomit-frame-pointer
+CFLAGS +=-O9 -funroll-loops -fomit-frame-pointer
 LDFLAGS=`sdl-config --libs` -lSDL_mixer
 
 C_FILES=src/dlb.c src/linked.c src/sprite.c src/ag.c
 OBJ_FILES=src/dlb.o src/linked.o src/sprite.o src/ag.o
 TEST_OBJS=$(OBJ_FILES:src/ag.o=src/ag_test.o)
-OUT_FILE=ag
 
 all:ag
 
@@ -34,7 +33,7 @@ src/ag.o: src/ag.c
 src/ag_test.o: src/ag_test.c
        $(CC) $(CFLAGS) -DUNIT_TEST -c -o $@ $^
 
-tests: test_ag test_linked
+tests: test_ag test_linked test_dlb
 
 test_ag: ag $(TEST_OBJS) src/unittest.h
        $(LD) $(LDFLAGS) -o $@ $(TEST_OBJS)
@@ -42,6 +41,9 @@ test_ag: ag $(TEST_OBJS) src/unittest.h
 test_linked: src/linked.c src/unittest.h
        $(CC) $(CFLAGS) -Isrc -DUNIT_TEST $< -o $@
 
+test_dlb: src/dlb.c src/unittest.h
+       $(CC) $(CFLAGS) -Isrc -DUNIT_TEST $< -o $@
+
 clean:
        rm -f src/*.o
        rm -f test_linked test_ag
index 7ee7eb9e2fa0ba878afb625981bd45089bd35566..018a504c36c3e505437f8e28a37d950e4bfd182e 100644 (file)
--- a/src/ag.c
+++ b/src/ag.c
@@ -58,6 +58,8 @@
  * -------------------------------------------------------------------
  */
 
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>
@@ -939,55 +941,41 @@ inputs: n/a
 
 outputs: a random word
 ***********************************************************/
-static char *
-getRandomWord()
+static void
+getRandomWord(char *output, size_t length)
 {
-    FILE* wordlist;
-    int filelocation;
-    int i;
-    char* wordFromList = malloc(sizeof(char) * 50);
-    int len=0;
-    int done = 0;
+    FILE *fp;
+    struct stat statbuf;
+    char buffer[64];
     
-       filelocation = rand()%10000;
+    assert(length == 9);
 
        strcpy(txt,language);
-       wordlist = fopen(strcat(txt,"wordlist.txt"),"r");
-
-       for (i = 0; i <= filelocation; i++) {
+    strcat(txt,"wordlist.txt");
+       fp = fopen(txt,"r");
 
-               if (fscanf(wordlist, "%s", wordFromList) != EOF) {
-                       /* spin on */
-               } else {
-                       /* go back to the start of the file */
-            fseek(wordlist, 0L, SEEK_SET);
-               }
-       }
+    stat(txt, &statbuf);
+    fseek(fp, (rand() % statbuf.st_size), SEEK_SET);
+    if (fscanf(fp, "%63s", buffer) == EOF)
+        fseek(fp, 0, SEEK_SET);
 
        /* ok random location reached */
-       while (!done) {
-               len = strlen(wordFromList);
-               if ((len==7)) {/* ||(len==6)||(len==5)){ */
-                       done = 1;
-               } else {
-                       if (fscanf(wordlist, "%s", wordFromList) != EOF) {
-                               /* spin on */
-                       } else {
-                               /* go back to the start of the file */
-                               fseek(wordlist, 0L, SEEK_SET);
-                               i = fscanf(wordlist, "%s", wordFromList);
-                assert(i != EOF);
-                       }
+       while (strlen(buffer) != 7) {
+        if (fscanf(fp, "%63s", buffer) == EOF) {
+            /* go back to the start of the file */
+            int i;
+            fseek(fp, 0L, SEEK_SET);
+            i = fscanf(fp, "%63s", buffer);
+            assert(i != EOF);
                }
        }
        
-       fclose(wordlist);
+       fclose(fp);
 
        /* add in our space character */
-       wordFromList[len] = ' ';
-       wordFromList[len+1] = '\0';
-
-       return wordFromList;
+    strcpy(output, buffer);
+    strcat(output, " ");
+       return;
 }
 
 /***********************************************************
@@ -1404,8 +1392,10 @@ newGame(struct node** head, struct dlb_node* dlbHead,
        remain = malloc(sizeof(char)*50);
 
        while (!happy) {
+        char buffer[9];
+        getRandomWord(buffer, sizeof(buffer));
                strcpy(guess,"");
-               strcpy(rootWord, getRandomWord());
+               strcpy(rootWord, buffer);
                bigWordLen = strlen(rootWord)-1;
                strcpy(remain,rootWord);
 
@@ -1705,6 +1695,13 @@ main(int argc, char *argv[])
        /* identify the resource locale */
        init_locale(argc, argv);
 
+       /* create dictionary */
+    strcpy(txt, language);
+       if (!dlb_create(&dlbHead, strcat(txt, "wordlist.txt"))) {
+        printf("failed to open word list file\n");
+        exit(1);
+    }
+
        if (SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0){
                fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
                exit(1);
@@ -1728,9 +1725,6 @@ main(int argc, char *argv[])
 
        bufferSounds(&soundCache);
 
-       /* create dictionary */
-       createDLBTree(&dlbHead, language);
-
        /* cache in-game graphics */
        strcpy(txt, language);
        letterBank = SDL_LoadBMP(strcat(txt,"images/letterBank.bmp"));
@@ -1748,8 +1742,9 @@ main(int argc, char *argv[])
        free(rootWord);
        Mix_CloseAudio();
        clearSoundBuffer(&soundCache);
-       /* trashDLBTree(); */
+       dlb_free(dlbHead);
        destroyLetters(&letters);
+       destroyAnswers(&head);
        SDL_FreeSurface(screen);
        SDL_FreeSurface(letterBank);
        SDL_FreeSurface(smallLetterBank);
index 7ef3464e2021a195e96ea1365807f04f7cc2409e..2d6e1ca5c98ea3658bb51649fc7a77ef1abbaa80 100644 (file)
@@ -46,11 +46,21 @@ static int test_whereinstr()
     return 0;
 }
 
+static int test_getRandomWord()
+{
+    char buffer[9];
+    strcpy(language, "i18n/en_GB/");
+    getRandomWord(buffer, sizeof(buffer));
+    test_equals_int("randword last char is space", ' ', buffer[7]);
+    return 0;
+}
+
 struct unit_test_t unit_tests[] = {
     {NULL, test_shiftLeftKill, NULL},
     {NULL, test_shiftLeft, NULL},
     {NULL, test_nextBlank, NULL},
     {NULL, test_whereinstr, NULL},
+    {NULL, test_getRandomWord, NULL},
 };
 
 int