// Description: This is a computer version of the game hangman, the user
// can play against a 2nd player or the computer, and he can enter how many 
// guesses he gets,
//

// Start of program

// Header file definitions

#include <iostream>				// Standard input/output
#include <string>				// String manipulation
#include <cctype>				// Character manipulation and testing
#include <fstream>				// File stream
#include <cstdlib>				// Used for random function

#include "DRAW.h"				// Draws hangman

using namespace std;

// Function declerations
void DrawGallows(int State);
void instruction(int& choice);		// Gives instructions and gets choice
void usergame(int i);				// Plays 2nd user game
void compgame(int i);				// Plays against computer
void test(string word, char letter, int& numwrong, string& temp, int i);		// Tests current letter and replaces starred word
void lchosen(char letter, string& letterchosen, int& check, int& chosencounter, int i);			// Checks current letter and adds it to letters chosen output if not entered already
void rnd(string& word, int i);		// Gets random word from file

inline istream& Flush(istream& stream);				// Flushes cin stream

// Start of main

int main()
{	
	int i = 0;			// Counter variable for loops
	int exit = 0;		// Main loop exit variable
	int choice;			// Users inputed choice for type of game or to exit

	// Main control loop

	do {				// while exit != 1
		system("cls"); // Clear the screen
		instruction(choice);		// Give instructions


		switch(choice)
		{
		case 1:
			usergame(i);			// Calls user game
			break;
		case 2: 
			compgame(i);			// Calls computer game
			break;
		case 3:
			cout << "Goodbye" << endl;	// Exits
			exit = 1;
			break;
		default:
			cerr << "Invalid choice - try again" << endl;    // Invalid choice erroe
		}
	} while (exit != 1);

	// End main loop

	system("pause");
	return 0;
}
// End main

// Subprograms
// ---------------------------------------------------------------------

// Instructions subprogram

void instruction(int& choice)
{	
	cout << "			-Hangman-" << endl << endl;
	cout << "		Created by Kyle Burmark" << endl << endl;
	cout << "*****************************************" << endl;
	cout << endl;
	cout << " Enter -1- to play against user" << endl;
	cout << " Enter -2- to play against computer" << endl;
	cout << " Enter -3- to quit" << endl;
	cout << endl;
	cout << "*****************************************" << endl << endl;
	
	cout << "Choice: ";		// Get user choice
	cin >> choice;

	// Bad data type check

	while (!cin)
	{
		cerr << "Invalid character" << endl
			<< "Enter again - choice: ";
		Flush(cin);
		cin >> choice;
	}

	// End check

	system("cls");
}

// End instruction

// User game subprogram

