Rate How Well This Is Written

I think I have a fair understanding of the very basics of OOP.
This easy to write game is quite well organized if I do say so myself.
Everything works as intended.
The only bug I needed to fix was a memory leak.
So is it Great / Good / Bad / Terrible / or other?
/*

Written By: Smjprogrammer
With Microsoft Visual C++ 2010 Express

March 2 2014
main.cpp

*/

#include <iostream>
#include <ctime>
#include <Windows.h>
using std::cin;
using std::cout;

int *a = new int(NULL), *b = new int(NULL);// Global Allocated Identifiers.

class Easy_Game
{
public:
	void Easy_Guess_The_Number()// Public Member Function.
	{
		*b = rand() % 100 + 1;
		for (;;)
		{
			cout << "Guess a number 1 through 100: ";
			cin >> *a;
			if (cin.fail())
			{
				cin.clear();
				cin.ignore (256, '\n');
				cout << "Enter integers only.\n";
			}
			else if (*a < *b)
			{
				cout << "Too Low.\n";
			}
			else if (*a > *b)
			{
				cout << "Too High.\n";
			}
			else
			{
				cout << "You Win!\n";
				break;
			}
		}
	}
};

class Medium_Game
{
public:
	void Medium_Guess_The_Number()// Public Member Function.
	{
		*b = rand() % 500 + 1;
		for (;;)
		{
			cout << "Guess a number 1 through 500: ";
			cin >> *a;
			if (cin.fail())
			{
				cin.clear();
				cin.ignore (256, '\n');
				cout << "Enter integers only.\n";
			}
			else if (*a < *b)
			{
				cout << "Too Low.\n";
			}
			else if (*a > *b)
			{
				cout << "Too High.\n";
			}
			else
			{
				cout << "You Win!\n";
				break;
			}
		}
	}
};

class Hard_Game
{
public:
	void Hard_Guess_The_Number()// Public Member Function.
	{
		*b = rand() % 1000 + 1;
		for (;;)
		{
			cout << "Guess a number 1 through 1000: ";
			cin >> *a;
			if (cin.fail())
			{
				cin.clear();
				cin.ignore (256, '\n');
				cout << "Enter integers only.\n";
			}
			else if (*a < *b)
			{
				cout << "Too Low.\n";
			}
			else if (*a > *b)
			{
				cout << "Too High.\n";
			}
			else
			{
				cout << "You Win!\n";
				break;
			}
		}
	}
};

class Game : public Easy_Game, public Medium_Game, public Hard_Game// Multiple Inheritance.
{
public:
	Game()// Constructor.
	{
		SetConsoleTitle (TEXT ("Guess The Number Game"));// Title.
		SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), 0x0A);// Text Color.

		srand ((unsigned int) time (NULL));// Seeding the random number generator's
	}

	void Rules()// Public Member Function.
	{
		cout << "\tThe rules too guessing the number between one and whatever are the\n"
			 << "following. If the number you guess is too low the game will tell you, and you\n"
			 << "should guess a higher number. If the number you guess is too high the game\n"
			 << "will tell you, for you should guess a lower number. The game will have a list\n"
			 << "of the numbers you have guessed, so you do not have to keep track.\n";
		system ("pause & cls");
	}
};

class Guess_The_Number
{
private:
	char yes_no [15];// Private Member Identifier.
	void Difficulty_Choice()// Private Member Function.
	{
		Game play;

		play.Rules();

		cout << "Press (1 Easy / 2 Medium / 3 Hard / [Anything else to quit]): ";
		cin >> *a;
		system ("cls");

		if (*a == 1)
		{
			play.Easy_Guess_The_Number();
		}
		else if (*a == 2)
		{
			play.Medium_Guess_The_Number();
		}
		else if (*a == 3)
		{
			play.Hard_Guess_The_Number();
		}
		else 
		{
			exit (1);
		}
	}
public:
	void Menu()// Public Member Function.
	{
		for (;;)
		{
			Difficulty_Choice();
			for (;;)
			{
				cout << "Would you like to play again? (y/n): ";
				cin >> yes_no;
				if ((yes_no [0] == 'y'))
				{
					system ("cls");
					break;
				}
				else if ((yes_no [0] == 'n'))
				{
					exit (1);
				}
				else 
				{
					system ("cls");
					cout << "Input Error "; Sleep (300);
					cout << "! ";           Sleep (300);
					cout << "! ";           Sleep (300);
					cout << "! ";           Sleep (100);
					system ("cls");
				} 
			}
		}
	}
	~Guess_The_Number()// Destructor.
	{
		delete a, b;// Deallocated Identifiers.
	}
};

