Logo
IT Dienstleistungen

Color Hangman

Simple Hangman Game for the command-line, maybe I'll put a already developed Version with Socketsupport online somedayy.

The Game uses ANSI Terminalcolors, has a Highscorelist and 3 skill-levels. Needs wordlist.txt as word-source in the same directory as the binary. If not available, a optional file could given via parameter (other language, etc). The Word-Sourcefile must contain one word a line, don't forget the return after the LAST word or it will be ignored.

Known Bugs

  • Scorecalculation does not what was expected. work
  • still using gets() sollution not implemented yet
hangman.c
/***************************************************************************
 *   Copyright (C) 2008 by Manuel Krischer   *
 *   manuel@edv-krischer.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
 
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define MAX_WORDS	 1024
#define MAX_WORD_LENGTH	 32
#define HIGHSCORE_MEMBER 10
 
/*Player variables - content changes with the skill-level*/
unsigned int lives = 0; /*number of trys*/
unsigned int level = 0; /**/
 
/*name of the scorefile*/
char *scorefile = "scores.txt";
 
/*made struct for highscore*/
struct highscore {
            char name[8];
    unsigned int points;
};
 
/*initialise struct with zeros*/
struct highscore ranking[10] = {
				"noname",0,
				"noname",0,
				"noname",0,
				"noname",0,
				"noname",0,
				"noname",0,
				"noname",0,
				"noname",0,
				"noname",0,
				"noname",0
                                };
 
unsigned int double_damage = 0; /*if set to 1, submitting a letter twice costs a live*/
long score = 0;
 
/*
main shit
*/
int main(int argc, char *argv[]) {
 
	/*check if user wants new wordfile, otherwise take default wordlist.txt*/
	char wordfile[512];			/*name of the file with the words*/
	int wordcount;				/*number of words found in file*/
 
	if (argc > 1 && (strlen(argv[1]) < 512)) {
		strcpy(wordfile,argv[1]);
	}
	else {
		strcpy(wordfile, "wordlist.txt");
	}
 
	char wordarray[MAX_WORDS][MAX_WORD_LENGTH];	
 
	/*Programm starts with Output here*/
	printf("\n\033[1;31m* * *  H A N G M A N   4   F R E A K S  * * *\033[0m\n\n");
 
	/*call the read function to get words in the word array. only needed once a run!*/
	wordcount = read_words(wordfile, wordarray, MAX_WORDS, MAX_WORD_LENGTH);
	if (wordcount < 0) {
                fprintf(stderr, "Error: File not Exist!\n");
		return 1;
	}
	/*now it's time to read the highscore from file*/
	read_highscore();
 
/*STARTING MENU LOOP HERE*/
	char choose[2];	
	do {
 
		printf("\n  \033[1;47m Please make your selection:               \033[0m\n");
		printf("  \033[1;42m (1) \033[0m Easy Game (simple Rules, small score)\n");
		printf("  \033[1;43m (2) \033[0m Medium Game (normal Rules and score) \n");
		printf("  \033[1;41m (3) \033[0m Hard Game (strict Rules, big score)  \n");
		printf("  \033[1;44m (4) \033[0m View Highscore                       \n");
		printf("  \033[1;45m (5) \033[0m Exit Hangman                         \n\n");
		printf("\n  Input > ");
		gets(choose);		
			if (atoi(choose) == 1) {
					printf("\n\n  \033[1;42m You are a wimp! Easy Game is for kids and loser!\033[0m\n");
					printf("  Level: Don't hurt me, daddy!\n");
					level = 1;
					/* start the gamefunction */
					score = play(wordarray, wordcount);
					/*check if score passes old value, if true prompt for name*/
					if (check_highscore(score) == 1) {
						new_highscore(score);
						show_highscore();
					}
					else {
						printf("\nNo new Highscore reached with %d Points!\n", score);
					}
			}
			if (atoi(choose) == 2) {
					printf("\n\n  \033[1;43m Come on! You don't trust yourself for real!\033[0m\n");
					printf("  Level: Damn, I'm good!\n");
					level = 2;
					score = play(wordarray, wordcount);
					/*check if score passes old value, if true prompt for name*/
					if (check_highscore(score) == 1) {
						new_highscore(score);
						show_highscore();
					}
					else {
						printf("\nNo new Highscore reached with %d Points!\n", score);
					}					
			}
			if (atoi(choose) == 3) {
					printf("\n\n  \033[1;41m Mess with best or die like the rest!\033[0m\n");
					printf("  Level: Bring 'em on!\n");
					level = 3;
					score = play(wordarray, wordcount);
					/*check if score passes old value, if true prompt for name*/
					if (check_highscore(score) == 1) {
						new_highscore(score);
						show_highscore();
					}
					else {
						printf("\n  No new Highscore reached with\033[1;35m %d Points!\033[0m\n", score);
					}
			}
			if (atoi(choose) == 4) {					
					show_highscore(0);
			}			
	} while (atoi(choose) != 5);
	/*game ends here*/
	printf("\n  \033[5;45m You don't wanna leave yet, won't you? \033[0m\n\n");
  return EXIT_SUCCESS;
}
 