void usergame(int i)
{
	int numguess = 0;			// Number of guesses player gets
	int numwrong = 0;			// Number of wrong guesses player has so far
	int check;					// A variable to test whether to check the letter entered in the test function
	int wordcheck;				// A variable to check whether the user has entered an invalid word
	int end = 0;				// A variable to test what to output to the user and to exit the usergame loop
	int chosencounter = 0;		// A counter to tell the replace function where to put the letter chosen in the letterchosen string
	char letter;				// User inputed letter
	string word;				// Word user is trying to guess
	string temp;				// Updated output word user sees
	string letterchosen = "                         ";		// Defines length of letterchosen string

	do {				// while user puts in guesses outside of allowed range
	cout << "How many chances does the person have (4 - 10): ";
	cin >> numguess;
	} while (numguess < 4 || numguess > 10);

	cout << "Enter word 2nd user: ";
	cin >> word;


	do {				// while user inputs bad word
		wordcheck = 0;
		for (int i = 0; i < word.length(); i++)
		{
			if (!isalpha(word.at(i)))
			{
				wordcheck = 1;
			}
		}
		if (wordcheck == 1)
		{
			cout << "Invalid - Enter word again: ";
			cin >> word; 
		}
	} while (wordcheck == 1);

	temp = word;		// Sets temp string length to word string length
	
	// Replace temp with stars loop

	for (i = 0; i < word.length(); i++)
	{
		temp.replace(i, 1, 1,'*');
	}
	
	// End loop

	system("cls");
	
	// Main game loop

	do {
	

		// Tests if user guessed word

		if (word == temp)
		{
			cout << endl << endl;
			cout << "You guessed it [ " << word << " ]" << endl << endl;
			system("pause");
			end = 1;
		}

		// Tests if user failed to guess word

		if (numwrong == numguess)
		{
			cout << endl << endl;
			cout << "You failed" << endl << endl;
			system("pause");
			end = 2;
		}

		// Play while above conditions aren't true

		if (end == 0)
		{
			cout << endl << endl << endl;
			cout << "Letters chosen: " << letterchosen << endl;
			cout << endl << endl << endl;
			cout << "Guesses left: " << numguess - numwrong << endl << endl; 
			cout << "    " << temp << endl << endl;
			cout << "Letter: ";
			cin >> letter;

			// Test for bad letter

			while (!isalpha(letter))
			{
				Flush(cin);
				cout << "Not a letter - enter letter: ";
				cin >> letter;
			}

			// End test

			lchosen(letter, letterchosen, check, chosencounter, i);
			
			// Test whether to check letter against correct word string

			if (check == 0)
			{
				test(word, letter, numwrong, temp, i);
			}
			else
			{
				;
			}

			// End test

			system("cls");
		}

		// End game
		
		system("cls");
	} while(end != 1 && end != 2);
	
	// End main game loop

	// Tests end variable to see what to display

	if (end == 2) 
	{
		cout << "Correct word was [ " << word << " ]" << endl << endl;
		system("pause");
	}
	if (end == 1)
	{
		cout << " ";
	}

	system("cls");
	
}

// End user game

// Start computer game
// See user game for variable and loop information

void compgame(int i)
{
	int numguess = 0;
	int numwrong = 0;
	int check;
	int end = 0;
	int chosencounter = 0;
	char letter;
	string word;
	string temp;
	string letterchosen = "                         ";
	
	do {
	cout << "How many chances do you want (4 - 10): ";
	cin >> numguess;
	} while (numguess < 4 || numguess > 10);

	rnd(word, i);		// Gets random word
	temp = word;

	for (i = 0; i < word.length(); i++)
	{
		temp.replace(i, 1, 1, '*');
	}

	system("cls");

	do {
        int State = 1;
	void DrawGallows(int State);
		if (word == temp)
		{
			cout << endl << endl;
			cout << "You guessed it [ " << word << " ]" << endl << endl;
			system("pause");
			end = 1;
		}
		if (numwrong == numguess)
		{
			cout << endl << endl;
			cout << "You failed" << endl << endl;
			system("pause");
			end = 2;
		}
		if (end == 0)
		{
			cout << endl << endl << endl;
			cout << "Letters chosen: " << letterchosen << endl;
			cout << endl << endl << endl;
			cout << "Guesses left: " << numguess - numwrong << endl << endl; 
			cout << "    " << temp << endl << endl;
			cout << "Letter: ";
			cin >> letter;

			while (!isalpha(letter))
			{
				Flush(cin);
				cout << "Not a letter - enter letter: ";
				cin >> letter;
			}

			lchosen(letter, letterchosen, check, chosencounter, i);
			
			if (check == 0)
			{
				test(word, letter, numwrong, temp, i);
			}
			else
			{
				;
			}

			system("cls");
		}
		
		system("cls");
	} while(end != 1 && end != 2);

	if (end == 2) 
		cout << "Correct word was [ " << word << " ]" << endl << endl;
		system("pause");
	if (end == 1)
		cout << endl;

	system("cls");
	
	
}

// End computer game

// Checks current letter chosen by user

void lchosen(char letter, string& letterchosen, int& check, int& chosencounter, int i)
{
	check = 0;
	
	// Check if letter is equal to any letter in letterchosen string loop

	for (i = 0; i < letterchosen.length(); i++)
	{
		if (letter == letterchosen.at(i))
		{
			check = 1;
		}
	}

	// End loop
	
	// Test if letter is already chosen

	if (check == 1)
	{
		cout << endl;
		cout << "Letter already chosen" << endl;
		system("pause");
	}

	// Puts letter in string if not chosen

	else
	{
		letterchosen.replace(chosencounter, 1, 1, letter);
		chosencounter++;
	}
	
}

