From 4cb1732990a12a22707978b2eb80c50761e7f2a4 Mon Sep 17 00:00:00 2001 From: structix Date: Mon, 1 May 2017 17:24:17 +0200 Subject: [PATCH] Initial commit; basic functionality --- .gitignore | 4 ++ hangman.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++ hangman.h | 33 ++++++++++++ makefile | 20 +++++++ 4 files changed, 208 insertions(+) create mode 100644 .gitignore create mode 100644 hangman.c create mode 100644 hangman.h create mode 100644 makefile diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cfee947 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.c~ +*.h~ +*.o +/hangman diff --git a/hangman.c b/hangman.c new file mode 100644 index 0000000..3ed7192 --- /dev/null +++ b/hangman.c @@ -0,0 +1,151 @@ +#include +#include "hangman.h" +#include //atexit +#include + +int main(void) { + /* Initialization */ + initscr(); + atexit(quitProgram); + game_state *gs; + gs = malloc(sizeof(game_state)); + initCoordinates(gs); + gs->allowedMoves = DEFAULTTRIES; + gs->moves = 0; + curs_set(0); + + /* start game */ + initGuessWord(gs); + 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 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++; + } + } else { + /* no valid character found */ + if (stackWrongCharacter(gs, inp)) { + gs->moves++; + } + } + 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 */ + clear(); + if (gs->moves >= gs->allowedMoves) { + mvprintw(gs->centery, gs->centerx, "Game lost."); + } else { + mvprintw(gs->centery, gs->centerx, "Game won!"); + } + refresh(); + return 0; + } +} diff --git a/hangman.h b/hangman.h new file mode 100644 index 0000000..5172bf3 --- /dev/null +++ b/hangman.h @@ -0,0 +1,33 @@ +/* Defined macros */ +#define DEFAULTTRIES 9 + +/* Data structures */ +typedef struct { + int moves; + int allowedMoves; + int maxy; + int maxx; + int centery; + int centerx; + char guessWord[100]; + int wordLength; + char currentWord[100]; + char wrongCharacters[DEFAULTTRIES]; +} game_state; + +typedef struct word { + char character; + struct word *next; +} word; + + +/* Function prototypes */ +void quitProgram(void); +void updateScreen(game_state *gs); +void initCoordinates(game_state *gs); +void initGuessWord(game_state *gs); +void drawGuessWord(game_state *gs); +int playerInput(game_state *gs); +int fillCurrentWord(game_state *gs, char validchar); +int stackWrongCharacter(game_state *gs, char wrongchar); +int checkWin(game_state *gs); diff --git a/makefile b/makefile new file mode 100644 index 0000000..b9f39f1 --- /dev/null +++ b/makefile @@ -0,0 +1,20 @@ +#Infos: http://www.ijon.de/comp/tutorials/makefile.html + + +VERSION = 1.0 +CC = /usr/bin/gcc +CFLAGS = -Wall -g -D_REENTRANT -DVERSION=\"$(VERSION)\" +#LDFLAGS = -lm -lpthread `gtk-config --cflags` `gtk-config --libs` -lgthread +LDFLAGS = -lncurses + +OBJ = hangman.o + +lcdclock: $(OBJ) + $(CC) $(CFLAGS) -o hangman $(OBJ) $(LDFLAGS) + +%.o: %.c + $(CC) $(CFLAGS) -c $< + +.PHONY: clean +clean: + rm -r *.o