#include #include "hangman.h" #include //atexit #include #include //tolower 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; /* Show the start screen */ curs_set(0); showStartScreen(gs); /* 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 showStartScreen(game_state *gs) { mvprintw(gs->centery - 1, gs->centerx - 15, "Welcome to hangman in ncurses."); mvprintw(gs->centery, gs->centerx - 5, "Have fun!"); mvprintw(gs->centery + 1, gs->centerx - 17, "https://gitlab.com/STRUCTiX/hangman"); refresh(); getch(); clear(); } 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: "); curs_set(1); getstr(gs->guessWord); curs_set(0); 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] = ' '; } else { gs->currentWord[i] = '_'; } } clear(); //clear the screen } void toLowerCase(char *str) { int length = strlen(str); int i; for (i = 0; i < length; i++) { str[i] = tolower(str[i]); } } 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(); }