// End lchosen function

// Tests whether letter is in word string

void test(string word, char letter, int& numwrong, string& temp, int i)
{
	int check2 = 0;		// Checks whether letter is in word string, = 1 if it is
	
	// Check for letter match loop

	for (i = 0; i < word.length(); i++)
	{
		if (letter == word.at(i))
		{
			temp.replace(i, 1, 1, letter);
			check2 = 1;
		}
	}

	// End loop

	// Displays "wrong letter" if user inputed bad letter

	if (check2 == 0)
	{
		cout << endl;
		cout << "Wrong letter" << endl;
		system("pause");
		numwrong++;
		
	}
}

// End test function

// Gets random word

void rnd(string& word, int i)
{
	
	int x;					// Random number to pass to word file loop
	ifstream ins;			// File stream
	
	srand(time(NULL));		// Gets better random number based on time
	x = rand()%100;			// Gets number 0 - 99 
	ins.open("words.txt");	// Opens random word file

	// Tests for bad file and gets word if not a bad file

	if (ins.fail())
	{
		cerr << "Words.txt is not in same folder as hangman.exe, " << endl
			<< "put in correct file and run again and make sure it's " << endl
			<< "called words.txt" << endl;
		system("pause");

		main();
	}
	else
	{
		for (i = 0; i < (x + 1); i++)
		{
			getline(ins, word);
		}
		
	}

	// End test

	ins.close();		// Close file
}

// End random function

// This will Draw the gallows according to the state
void DrawGallows(int State)
{
 if(State==6)
 {
  // The \\ will translate as '\' because it is a special char
  cout<<endl<<endl
   <<"   +----+     "<<endl
   <<"   |    |     "<<endl
   <<"   |    O     "<<endl
   <<"   |   /|\\   "<<endl
   <<"   |   / \\   "<<endl
   <<"   |Your Dead "<<endl
   <<"  ============"<<endl<<endl;
 }
 else if(State==5)
 {
  cout<<endl<<endl
   <<"   +----+  "<<endl
   <<"   |    |  "<<endl
   <<"   |    O  "<<endl
   <<"   |   /|\\ "<<endl
   <<"   |     \\ "<<endl
   <<"   |       "<<endl
   <<"  ============"<<endl<<endl;
 }
 else if(State==4)
 {
  cout<<endl<<endl
   <<"   +----+  "<<endl
   <<"   |    |  "<<endl
   <<"   |    O  "<<endl
   <<"   |   /|\\ "<<endl
   <<"   |       "<<endl
   <<"   |       "<<endl
   <<"  ============="<<endl<<endl;
 }
 else if(State==3)
 {
  cout<<endl<<endl
   <<"   +----+  "<<endl
   <<"   |    |  "<<endl
   <<"   |    O  "<<endl
   <<"   |   /|  "<<endl
   <<"   |       "<<endl
   <<"   |       "<<endl
   <<"  ============="<<endl<<endl;
 }
 else if(State==2)
 {
  cout<<endl<<endl
   <<"   +----+  "<<endl
   <<"   |    |  "<<endl
   <<"   |    O  "<<endl
   <<"   |    |  "<<endl
   <<"   |       "<<endl
   <<"   |       "<<endl
   <<"  ============="<<endl<<endl;
 }
 else if(State==1)
 {
  cout<<endl<<endl
   <<"   +----+  "<<endl
   <<"   |    |  "<<endl
   <<"   |       "<<endl
   <<"   |       "<<endl
   <<"   |       "<<endl
   <<"   |       "<<endl
   <<"  ============="<<endl<<endl;
 }

}
inline istream& Flush(istream& stream)
{
	stream.clear();
	int chars_to_skip = stream.rdbuf()->in_avail();
	return stream.ignore(chars_to_skip);
}

// End flush function

// End subprogams

// End program

my problem is I was trying to top down design this program by solving each function seperately. However, I am consfued how to link the function draw to the main function. please help me. thank you

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.