164 lines
3.8 KiB
C
164 lines
3.8 KiB
C
#include <ncurses.h>
|
|
#include "hangman.h"
|
|
#include <stdlib.h> //atexit
|
|
#include <string.h>
|
|
|
|
int main(void) {
|
|
/* Initialization */
|
|
initscr();
|
|
atexit(quitProgram);
|
|
game_state *gs;
|
|
gs = malloc(sizeof(game_state));
|
|
initCoordinates(gs);
|
|
gs->allowedMoves = DEFAULTTRIES;
|
|
gs->moves = 0;
|
|
gs->guesses = 0;
|
|
curs_set(0);
|
|
|
|
/* start game */
|
|
initGuessWord(gs);
|
|
noecho(); /* Don't show the player input */
|
|
while (checkWin(gs)) {
|
|
updateScreen(gs);
|
|
playerInput(gs);
|
|
}
|
|
getch();
|
|
free(gs);
|
|
return 0;
|
|
}
|
|
|
|
void quitProgram(void) {
|
|
endwin();
|
|
}
|
|
|
|
|
|
void updateScreen(game_state *gs) {
|
|
mvprintw(1, 1, "Remaining wrong guesses: %i", (gs->allowedMoves - gs->moves));
|
|
mvprintw(gs->maxy - 1, 1, "Press ctrl + c to exit.");
|
|
drawGuessWord(gs);
|
|
mvprintw(2, 1, "Wrong characters: %s", gs->wrongCharacters);
|
|
refresh();
|
|
}
|
|
|
|
void initCoordinates(game_state *gs) {
|
|
getmaxyx(stdscr, gs->maxy, gs->maxx);
|
|
gs->centery = gs->maxy / 2;
|
|
gs->centerx = gs->maxx / 2;
|
|
}
|
|
|
|
void initGuessWord(game_state *gs) {
|
|
int i;
|
|
mvprintw(1, 1, "Please enter your word: ");
|
|
getstr(gs->guessWord);
|
|
gs->wordLength = strlen(gs->guessWord);
|
|
for (i = 0; i < gs->wordLength; i++) {
|
|
gs->currentWord[i] = '_';
|
|
}
|
|
clear(); //clear the screen
|
|
}
|
|
|
|
void drawGuessWord(game_state *gs) {
|
|
int startpos = gs->centerx - gs->wordLength;
|
|
int i, wordpos = 0;
|
|
int switchspace = 0;
|
|
for (i = startpos; i < startpos + (gs->wordLength * 2); i++) {
|
|
if (switchspace) {
|
|
/* this will place a space */
|
|
mvprintw(gs->centery, i, " ");
|
|
switchspace = 0;
|
|
} else {
|
|
mvprintw(gs->centery, i, "%c", gs->currentWord[wordpos++]);
|
|
switchspace = 1;
|
|
}
|
|
}
|
|
refresh();
|
|
}
|
|
|
|
int playerInput(game_state *gs) {
|
|
char inp;
|
|
int i, found = 0;
|
|
inp = getch();
|
|
|
|
for (i = 0; i < gs->wordLength; i++) {
|
|
if (inp == gs->guessWord[i]) {
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
if (found) {
|
|
/* found a valid character */
|
|
if (fillCurrentWord(gs, inp)) {
|
|
//gs->moves++;
|
|
gs->guesses++;
|
|
}
|
|
} else {
|
|
/* no valid character found */
|
|
if (stackWrongCharacter(gs, inp)) {
|
|
gs->moves++;
|
|
gs->guesses++;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int fillCurrentWord(game_state *gs, char validchar) {
|
|
int i, alreadyUsed = 0;
|
|
for (i = 0; i < gs->wordLength; i++) {
|
|
if (gs->currentWord[i] == validchar) {
|
|
alreadyUsed = 1;
|
|
break;
|
|
}
|
|
}
|
|
if (!alreadyUsed) {
|
|
for (i = 0; i < gs->wordLength; i++) {
|
|
if (gs->guessWord[i] == validchar) {
|
|
gs->currentWord[i] = validchar;
|
|
}
|
|
}
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int stackWrongCharacter(game_state *gs, char wrongchar) {
|
|
int i, alreadyUsed = 0;
|
|
for (i = 0; i < gs->wordLength; i++) {
|
|
if (gs->wrongCharacters[i] == wrongchar) {
|
|
alreadyUsed = 1;
|
|
}
|
|
}
|
|
|
|
if (!alreadyUsed) {
|
|
gs->wrongCharacters[strlen(gs->wrongCharacters)] = wrongchar;
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int checkWin(game_state *gs) {
|
|
if (strcmp(gs->guessWord, gs->currentWord) != 0 && gs->moves < gs->allowedMoves) {
|
|
/* next move */
|
|
return 1;
|
|
} else {
|
|
/* game end: decide if game is won or lost */
|
|
printGameStats(gs);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void printGameStats(game_state *gs) {
|
|
clear();
|
|
if (gs->moves >= gs->allowedMoves) {
|
|
mvprintw(gs->centery, gs->centerx - 5, "Game lost.");
|
|
} else {
|
|
char message[100];
|
|
sprintf(message, "Game won! Total guesses: %i", gs->guesses);
|
|
mvprintw(gs->centery, gs->centerx - (strlen(message) / 2), message);
|
|
}
|
|
refresh();
|
|
}
|
|
|
|
|