+1 (315) 557-6473 

Create A Hangman Game in C Assignment Solution.


Instructions

Objective
Write a C assignment program to create a hangman game.

Requirements and Specifications

= Hangman
== Task Specification
Implement a simple link:https://en.wikipedia.org/wiki/Hangman_(game)[_Hangman_] game, where one player has to guess a word.
. Main Task (30 points)
Supply the word to guess on the command line.
Let the user guess character by character and inform him about the state of the game (cf. <>).
Do not distinguish between lower- and uppercase characters, i.e. use an alphabet of only 26 symbols.
Write the progress of the game into a log file including the time of the user inputs (cf. time.h). Clearly mark the start and end of each game and do not overwrite an existing log file.
2Task (15 points)* +
Allow the user to directly guess the whole word instead of a single character and end the game immediately afterwards (the player looses if he guesses wrong).
. 3Task (10 points) +
Support multiple game rounds without restarting the game.
Supply a new word for each round in a sensible way.
. 4Task (15 points) +
Instead of supplying the word directly the user has to specify an input file that contains possible words to guess.
Select any word from that list at random.
.5 Task (15 points) +
Mark used words persistently in the word input file.
Exclude previously used words when selecting a random word.
Allow the user to reset the markers in the file.
.6 Task (25 points) + Instead of the simpler version above implement the following user interface: +
Draw the used interface including a depiction of the gallows and body parts using the ncurses library (cf. link:https://en.wikipedia.org/wiki/Ncurses[Wikipedia], link:http://invisible-island.net/ncurses/ncurses-intro.html[Howto by one of the ncurses authors], link:http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/[TLDP Howto]).
Draw the gallows and the parts of the hanging stick figure in simple link:https://en.wikipedia.org/wiki/ASCII_art[ASCII graphics].
Do not require the user to hit enter after each character.
. Task (15 points) +
The program arguments are handled by getopt(3).
== Example Execution[[exec]]
Source Code
#include
#include
#include
#include
#include
#include
// number of tries to guess the word
#define TRIES_LIMIT 8
// input line limit
#define MAX_LINE 1024
// max number of words in file
#define MAX_WORDS 100
// default words file name
#define WORDS_FILENAME "words.txt"
// default log file name
#define LOG_FILENAME "log.txt"
FILE *logFile;
// method for logging a message
void logInfo(char* message) {
 // creating timestamp string
 char buff[20];
  struct tm *sTm;
  time_t now = time (0);
  sTm = gmtime (&now);
 strftime (buff, sizeof(buff), "%Y-%m-%d %H:%M:%S", sTm);
 // outputting timestamp and message to log file
  fprintf (logFile, "%s %s\n", buff, message);
}
// method for reading word list and used array from word file
int readWords(char* wordsFileName, char words[MAX_WORDS][MAX_LINE], int* used) {
 char line[MAX_LINE];
 int count = 0, available = 0, i;
 // opening file
 FILE *f = fopen(wordsFileName, "r");
 // reading line, while there are lines to read
 while(fgets(line, MAX_LINE, f) != NULL) {
  // reading word
  sscanf(line, "%s", words[count]);
  for (i = 0; i
   words[count][i] = toupper(words[count][i]);
  }
  // reading used flag
  sscanf(line, "%d", &used[count]);
  // counting available words
  if (used[count] == 1) {
   available++;
  }
  // counting all words
  count++;
 }
 fclose(f);
 // returning number of words
 return count;
}
// method for choosing randomly a single words for game from word list
int chooseWord(int n, char words[MAX_WORDS][MAX_LINE], int* used) {
 srand(time(NULL));
 int i, available = 0, r, count = 0;
 // checking if there are available words and reset if needed
 while (available == 0) {
  available = 0;
  for (i = 0; i
   if (used[i] == 1) {
    available++;
   }
  }
  // there are available words - no need to reset
  if (available > 0) {
   break;
  }
  // no words available - we need to reset used array
  for (i = 0; i
   used[i] = 1;
  }
 }
 // choosing random word from available list
 r = rand() % available;
 for (i = 0; i
  if (used[i] == 1) {
   if (count == r) {
    used[i] = 0;
    return i;
   }
   count++;
  }
 }
 return -1;
}
// method for updating word list with new used array state
void saveWords(int n, char words[MAX_WORDS][MAX_LINE], int* used) {
 int i;
 // opening file for writing
 FILE *f = fopen(WORDS_FILENAME, "w");
 // printing data for each word
 for(i = 0; i < n; i++) {
  fprintf(f, "%s %d\n", words[i], used[i]);
 }
 fclose(f);
}
// method for reading user integer choice
int readUsersIntChoice(char* prompt, int max) {
 // keep repeating until valid input
 while(1) {
  char line[MAX_LINE];
  int choice;
  // prompting user
  printf("%s: ", prompt);
  // reading line and converting it to int
  gets(line);
  choice = atoi(line);
  // choice must be in [1,max]
  if (choice <= 0 || choice > max) {
   // otherwise it is invalid
   printf("Invalid input.\n");
  }
  else {
   printf("\n");
   // if input is valid, returning it
   return choice;
  }
 }
}
// method for reading user char choice
char readUsersCharChoice(char* prompt) {
 while(1) {
  char line[MAX_LINE];
  // keep repeating until valid input
  printf("%s: ", prompt);
   // reading line
  gets(line);
  // everything is valid besides empty line
  if (strlen(line) > 0) {
   // if line is not empty, return first character
   printf("\n");
   return line[0];
  }
  printf("Invalid input\n");
 }
}
// method for opening a single character in current game state
int open(char* word, char* state, char c) {
 // uppercasing letter
 char cUp = toupper(c);
 int i, opened = 0, len = strlen(word);
 // going through the word array and trying to open it
 for (i = 0; i
  if (toupper(word[i]) == cUp && state[i] == '_') {
   state[i] = cUp;
   // counting open letters
   opened++;
  }
 }
 return opened;
}
// method which makes single game rounf
void playGame(char* word) {
 // logging
 logInfo("New game started");
 int i, len = strlen(word);
 char state[len+1], buf[MAX_LINE + 40];
 // creating new empty state word of secret word length
 for(i = 0; i
  state[i] = '_';
 }
 state[len] = 0;
 int tries = TRIES_LIMIT;
 int left = len;
 // keep iterating until game is over
 while(tries > 0 && left > 0) {
  printf("-----------------------\n");
  printf("Current state: %s\n", state);
  // logging
  sprintf(buf, "Current state: %s", state);
  logInfo(buf);
  printf("Tries left: %d\n", tries);
  // logging
  sprintf(buf, "Tries left: %d", tries);
  logInfo(buf);
  // reading user game option
  int choice = readUsersIntChoice("Options:\n1. Open a letter\n2. Guess the word\nPlease, enter your choice", 2);
  if (choice == 1) {
   // reading single character
   char c = readUsersCharChoice("Please, enter character");
   // trying to open entered letter
   int opened = open(word, state, c);
   // logging
   sprintf(buf, "User tries to open letter: %c", c);
   logInfo(buf);
   // if there were more, than 0 open letters - the move was successful
   if (opened > 0) {
    left -= opened;
    printf("Success! You opened %d letter(s)\n", opened);
    sprintf(buf, "User opened %d letter(s)", opened);
    logInfo(buf);
   }
   else {
    // there were no open letters - move was bad
    tries--;
    printf("Fail! Can not open such letter\n");
    logInfo("User fails. No such letter");
   }
  }
  else {
   // user tries to guess the whole word
   printf("Please, enter your guess: ");
   char guess[MAX_LINE];
   // reading user's guess
   gets(guess);
   // logging
   sprintf(buf, "User tries to guess the word letter: %s", guess);
   logInfo(buf);
   for (i = 0; i
    guess[i] = toupper(guess[i]);
   }
   // comparing guess with secret word
   if (strcmp(guess, word) == 0) {
    left = 0;
   }
   else {
    tries = 0;
   }
   break;
  }
 }
 // analyzing game end and output messages
 printf("=======================\n");
 if (left > 0) {
  printf("You lost... The correct word was '%s'\n", word);
  sprintf(buf, "User LOST. The correct word was '%s'", word);
  logInfo(buf);
 }
 else {
  printf("You WON!\n");
  logInfo("User WON");
 }
 logInfo("Game finished");
}
int main(int argc, char** argv) {
 char words[MAX_WORDS][MAX_LINE], singleWord[MAX_LINE];
 int used[MAX_WORDS];
 char* logFileName = LOG_FILENAME, *wordsFileName = WORDS_FILENAME;
 int totalWords, a, useSingleWord = 0;
 // parsing command line arguments
 while ((a = getopt(argc, argv, "l:w:")) != -1) {
    switch (a)
      {
   // custom log file name
      case 'l':
        logFileName = optarg;
        break;
   // custom word file name
      case 'w':
        wordsFileName = optarg;
        break;
      default:
    printf("Unknown command line argument. Terminating\n");
        abort ();
      }
 }
 for (a = optind; a < argc; a++) {
  int i;
  strcpy(singleWord, argv[a]);
  for (i = 0; i
   singleWord[i] = toupper(singleWord[i]);
  }
  useSingleWord = 1;
 }
 // opening log file
 logFile = fopen(logFileName, "w");
 logInfo("Application started");
 // reading words
 totalWords = readWords(wordsFileName, words, used);
 // keep repeating new rounds of game, while needed
 while(1) {
  if (useSingleWord == 0) {
   // choosing word
   int w = chooseWord(totalWords, words, used);
   // updating word usage array
   saveWords(totalWords, words, used);
   playGame(words[w]);
  }
  else {
   playGame(singleWord);
  }
  printf("==================================\n");
  // asking user, if he wants play one more time
  if (readUsersIntChoice("Do you want to play one more time?\n1. Yes\n2. No\nPlease, enter your choice", 2) == 2) {
   break;
  }
 }
 // finishing
 logInfo("Application finished");
 fclose(logFile);
  return 0;