Initial commit; basic functionality

This commit is contained in:
2017-05-01 17:24:17 +02:00
parent 5b1e0121df
commit 4cb1732990
4 changed files with 208 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
*.c~
*.h~
*.o
/hangman

151
hangman.c Normal file
View File

@@ -0,0 +1,151 @@
#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;
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;
}
}

33
hangman.h Normal file
View File

@@ -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);

20
makefile Normal file
View File

@@ -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