/* Program 1 Programmer: Dan Bennett Date : Jan 2013 Play a game of hangman. This program will play a game of hangman, the computer will select words from an input file and allow the user to guess letters in the word. The user gets 5 incorrect letters before they lose that round of the game. This program uses a trick of constructing a "guessed" word, which is all blanks in the beginning, but gets filled in as the game goes by. Thus _ can not be part of any word selected. It works somewhat like "wheel of fortune" in that it allows for phrases not just words. */ #include #include #include using namespace std; // note, I only used function prototypes for high level functions. // The others are declared before they are used. // // Your choice on this. We will find a way to do this better (or different) // later in the semester. bool PlayAnotherGame(void); void FixAWord(string & ); string GetAWord(ifstream & wordFile); void DisplayCurrentGame(string word, string badLetters, int turn); void PlayAGame(string word, int & wins); void PrintStats(int games, int wins); void Greeting(void ); // input file name const string WORD_FILE_NAME = "phrases.txt" ; // constants associated with drawing the suspect on the gallows. const char LEFT_ARM = '\\'; const char HEAD = '0'; const char RIGHT_ARM = '/'; const char BODY = '|'; const char LEFT_LEG = '/'; const char RIGHT_LEG = '\\'; const int LEFT_ARM_COUNT = 1; const int HEAD_COUNT = 2; const int RIGHT_ARM_COUNT = 3; const int BODY_COUNT = 4; const int LEFT_LEG_COUNT = 5; const int RIGHT_LEG_COUNT = 6; int main() { ifstream wordFile; bool done = false; int wins =0, games = 0; string word; wordFile.open(WORD_FILE_NAME.c_str()); Greeting(); while(not done) { games ++; word= GetAWord(wordFile); PlayAGame(word, wins); done = not PlayAnotherGame(); } wordFile.close(); PrintStats(games, wins); return 0; } /* This routine will ask the player if they wish to play another game. No input, Boolean output, true if they want to play another game. */ bool PlayAnotherGame(void){ char answer = 'x'; do { cout << "Do you want to play another game?"; cout << " (y/n) => "; cin >> answer; answer = tolower(answer); } while (answer != 'y' and answer != 'n'); return answer == 'y'; } /* This routine will get the next word from the file. Remember the assumption that the file will have at least one word in it. The routine will start at the top when the end of file is hit. The routine will read all of the data on a line. It will also replace any _ in the string with a space Input: The open file Output: The corrected input phrase. */ string GetAWord(ifstream & wordFile){ string word; // read the word getline(wordFile, word); // if we are at the end of the file if (not wordFile) { // reset wordFile.close(); wordFile.open(WORD_FILE_NAME.c_str()); // read the word. getline(wordFile, word); } FixAWord(word); return word; } /* This routine will "fix" a word. This involves: changeing the case of all letters to lowercase rmoving all _, and replacing them with a space. Input/Output: The word. */ void FixAWord(string & word){ int i; for(i=0;i= partMin) { cout << part; } else { cout << " "; } return; } // Nasty routine to draw the gallows and the poor fellow dangling. // // This uses the fact that the number of incorrect letters determines // how far the suspect has been hung. // // Input: The word and the bad letters // Output: none void DrawPicture(string word, string badLetters){ int i; // top of gallows cout << " +--+" << endl; cout << " | |" << endl; // arms and head if needed cout << " | "; DisplayBodyPart(badLetters.size(), LEFT_ARM, LEFT_ARM_COUNT); DisplayBodyPart(badLetters.size(), HEAD, HEAD_COUNT); DisplayBodyPart(badLetters.size(), RIGHT_ARM, RIGHT_ARM_COUNT); cout << endl; // main body cout << " | "; DisplayBodyPart(badLetters.size(), BODY, BODY_COUNT); cout << endl; // legs cout << " | "; DisplayBodyPart(badLetters.size(), LEFT_LEG, LEFT_LEG_COUNT); cout << " "; DisplayBodyPart(badLetters.size(), RIGHT_LEG, RIGHT_LEG_COUNT); cout << endl; // air to dangle in cout << " |" << endl; // platorm cout << "_+_______ "; // the word for (i=0;i "; cin >> letter; } while (not isalpha(letter)); return tolower(letter); } /* This routine will do two things: It will decide if the guessed letter is in the word If so it will add that letter to the correct guess if not it will add the letter to the bad letters Input: The word to guess The letter guessed Output the guessed word so far the list of bad letters */ void DoAPlay(string word, char letter, string & solved, string & bad){ int i; if (word.find(letter) != string::npos) { i = word.find(letter); while (i != string::npos) { solved[i] = word[i]; i = word.find(letter,i+1); } } else { bad += letter; } return; } // This routine informs the player of a win or loss. // input the incorrectly guessed letters // the word the player has guessed // The turn number // The word the player was trying to guess // output // The number of wins so far. void DoWinOrLoss(string badLetters, string solvedWord, int turn, string word, int & wins){ if(badLetters.size() >= RIGHT_LEG_COUNT) { DisplayCurrentGame(solvedWord, badLetters, turn); cout << "You have been convicted and hung!" << endl; cout << "The word was " << word << endl; cout << "Your guess was " << solvedWord << endl; } else { cout << "You are innocent" << endl; cout << "You guessed " << word << " correctly!"<< endl; wins ++; } cout << endl; return; } // logic to play a game. // // Input the word to guess // Output The number of wins so far. void PlayAGame(string word, int & wins){ int turn = 1; string badLetters, solvedWord; char letter; MakeSolvedWord(solvedWord, word); // if _ is in the guessed word, then it is not done. // If there are RIGHT_LEG_COUNT (or more?) letters the player has lost // This is essentually while not won or lost while(solvedWord.find('_') != string::npos and badLetters.size() < RIGHT_LEG_COUNT) { turn ++; DisplayCurrentGame(solvedWord, badLetters, turn); letter = GetALetter(); DoAPlay(word, letter, solvedWord, badLetters); } DoWinOrLoss(badLetters, solvedWord, turn, word,wins); return; } // this routine prints the final statistics. // Input wins and games played // Output None void PrintStats(int games, int wins){ cout << endl; cout << "Games Played: " << games << endl; cout << "Games Won " << wins << endl; cout << "Thanks for playing! " << endl; return; } void Greeting(void ) { cout << "Hello, welcome to hangman" << endl; cout << endl; return; }