/* read_words()
need wordfile, an char array for the words, a number of words to read in and max_length of single words <= arraysize
gives back number of words read in, -1 for errors and 0 for empty file.
*/
int read_words(char *wordfile, char array[][MAX_WORD_LENGTH], int max_words) {	
	int rows=0, chars=0;
	FILE * filed = fopen(wordfile, "r");
	if (filed == 0 ) {
                return -1;
        }
	char temp[MAX_WORD_LENGTH+1];
	/*get first line, set null-byte instead of linechange*/
	fgets(temp, MAX_WORD_LENGTH, filed);		
	while (! feof(filed) && rows < max_words-1) {		
		chars = strlen(temp);
		temp[chars-1] = '\0';
		strcpy(array[rows++],temp);
		fgets(temp, MAX_WORD_LENGTH, filed);
	}
return rows;
}
 
/* print_words(array_with_words)
simply prints out the whole word list
*/
print_words(char array[][MAX_WORD_LENGTH], int max) {
	int i;	
	for (i=0; i<max; i++) {
		printf("%3d: %s\n",i+1, array[i]);
	}
}
 
/* give_rnd_word()
gives random number from given array as char array
*/
int give_rnd_word(int max) {
	char word[MAX_WORD_LENGTH]; 
	int i;
	/*initialize randomnumber generator*/
	srand(time(NULL));
	/*Random number between zero and max_words*/
    	while ( i > max-1 || i < 0) {
        	i = rand()%max;
    	}
	/*printf("Zahl %d\n",i);*/
return i;
}
 
 
/* show_highscore()
show the actual highscore
*/
int show_highscore(long score) {
  int i;
    printf("\n  \033[1;42m * * *   HIGHSCORE   * * *  \033[0m\n");
    for (i=0; i<HIGHSCORE_MEMBER; i++) {
      /*mark the new score*/
        if (ranking[i].points == score && score != 0) {
            printf("  \033[0;43m\033[1;33m%3d. %11s\033[1;33m %10d \033[0m\033[0m\n", i+1, ranking[i].name, ranking[i].points);
        }
        else {
            printf("  %3d. %11s %10d\n",i+1,ranking[i].name, ranking[i].points);
        }
    }
    printf("\n\n");
return 0;
}
 
/* read_highscore()
reads the highscore file and put the content into the struct
*/
read_highscore(){
     int geschafft = 0;
     int i = 0, j = 0, k = 0;
     char string[32];
     char temp[24];
 
     FILE * datei = fopen(scorefile, "r");
     if (datei == 0)  {
         return -1;
      }
      /*array aus Datei lesen*/
     for (i=0; i<HIGHSCORE_MEMBER; i++) {
         fgets(string, 32 ,datei);
         strcpy(ranking[i].name,strtok(string," "));
         ranking[i].points = atoi(strtok(NULL,";"));
     }
     fclose(datei);
return 0;
}
 
/* new_highscore(score)
enter the new highscore in the struct, sort the struct and writes it back to disk
*/
int new_highscore(long score) {
	char player[512];
 
	printf("\n  \033[0;43m You really made it into the Highscore!\033[0m");
	printf("\n  \033[0;32mPlease enter your Name [10 Chars]: \033[0m");
	gets(player);
 
	/*copy player values to the last place*/
	ranking[HIGHSCORE_MEMBER-1].points = score;
	strcpy(ranking[HIGHSCORE_MEMBER-1].name, player);
 
	/*sort struct by points*/
	int i,j;
	struct highscore *temp;	
	temp = (struct highscore *)malloc(sizeof(struct highscore *));
		if(NULL == temp) {
           printf("memory failure...\n");
           return 1;
       }
	for(i=0; i<HIGHSCORE_MEMBER; i++) {
           for(j=i+1; j<HIGHSCORE_MEMBER; j++) {
              if(ranking[i].points < ranking[j].points) {
                  *temp      = ranking[j];
                  ranking[j] = ranking[i];
                  ranking[i] = *temp;
              }
           }
       }
	/*write everything in the scorefile*/
	FILE * filed = fopen(scorefile, "w");
	if (filed == 0)  {
		printf("opening scorefile failure\n");
		return -1;
	}
	for (i=0; i<HIGHSCORE_MEMBER; i++) {
		fprintf(filed,"%10s %10d;\n", ranking[i].name, ranking[i].points);
	}
	fclose(filed);
return 0;
}
 
