Random word from file #5

This commit is contained in:
2017-05-02 18:22:29 +02:00
parent 83ffee4315
commit 37b129b811
5 changed files with 141 additions and 9 deletions

View File

@@ -4,7 +4,8 @@
#include <string.h>
#include <ctype.h> //tolower
#include <getopt.h>
#include <time.h>
#include "prng.h"
int main(int argc, char **argv) {
@@ -55,7 +56,8 @@ int main(int argc, char **argv) {
break;
}
}
InitializePRNG(time(NULL)); /* Initialize random number generator */
if (startscr) {
showStartScreen(gs);
}
@@ -112,12 +114,22 @@ void initGuessWord(game_state *gs, char *filename) {
int i;
mvprintw(1, 1, "Please enter your word: ");
if (strlen(gs->guessWord) == 0) { /* Word can be set by arguments */
curs_set(1);
getstr(gs->guessWord);
curs_set(0);
if (strlen(filename) == 0) {
/* Manual input */
curs_set(1);
getstr(gs->guessWord);
curs_set(0);
} else {
/* Random line from file */
readRandomLine(filename, gs->guessWord);
}
}
/* Make String all lowercase */
toLowerCase(gs->guessWord);
gs->wordLength = strlen(gs->guessWord);
for (i = 0; i < gs->wordLength; i++) {
if (gs->guessWord[i] == ' ') { //Check for spaces if it's a sentence
gs->currentWord[i] = ' ';
@@ -230,7 +242,8 @@ int checkWin(game_state *gs) {
void printGameStats(game_state *gs) {
clear();
if (gs->moves >= gs->allowedMoves) {
mvprintw(gs->centery, gs->centerx - 5, "Game lost.");
mvprintw(gs->centery, gs->centerx - 10, "Game lost. Solution:");
mvprintw(gs->centery + 1, gs->centerx - (gs->wordLength / 2), gs->guessWord);
} else {
char message[100];
sprintf(message, "Game won! Total guesses: %i", gs->guesses);
@@ -251,3 +264,20 @@ int centerDiff(int coordinate, char *str) {
int len = strlen(str);
return coordinate - (len / 2); /* Integer division */
}
void readRandomLine(char *file, char *result) {
long totalLength = 0, rand = 0;
FILE *fp = fopen(file, "r");
char c;
while ((c = fgetc(fp)) != EOF) {
if (c == '\n') ++totalLength;
}
rand = getrandom(0, totalLength);
fseek(fp, rand, SEEK_SET);
fgets(result, MAXWORDLENGTH, fp);
fclose(fp);
}

View File

@@ -1,5 +1,6 @@
/* Defined macros */
#define DEFAULTTRIES 9
#define MAXWORDLENGTH 100
/* Data structures */
typedef struct {
@@ -10,9 +11,9 @@ typedef struct {
int maxx;
int centery;
int centerx;
char guessWord[100];
char guessWord[MAXWORDLENGTH];
int wordLength;
char currentWord[100];
char currentWord[MAXWORDLENGTH];
char wrongCharacters[DEFAULTTRIES];
} game_state;
@@ -38,3 +39,4 @@ void showStartScreen(game_state *gs);
void startGame(game_state *gs);
void showHelp(game_state *gs);
int centerDiff(int coordinate, char *str);
void readRandomLine(char *file, char *result);

View File

@@ -7,7 +7,7 @@ CFLAGS = -Wall -g -D_REENTRANT -DVERSION=\"$(VERSION)\"
#LDFLAGS = -lm -lpthread `gtk-config --cflags` `gtk-config --libs` -lgthread
LDFLAGS = -lncurses
OBJ = hangman.o
OBJ = hangman.o prng.o
all: $(OBJ)
$(CC) $(CFLAGS) -o hangman $(OBJ) $(LDFLAGS)

91
prng.c Normal file
View File

@@ -0,0 +1,91 @@
#include "prng.h"
// Define MT19937 constants (32-bit RNG)
enum
{
// Assumes W = 32 (omitting this)
N = 624,
M = 397,
R = 31,
A = 0x9908B0DF,
F = 1812433253,
U = 11,
// Assumes D = 0xFFFFFFFF (omitting this)
S = 7,
B = 0x9D2C5680,
T = 15,
C = 0xEFC60000,
L = 18,
MASK_LOWER = (1ull << R) - 1,
MASK_UPPER = (1ull << R)
};
static uint32_t mt[N];
static uint16_t index;
// Re-init with a given seed
void InitializePRNG(const uint32_t seed)
{
uint32_t i;
mt[0] = seed;
for ( i = 1; i < N; i++ )
{
mt[i] = (F * (mt[i - 1] ^ (mt[i - 1] >> 30)) + i);
}
index = N;
}
static void Twist()
{
uint32_t i, x, xA;
for ( i = 0; i < N; i++ )
{
x = (mt[i] & MASK_UPPER) + (mt[(i + 1) % N] & MASK_LOWER);
xA = x >> 1;
if ( x & 0x1 )
xA ^= A;
mt[i] = mt[(i + M) % N] ^ xA;
}
index = 0;
}
// Obtain a 32-bit random number
uint32_t ExtractU32()
{
uint32_t y;
int i = index;
if ( index >= N )
{
Twist();
i = index;
}
y = mt[i];
index = i + 1;
y ^= (mt[i] >> U);
y ^= (y << S) & B;
y ^= (y << T) & C;
y ^= (y >> L);
return y;
}
int getrandom(int low, int high) {
return ((ExtractU32() % high) + low);
}

9
prng.h Normal file
View File

@@ -0,0 +1,9 @@
/**
* Pseudo random number generator using the Mersenne Twister algorithm
* This code was taken from wikipedia: https://en.wikipedia.org/wiki/Mersenne_Twister
*/
#include <stdint.h>
void InitializePRNG(const uint32_t seed);
uint32_t ExtractU32();
int getrandom(int low, int high);