int main()
{
	Guess_The_Number game_play;

	game_play.Menu();
}

Feel free to ask questions.

Comments

  • Your understanding of when and how to use inheritance is all wrong. Your game class should not inherit from the 3 different classes, this just does not make any sense. If you solution requires multiple inheritance, consider a different solution (there is a reason why most modern languages don't even support it). What you have is no different then just having the three difficulty methods in the game class itself. If anything you would have a GuessNumber() in the base class, and then override that in the child classes for the different difficulties, and based on what difficulty the user selects, you create the corresponding child class (would be overkill for this, but would show some of the OOP principals). Look up polymorphism and the factory pattern.

    I think your guess the number game is just too simplistic to use as a design exercise. Really, a game this simple does not need more than 1 or 2 classes. I would consider doing something like a blackjack game, which will allow you to design classes for the player, deck, card, etc... Maybe start with this and post if you have any questions.
  • Line 17: why are a and b pointers that are allocated to contain only 1 integer? Why not just make them simple integers? And why are they global? They should be local to the class in which they are used, not global for everyone to see, which makes them very error prone.


    The three classes Easy_Game, Medium_Game, and Hard_Game can easily be just one class.
    class Game
    {
    public:
           Game(int type = 0) {game_type = type;} // default is easy game, 1 = medium, 2 = hard
    	void Guess_The_Number()// Public Member Function.
    	{
                  int max = 0;
                  switch(game_type)
                  {
                      case 0: // easy game
                          max = 100;
                          break;
                      case 1: // medium game
                          max = 500;
                          break;
                      case 2: // hard game
                          max = 1000;
                          break;
                  }
    		b = rand() % max + 1;
    		for (;;)
    		{
    			cout << "Guess a number 1 through " << max << '\n';;
    			cin >> a;
    			if (cin.fail())
    			{
    				cin.clear();
    				cin.ignore (256, '\n');
    				cout << "Enter integers only.\n";
    			}
    			else if (a > b)
    			{
    				cout << "Too Low.\n";
    			}
    			else if (a < b)
    			{
    				cout << "Too High.\n";
    			}
    			else
    			{
    				cout << "You Win!\n";
    				break;
    			}
    		}
    	}
    private:
        int game_type; // 0 = Easy, 1 = Medium, 2 = Hard
       int a,b;
    };
    
  • Yes I knew someone would mention line 17 as not being in the private section of a class, but it gave me an excuse to use the destructor. When would it be a good time to use allocation/deallocation?
  • Your destructor should be deleting it's own member variables, not global data. When you have member variables that are pointers, that is when you want to delete them in your destructor.

    Consider picking up a book, I highly recommend Accelerated C++ (was actually what my college required us to get):
    http://www.amazon.ca/Accelerated-C-Practical-Programming-Example/dp/020170353X

    This teaches C++ by example, and later in the book has a few good sections on class structure and OOP principals. If you stick with it, you would get through it in a few months, and I guarantee you will come out of it having a decent grasp on all the basics of C++ (and OOP), and have a really good base to build on.
  • I think I really and truly will get that book. It has been years since I got a programing book anyways. How many hours a day should I spend with this book?
  • It all depends on how much free time you have available to study. No one can tell you that but you. And don't forget friends and family.
  • It all depends on how much free time you have available to study. No one can tell you that but you. And don't forget friends and family.

    I mostly sit around everyday playing video games, so that said how much time should I spend learning how to make them?
  • Is writing the simple game like this better?
    #include <iostream>
    #include <ctime>
    #include <Windows.h>
    using std::cin;
    using std::cout;
    
    class Game
    {
    private:
    	int a, b, c, d;// c is for 0 = Easy, 1 = Medium, 2 = Hard
    public:
    	Game (int e = 0)// default is easy game, 1 = medium, 2 = hard
    	{
    		SetConsoleTitle (TEXT ("Guess The Number Game"));
    		SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), 0x0A);
    		srand ((unsigned int) time (NULL));
    
    		cout << "Press (0 Easy / 1 Medium / 2 Hard): ";
    		cin >> c; system ("cls");
    		e = c;
    	}
    
    	void Guess_The_Number()// Public Member Function.
    	{
    		d = 0;
    		switch (c)
    		{
    		case 0:// easy game
    			d = 100;
    			break;
    		case 1:// medium game
    			d = 500;
    			break;
    		case 2:// hard game
    			d = 1000;
    			break;
    		}
    		b = rand() % d + 1;
    		for (;;)
    		{
    			cout << "Guess a number 1 through " << d << ": ";
    			cin >> a;
    			if (cin.fail())
    			{
    				cin.clear();
    				cin.ignore (256, '\n');
    				cout << "Enter integers only.\n";
    			}
    			else if (a < b)
    			{
    				cout << "Too Low.\n";
    			}
    			else if (a > b)
    			{
    				cout << "Too High.\n";
    			}
    			else
    			{
    				cout << "You Win!\n";
    				break;
    			}
    		}
    	}
    };
    
    class Start
    {
    private:
    	char yes_no [15];
    public:
    	void Menu()// Public Member Function.
    	{
    		for (;;)
    		{
    			Game play;
    			play.Guess_The_Number();// The Game. 
    			for (;;)
    			{
    				cout << "Would you like to play again? (y/n): ";
    				cin >> yes_no;
    				if ((yes_no [0] == 'y'))
    				{
    					system ("cls");
    					break;
    				}
    				else if ((yes_no [0] == 'n'))
    				{
    					exit (1);
    				}
    				else 
    				{
    					system ("cls");
    					cout << "Input Error "; Sleep (300);
    					cout << "! ";           Sleep (300);
    					cout << "! ";           Sleep (300);
    					cout << "! ";           Sleep (100);
    					system ("cls");
    				} 
    			}
    		}
    	}
    };
    
    int main()
    {
    	Start menu;
    
    	menu.Menu();
    }
    
  • I mostly sit around everyday playing video games, so that said how much time should I spend learning how to make them?
    A few hours a night. If you get get on a good schedule and stick with it the more you will get out of it.

    I try to read through a chapter one night, and then do the questions and code samples the following night, then move onto the next chapter... and repeat. If a chapter is hard, or takes a few extra days to wrap your brain around it that is fine. Ensure you actually do the examples and questions, or nothing will actually sync in.
  • I mostly sit around everyday playing video games, so that said how much time should I spend learning how to make them?

    Yes, I agree with King, doing all the problems at the end of the chapters is very important for self-learning. Don't try to rush it, if you don't understand what you just read then read it again.
  • Ok then I will spend all the time I can on the problems at the end of the chapters. I did order the book. Should I skip over anything I know I have done before in other books? Such as the Hello, World! program I feel like I have been past that for a while. Also any thoughts on the second piece of code I posted would be nice.
  • I am having a hard time getting something to work as it did in the original code. When you are playing the game and want to press anything to exit as described on #18 it still thinks I am playing a game.
    #include <iostream>
    #include <ctime>
    #include <Windows.h>
    using std::cin;
    using std::cout;
    
    class Game
    {
    private:
    	int a, b, c, d;// c is for 0 = Easy, 1 = Medium, 2 = Hard
    public:
    	Game (int e = 0)// default is easy game, 1 = medium, 2 = hard
    	{
    		SetConsoleTitle (TEXT ("Guess The Number Game"));
    		SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), 0x0A);
    		srand ((unsigned int) time (NULL));
    
    		cout << "Press (0 Easy / 1 Medium / 2 Hard / [Anything else to quit]): ";
    		cin >> c; system ("cls");
    		e = c;
    	}
    
    	void Guess_The_Number()// Public Member Function.
    	{
    		d = 0;
    		switch (c)
    		{
    		case 0:// easy game
    			d = 100;
    			break;
    		case 1:// medium game
    			d = 500;
    			break;
    		case 2:// hard game
    			d = 1000;
    			break;
    		default:
    			exit (1);
    			break;
    		}
    		b = rand() % d + 1;
    		for (;;)
    		{
    			cout << "Guess a number 1 through " << d << ": ";
    			cin >> a;
    			if (cin.fail())
    			{
    				cin.clear();
    				cin.ignore (256, '\n');
    				cout << "Enter integers only.\n";
    			}
    			else if (a < b)
    			{
    				cout << "Too Low.\n";
    			}
    			else if (a > b)
    			{
    				cout << "Too High.\n";
    			}
    			else
    			{
    				cout << "You Win!\n";
    				break;
    			}
    		}
    	}
    };
    
    class Start
    {
    private:
    	char yes_no [15];
    public:
    	void Menu()// Public Member Function.
    	{
    		for (;;)
    		{
    			Game play;
    			play.Guess_The_Number();// The Game. 
    			for (;;)
    			{
    				cout << "Would you like to play again? (y/n): ";
    				cin >> yes_no;
    				if ((yes_no [0] == 'y'))
    				{
    					system ("cls");
    					break;
    				}
    				else if ((yes_no [0] == 'n'))
    				{
    					exit (1);
    				}
    				else 
    				{
    					system ("cls");
    					cout << "Input Error "; Sleep (300);
    					cout << "! ";           Sleep (300);
    					cout << "! ";           Sleep (300);
    					cout << "! ";           Sleep (100);
    					system ("cls");
    				} 
    			}
    		}
    	}
    };
    
    int main()
    {
    	Start menu;
    
    	menu.Menu();
    }
    
  • line 18 is in Game class, and you only instantiated an object of Start class on line 109, so line 18 never gets executed. Why is there a Start class anyway? Why not just put the menu method inside Game?
  • I am still having the same problem only with an added one. When you are playing the game you have to press the difficulty twice to get it to register.
    #include <iostream>
    #include <ctime>
    #include <Windows.h>
    using std::cin;
    using std::cout;
    
    class Game
    {
    private:
    	char yes_no [15];
    	int a, b, c, d;// c is for 0 = Easy, 1 = Medium, 2 = Hard
    public:
    	Game (int e = 0)
    	{
    		SetConsoleTitle (TEXT ("Guess The Number Game"));
    		SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), 0x0A);
    		srand ((unsigned int) time (NULL));
    
    		cout << "Press (0 Easy / 1 Medium / 2 Hard / [Anything else to quit]): ";
    		cin >> c; system ("cls");
    		e = c;
    	}
    
    	void Guess_The_Number()// Public Member Function.
    	{
    		d = 0;
    		switch (c)
    		{
    		case 0:// easy game
    			d = 100;
    			break;
    		case 1:// medium game
    			d = 500;
    			break;
    		case 2:// hard game
    			d = 1000;
    			break;
    		default:
    			exit (1);
    			break;
    		}
    		b = rand() % d + 1;
    		for (;;)
    		{
    			cout << "Guess a number 1 through " << d << ": ";
    			cin >> a;
    			if (cin.fail())
    			{
    				cin.clear();
    				cin.ignore (256, '\n');
    				cout << "Enter integers only.\n";
    			}
    			else if (a < b)
    			{
    				cout << "Too Low.\n";
    			}
    			else if (a > b)
    			{
    				cout << "Too High.\n";
    			}
    			else
    			{
    				cout << "You Win!\n";
    				break;
    			}
    		}
    	}
    
    	void Menu()// Public Member Function.
    	{
    		for (;;)
    		{
    			Game play;
    			play.Guess_The_Number();// The Game. 
    			for (;;)
    			{
    				cout << "Would you like to play again? (y/n): ";
    				cin >> yes_no;
    				if ((yes_no [0] == 'y'))
    				{
    					system ("cls");
    					break;
    				}
    				else if ((yes_no [0] == 'n'))
    				{
    					exit (1);
    				}
    				else 
    				{
    					system ("cls");
    					cout << "Input Error "; Sleep (300);
    					cout << "! ";           Sleep (300);
    					cout << "! ";           Sleep (300);
    					cout << "! ";           Sleep (100);
    					system ("cls");
    				} 
    			}
    		}
    	}
    };
    
    int main()
    {
    	Game play;
    
    	play.Menu();
    	play.Guess_The_Number();
    }// main.cpp
    
  • delete line 73. and line 74 should be just [icode]Guess_The_Number();[/icode]
  • Ok got it keeps things nice and dry. Only issue with that would be what if the player wants to change the difficulty after a game, or should they just start the whole thing over again? Which would make things easy for the programmer. :)
  • If you want to allow someone to change the difficulty without quiting and restarting the game then move lines 19, 20 and 21 into a function of their own so that the function can be called from anywhere, such as in the menu()
  • Should I skip over anything I know I have done before in other books? Such as the Hello, World! program I feel like I have been past that for a while.

    Don't skip anything. Do it front to back, each chapter builds on the last. Reinforcing what you already know is not a bad thing.
  • It works but I did not put it in a function is that ok, and also I took out the d = 0; line above the switch structure. I feel like it was not doing anything anymore.
    #include <iostream>
    #include <ctime>
    #include <Windows.h>
    using std::cin;
    using std::cout;
    
    class Game
    {
    private:
    	char yes_no [15];
    	int a, b, c, d;// c is for 0 = Easy, 1 = Medium, 2 = Hard
    public:
    	Game (int e = 0)
    	{
    		SetConsoleTitle (TEXT ("Guess The Number Game"));
    		SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), 0x0A);
    		srand ((unsigned int) time (NULL));
    	}
    
    	void Guess_The_Number()// Public Member Function.
    	{
    		switch (c)
    		{
    		case 0:// easy game
    			d = 100;
    			break;
    		case 1:// medium game
    			d = 500;
    			break;
    		case 2:// hard game
    			d = 1000;
    			break;
    		default:
    			exit (1);
    			break;
    		}
    		b = rand() % d + 1;
    		for (;;)
    		{
    			cout << "Guess a number 1 through " << d << ": ";
    			cin >> a;
    			if (cin.fail())
    			{
    				cin.clear();
    				cin.ignore (256, '\n');
    				cout << "Enter integers only.\n";
    			}
    			else if (a < b)
    			{
    				cout << "Too Low.\n";
    			}
    			else if (a > b)
    			{
    				cout << "Too High.\n";
    			}
    			else
    			{
    				cout << "You Win!\n";
    				break;
    			}
    		}
    	}
    
    	void Menu()// Public Member Function.
    	{
    		for (;;)
    		{
    			cout << "Press (0 Easy / 1 Medium / 2 Hard / [Anything else to quit]): ";
    			cin >> c; 
    			system ("cls");
    
    			Guess_The_Number();// The Game. 
    			for (;;)
    			{
    				cout << "Would you like to play again? (y/n): ";
    				cin >> yes_no;
    				if ((yes_no [0] == 'y'))
    				{
    					system ("cls");
    					break;
    				}
    				else if ((yes_no [0] == 'n'))
    				{
    					exit (1);
    				}
    				else 
    				{
    					system ("cls");
    					cout << "Input Error "; Sleep (300);
    					cout << "! ";           Sleep (300);
    					cout << "! ";           Sleep (300);
    					cout << "! ";           Sleep (100);
    					system ("cls");
    				} 
    			}
    		}
    	}
    };
    
    int main()
    {
    	Game play;
    
    	play.Menu();
    	play.Guess_The_Number();
    }// main.cpp
    
  • Yes, I agree with King, doing all the problems at the end of the chapters is very important for self-learning. Don't try to rush it, if you don't understand what you just read then read it again.

    Too say I do not understand what I am being asked to do in some of these exercises would be somewhat of an understatement. If I am having a hard time this early on what on earth am I going to do later on in the book? :S

    I got this Accelerated C++ book on Friday, and it was pretty easy until the second chapter. Which is actually the third because the book starts at chapter 0 as a sort of hat tilt to C++'s indexing with integers.
  • If I may be so blunt: Are you sure programming is what you want to do? You've been at PF.org for a good 4 years, and most of the questions I've seen from you demonstrate a certain lack of self-sufficiency that is vital in programming. Asking for help is absolutely fine, but you often neglect the virtually infinite amount of free resources available to you via a 10-second Google search. I promise there's a ton of new C++ programmers who have asked questions you have asked or will ask.

    C++ is a beast of a language, and I'd never recommend it to a novice. My opinion is that you should start over and learn the fundamentals from a different language. C is extremely compact and teaches good lessons about how computers work, but it's probably not a good suggestion in this case.

    I'd probably go with Python: It's easy to pick up, very expressive, and very powerful. Python also has classes, so OO is covered as well. I'm sure it's a lot easier to find a comprehensive beginner's tutorial that uses Python rather than one with C++; the latter will just get convoluted too quickly. C and C++ assume a fair bit of knowledge about computers, the compilation process, memory, and more, which is very hard to juggle when you still haven't grasped the fundamentals yet.
  • Too say I do not understand what I am being asked to do in some of these exercises would be somewhat of an understatement. If I am having a hard time this early on what on earth am I going to do later on in the book?

    Post the question and ask someone to explain it to you.
  • Well here is the exercise they want me to do.

    2-4. The framing program writes the mostly blank lines that separate the borders from the greeting one character at a time. Change the program so that it writes all the spaces needed in a single output expression.
  • Would you like me to post the code with the exercise, or should somebody reword the question?
  • The previous program probably displays each character one at a time in a loop. They want you to change it to first generate a string that holds the characters then display that array with a single cout statement.

    There are several ways to do that. With sprintf() you can build the string all in a single statement instead of a loop.
    char spaces[255];
    sprintf(spaces,"%*s", 10," ");
    

    In the above, sprintf() is used to create a string with length 10 (the 10 is substituted for the asterisk). You can just as easily substitute a variable for the hard-coded 10
    char spaces[255];
    int length = 10;
    sprintf(spaces,"%*s", length," ");
    

    The std::string way of doing it would be
    std::string line;
    line.insert(0,10,' ');
    
    That inserts 10 copies of the space character into the string starting at position 0.
  • Are you telling me they just want this program below.
    #include <iostream>
    #include <string>
    using std::cin;
    using std::cout;
    using std::string;
    
    
    /*
    
    The framing program writes the mostly blank lines that separate the
    borders from the greeting one character at a time. Change the program
    so that it writes all the spaces needed in a single output expression.
    
    */
    
    int main()
    {
    	int pad;
    	string a, b;
    
    	cout << "Enter users first and last name, and then press enter: ";// Ask for the person's name.
    	cin >> a >> b;// Read the name.
    
    	cout << "Enter how many spaces you need in your greeting: ";// Ask for spaces.
    	cin >> pad;// Read the spaces.
    
    	const string greeting = "Hello, " + a + " " + b + "!";// Build the message that we intend to write.
    	const int rows = pad * 2 + 3;// The number of rows and colums to write.
    	const string::size_type cols = greeting.size() + pad * 2 + 2;
    
    	cout << '\n';// Write a blank line to separate the output for the input;
    
    	// Write rows Rows of output.
    	// Invariant: we have written r rows so far.
    	for (int r = 0; r != rows; ++r)
    	{
    		string::size_type d = 0;
    
    		while (d != cols)// Invariant: we have written c characters so far in the current row. 
    		{
    			if ((r == pad + 1) && (d == pad + 1))// Is it time to write the greeting?
    			{
    				cout << greeting;
    				d += greeting.size();
    			}
    			else
    			{
    				if ((r == 0) || (r == rows - 1) || (d == 0) || (d == cols - 1))// Are we on the border?
    				{
    					cout << "*";
    				}
    				else
    				{
    					cout << " ";
    				}
    				++d;
    			}
    		}
    		cout << '\n';
    	}
    }// main.cpp
    

    Turned into this.
    #include <iostream>
    #include <string>
    using std::cin;
    using std::cout;
    using std::string;
    
    int main()
    {
    	string a, b;
    	cout << "Enter user first and last name, and then press enter: ";
    	cin >> a >> b;
    
    	cout << "Hello " << a << " " << b << ".\n";
    }
    
  • No -- change lines 35-60 and remove the while loop.
  • All I got was a big empty space. Is that what they are looking for?
  • Almost -- you have to print the greeting inside that rectangle
  • Is that not what is already happening?
Sign In or Register to comment.