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; }