/* check_highscore(score)
Checks if the new Score is higher than actual scores, return 1 if it's higher, else zero
*/
check_highscore(long score) {
	int high = 0,i;
	/*compare the scores*/
	for (i=0; i<HIGHSCORE_MEMBER; i++) {
		if (score > ranking[i].points) {
			high = 1;
		}
	}
return high;
}
 
/* play()
runs the real game, returns highscore value
*/
int play(char array[][MAX_WORD_LENGTH], int max) {	
	int i,j,k; /*some counting ints*/
 
	char word_to_play[MAX_WORD_LENGTH];	/*storage of the random word selected*/
	char visual[MAX_WORD_LENGTH];		/*visualisation array*/	
	/*copy random word to play-array*/
 	strcpy(word_to_play, array[(give_rnd_word(max))]);
	int wordlength = strlen(word_to_play);
	//printf("Random selected word: %s\n", word_to_play); /*throw away for release*/
	/*initiaizing for skillllevel*/
	if (level == 1) { /*EEEEEEEEAAAASSSSY*/
		lives = wordlength;
		if (lives < 5) {
			lives += 2;
		}
		double_damage = 0;
	}
	if (level == 2) { /*medium*/
		lives = wordlength-1;
		if (lives < 4) {
			lives += 1;
		}
		if (lives > 10) {
			lives = 10;
		}
		double_damage = 0;
	}
	if (level == 3) { /*real hardcore*/
		lives = (wordlength>>1)-2;
		/*printf("%d %d",lives, wordlength);*/
		if (lives < 3) {
			lives = 3;
		}
		if (lives > 8) {
			lives = 8;
		}
		double_damage = 1;
	}
 
	/*initialize the visualarray*/
	for (i=0; i<wordlength; i++) {
		visual[i] = '-';
	}
	visual[wordlength] = '\0';
	/*zero some vars*/
	int trys = 0;  /*number of trys to get the word*/
	int true = 0;  /*set to 1, if the character is found, set to 2 if charakter is already typed*/
	int rightchars = 0;
	char character[2];
	char already_taken[256];
	char *color = "\033[1;32m";
	fflush(stdin);	
 
	while (strcmp(visual, word_to_play) != 0 ) {	
		true = 0;
		j=0;
		trys++;
 
		/*Color the amount of lives*/		
		if (lives < 7 ) color = "\033[1;35m";
		if (lives < 5 ) color = "\033[1;33m";
		if (lives < 3 ) color = "\033[1;31m";
 
		printf("\n  Your Task: [%s] - %s%d lives left\033[0m\n", visual, color, lives);
		printf("  Input > ");
 
		gets(character);
		character[1] = '\0';
 
		/*copy char to the already_taken array*/	
		already_taken[k++] = character[0];
 
		/*search if char is in the search_word*/
		for (i=0; i<wordlength; i++) {
			if (character[0] == word_to_play[i]) {
				visual[i] = word_to_play[i];
				true = 1;
				j++;
			}			
		}
		/*check if char is here for the second time*/	
		for (i=0; i<k-1; i++) {
			if (character[0] == already_taken[i]) {
				j--;
				true = 2;
			}
		}
 
		/*Check for penalties*/
		if (true == 0)  {
			printf ("  \033[1;31mThis Character is not inside the word! \033[0m\n");
			lives--;
		}
		if (true == 1) {
			printf ("  \033[1;32mFound '%c' %d time(s)! \033[0m\n",character[0], j);
			rightchars++; /*Number of right characters*/
 
		}
		if (true == 2) {
			printf ("  \033[1;33mCharacter already tried! \033[0m\n");
			if (double_damage == 1) {
				lives--;
			}
		}
		/*check for lives*/
		if (lives < 1) {
			printf("\n\n  \033[5;41m You wouldn't made it with another 25 tries, Loser! \033[0m\n\n\n\n\n\n");			
			score = level*rightchars*10;
			return score;	
		}
	}
	/*calculate score*/
	if (strcmp(visual, word_to_play) == 0) {
		/*use: level, lives, rightchars, wordlength*/
		score = (( ((lives)/(wordlength/2))*100 - (2*(trys-wordlength))) * (150*level*rightchars));	
	}
	printf("\n  \033[1;33mYour Score: %d\033[0m\n",score);
return score;
}

Seiten-Werkzeuge