|
|
|
@@ -15,7 +15,6 @@
|
|
|
|
|
#include "figures.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
|
|
|
|
|
|
const char *short_options = "w:hf:ct";
|
|
|
|
@@ -28,23 +27,18 @@ int main(int argc, char **argv) {
|
|
|
|
|
};
|
|
|
|
|
int c, startscr = 1; /* Show startscreen by default */
|
|
|
|
|
char filename[255];
|
|
|
|
|
game_state gs = {0};
|
|
|
|
|
hitfeed hf = {{{0}}}; // 3 braces are needed to not get a warning
|
|
|
|
|
|
|
|
|
|
filename[0] = '\0';
|
|
|
|
|
|
|
|
|
|
/* Initialization */
|
|
|
|
|
initscr();
|
|
|
|
|
atexit(quitProgram);
|
|
|
|
|
game_state *gs;
|
|
|
|
|
hitfeed *hf;
|
|
|
|
|
|
|
|
|
|
gs = malloc(sizeof(game_state));
|
|
|
|
|
hf = malloc(sizeof(hitfeed)); //zeroes the whole struct
|
|
|
|
|
initCoordinates(gs);
|
|
|
|
|
gs->allowedMoves = DEFAULTTRIES;
|
|
|
|
|
gs->moves = 0;
|
|
|
|
|
gs->guesses = 0;
|
|
|
|
|
gs->trollEnabled = 0;
|
|
|
|
|
hf->besthit = 0;
|
|
|
|
|
hf->impstreakcounter = 0;
|
|
|
|
|
initCoordinates(&gs);
|
|
|
|
|
gs.allowedMoves = DEFAULTTRIES;
|
|
|
|
|
|
|
|
|
|
keypad(stdscr, FALSE);
|
|
|
|
|
nonl(); //No new line. Prevents the new line when hitting enter
|
|
|
|
|
|
|
|
|
@@ -52,12 +46,12 @@ int main(int argc, char **argv) {
|
|
|
|
|
while ( (c = getopt_long(argc, argv, short_options, long_options, NULL)) != -1 ) {
|
|
|
|
|
switch (c) {
|
|
|
|
|
case 'w':
|
|
|
|
|
sprintf(gs->guessWord, "%s", optarg);
|
|
|
|
|
sprintf(gs.guessWord, "%s", optarg);
|
|
|
|
|
startscr = 0;
|
|
|
|
|
break;
|
|
|
|
|
case 'h':
|
|
|
|
|
showHelp(gs);
|
|
|
|
|
exit(0);
|
|
|
|
|
showHelp(&gs);
|
|
|
|
|
return 0;
|
|
|
|
|
break;
|
|
|
|
|
case 'f':
|
|
|
|
|
/* Set filename */
|
|
|
|
@@ -69,34 +63,32 @@ int main(int argc, char **argv) {
|
|
|
|
|
break;
|
|
|
|
|
case 't':
|
|
|
|
|
/* troll option */
|
|
|
|
|
gs->trollEnabled = 1;
|
|
|
|
|
gs.trollEnabled = 1;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
mvprintw(gs->centery, gs->centerx - 9, "Invalid arguments.");
|
|
|
|
|
mvprintw(gs.centery, gs.centerx - 9, "Invalid arguments.");
|
|
|
|
|
getch();
|
|
|
|
|
showHelp(gs);
|
|
|
|
|
exit(0);
|
|
|
|
|
showHelp(&gs);
|
|
|
|
|
return 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
InitializePRNG(time(NULL)); /* Initialize random number generator */
|
|
|
|
|
|
|
|
|
|
if (startscr) {
|
|
|
|
|
showStartScreen(gs);
|
|
|
|
|
showStartScreen(&gs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* start game */
|
|
|
|
|
initGuessWord(gs, filename);
|
|
|
|
|
initAlphabet(gs);
|
|
|
|
|
drawAlphabet(gs, 0);
|
|
|
|
|
drawFigure(gs, 0);
|
|
|
|
|
startGame(gs, hf);
|
|
|
|
|
initGuessWord(&gs, filename);
|
|
|
|
|
initAlphabet(&gs);
|
|
|
|
|
drawAlphabet(&gs, 0);
|
|
|
|
|
drawFigure(&gs, 0);
|
|
|
|
|
startGame(&gs, &hf);
|
|
|
|
|
|
|
|
|
|
nl(); //enable newline again
|
|
|
|
|
while (getch() != 10);
|
|
|
|
|
clear();
|
|
|
|
|
free(gs);
|
|
|
|
|
free(hf);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -143,14 +135,13 @@ void initGuessWord(game_state *gs, char *filename) {
|
|
|
|
|
int i;
|
|
|
|
|
mvprintw(0, 1, "Please enter your word: ");
|
|
|
|
|
if (strlen(gs->guessWord) == 0) { /* Word can be set by arguments */
|
|
|
|
|
if (strlen(filename) == 0) {
|
|
|
|
|
/* If a file argument was specified then try to read a random line from the file,
|
|
|
|
|
if this is not successful or if there is no file argument use the manual input. */
|
|
|
|
|
if (strlen(filename) == 0 || readRandomLine(filename, gs->guessWord) != 0) { // readRandomLine is only excecuted when strlen(filename) != 0
|
|
|
|
|
/* Manual input */
|
|
|
|
|
curs_set(1);
|
|
|
|
|
getnstr(gs->guessWord, MAXWORDLENGTH - 1); /* Reads the guessWord with a limit */
|
|
|
|
|
curs_set(0);
|
|
|
|
|
} else {
|
|
|
|
|
/* Random line from file */
|
|
|
|
|
readRandomLine(filename, gs->guessWord);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -169,19 +160,13 @@ void initGuessWord(game_state *gs, char *filename) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void initAlphabet(game_state *gs) {
|
|
|
|
|
int hasNumber = 0;
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < MAXWORDLENGTH; i++) {
|
|
|
|
|
if (isdigit(gs->guessWord[i]) > 0) {
|
|
|
|
|
hasNumber = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
gs->alphabet = malloc(sizeof(char) * hasNumber ? ALPHABET : ALPHABET_NUM);
|
|
|
|
|
strcpy(gs->alphabet, "abcdefghijklmnopqrstuvwxyz");
|
|
|
|
|
|
|
|
|
|
if (hasNumber) {
|
|
|
|
|
for (unsigned int i = 0; i < strlen(gs->guessWord); i++) {
|
|
|
|
|
if (isdigit(gs->guessWord[i]) > 0) {
|
|
|
|
|
strcat(gs->alphabet, "1234567890");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -301,21 +286,18 @@ int fillCurrentWord(game_state *gs, char validchar) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int stackWrongCharacter(game_state *gs, char wrongchar) {
|
|
|
|
|
int i, alreadyUsed = 0;
|
|
|
|
|
for (i = 0; i < gs->wordLength; i++) {
|
|
|
|
|
for (unsigned i = 0; i < strlen(gs->wrongCharacters); i++) {
|
|
|
|
|
if (gs->wrongCharacters[i] == wrongchar) {
|
|
|
|
|
alreadyUsed = 1;
|
|
|
|
|
return 0; // already used
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!alreadyUsed) {
|
|
|
|
|
// not yet used
|
|
|
|
|
gs->wrongCharacters[strlen(gs->wrongCharacters)] = wrongchar;
|
|
|
|
|
drawAlphabet(gs, wrongchar);
|
|
|
|
|
drawFigure(gs, 1);
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
} else {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int checkWin(game_state *gs) {
|
|
|
|
@@ -333,8 +315,7 @@ int checkWin(game_state *gs) {
|
|
|
|
|
void printGameStats(game_state *gs) {
|
|
|
|
|
//clear();
|
|
|
|
|
int i, z;
|
|
|
|
|
double diff;
|
|
|
|
|
diff = difftime(gs->endTime, gs->startTime);
|
|
|
|
|
|
|
|
|
|
if (!gs->trollEnabled) {
|
|
|
|
|
for (z = 0; z <= gs->wordRows; z++) { //<= takes the last row too
|
|
|
|
|
for (i = 0; i < gs->maxx; i++) {
|
|
|
|
@@ -353,16 +334,18 @@ void printGameStats(game_state *gs) {
|
|
|
|
|
mvprintw(gs->centery + 1, gs->centerx - (gs->wordLength / 2), gs->guessWord);
|
|
|
|
|
} else {
|
|
|
|
|
char message[100];
|
|
|
|
|
float result = 0;
|
|
|
|
|
|
|
|
|
|
sprintf(message, "Game won! Total guesses: %i", gs->guesses);
|
|
|
|
|
mvprintw(gs->centery, gs->centerx - (strlen(message) / 2), message);
|
|
|
|
|
|
|
|
|
|
sprintf(message, "Wrong guesses: %i, right/wrong ratio: ", gs->moves);
|
|
|
|
|
if (gs->moves != 0) {
|
|
|
|
|
result = (float)((gs->guesses - gs->moves) / gs->moves);
|
|
|
|
|
sprintf(message + strlen(message), "%.2f", ((double)gs->guesses - (double)gs->moves) / (double)gs->moves);
|
|
|
|
|
} else {
|
|
|
|
|
result = (float)((gs->guesses - gs->moves) / 1);
|
|
|
|
|
sprintf(message + strlen(message), "max");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sprintf(message, "Wrong guesses: %i, right/wrong ratio: %.2f, time: %.2fsec", gs->moves, result, diff);
|
|
|
|
|
sprintf(message + strlen(message), ", time: %llusec", (unsigned long long)(gs->endTime - gs->startTime));
|
|
|
|
|
mvprintw(gs->centery + 1, gs->centerx - (strlen(message) / 2), message);
|
|
|
|
|
mvprintw(gs->centery + 2, gs->centerx - (gs->wordLength / 2), gs->guessWord);
|
|
|
|
|
|
|
|
|
@@ -383,10 +366,16 @@ int centerDiff(int coordinate, char *str) {
|
|
|
|
|
return coordinate - (len / 2); /* Integer division */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void readRandomLine(char *file, char *result) {
|
|
|
|
|
FILE *fp = fopen(file, "r");
|
|
|
|
|
int readRandomLine(char *file, char *result) {
|
|
|
|
|
FILE *fp;
|
|
|
|
|
int count = 0, wordlength = 0;
|
|
|
|
|
char line[MAXWORDLENGTH];
|
|
|
|
|
|
|
|
|
|
fp = fopen(file, "r");
|
|
|
|
|
if (fp == NULL) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
srand(time(NULL));
|
|
|
|
|
while (fgets(line, MAXWORDLENGTH, fp) != NULL) {
|
|
|
|
|
count++;
|
|
|
|
@@ -398,12 +387,14 @@ void readRandomLine(char *file, char *result) {
|
|
|
|
|
wordlength = strlen(result);
|
|
|
|
|
result[wordlength - 1] = '\0';
|
|
|
|
|
fclose(fp);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void trollHitScreen(game_state *gs, hitfeed *hf, int hits) {
|
|
|
|
|
if (gs->trollEnabled) {
|
|
|
|
|
char *strings[] = {"Double Hit", "Triple Hit", "Multi Hit", \
|
|
|
|
|
"Ultra Hit", "Monster Hit", "Rampage", \
|
|
|
|
|
char *strings[] = {"Double Hit", "Triple Hit", "Multi Hit",
|
|
|
|
|
"Ultra Hit", "Monster Hit", "Rampage",
|
|
|
|
|
"Unstoppable", "Wicked sick", "Godlike"};
|
|
|
|
|
int selection[] = {2, 3, 4, 5, 6, 7, 8, 9, 10};
|
|
|
|
|
int i, found = 0;
|
|
|
|
@@ -448,8 +439,8 @@ void printHitFeed(game_state *gs, hitfeed *hf) {
|
|
|
|
|
int newMaxy = gs->maxy - HITFEEDSLOTS;
|
|
|
|
|
int newMaxx = gs->maxx - (gs->centerx / 2);
|
|
|
|
|
int i, z;
|
|
|
|
|
for (i = 0; i < HITFEEDSLOTS; i++) {
|
|
|
|
|
for (z = 0; z < gs->maxx - newMaxx; z++) {
|
|
|
|
|
for (i = -1; i < HITFEEDSLOTS; i++) {
|
|
|
|
|
for (z = 0; z <= gs->maxx - newMaxx; z++) {
|
|
|
|
|
mvprintw(newMaxy + i, newMaxx + z, " ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -489,9 +480,6 @@ void trollHandleImpressive(hitfeed *hf, game_state *gs, int hits) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void drawFigure(game_state *gs, int drawNext) {
|
|
|
|
|
int row = 6;
|
|
|
|
|
int length = 8;
|
|
|
|
@@ -525,5 +513,3 @@ void animateLineClear(game_state *gs, int line, int offsetMultiplier) {
|
|
|
|
|
mvprintw(line, k, " ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|