Initial commit; basic functionality
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
*.c~
|
||||
*.h~
|
||||
*.o
|
||||
/hangman
|
151
hangman.c
Normal file
151
hangman.c
Normal 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
33
hangman.h
Normal 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
20
makefile
Normal 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
|
Reference in New Issue
Block a user