Hello. I have been out of programming in C++ for about a year now (around the time I took my last C++ class) and I am wanting to get back into it. So I decided to make a rock, paper, scissors game to refresh my memory but I am running into some problems on finalizing my program.

int main()
{
	bool quit = false;
	
	displayMenu();

	while (quit != true)
	{

		int userInput = 0;
		string userResult = "";
	
		cout << "Press 1 for Rock, 2 for Paper, 3 for Scissors, or '0' to quit: ";

		cin >> userInput;

		if (userInput == 0)
		{
			quit = true;
			break;
		}

		if (userInput == 1 | userInput == 2 | userInput == 3)
		{
		userResult = userSelection(userInput);
		compareChoice(userResult);
		}

		else
		{
			cout << endl;
			cout << "Please enter 1, 2, 3, or '0' to quit." << endl;
			cout << endl;
		}

	}

	return 0;
}

Above is my first problem. I want to make sure the user only inputs numbers 1, 2, 3, or 0. How do I go about detecting when the user enters anything but these numbers? I have tried functions (isdigit()) as well as using Try/Catch.

My second problem is that the game's logic is not working properly. For the first few choices, it will determine who wins correctly but after a few rounds, it starts giving incorrect logic (i.e. Rock beats Paper). I know Im not suppose to submit a lot of code but I think the only way for someone to understand my problem is by posting the rest of the code:

#include <iostream>
#include <string>
#include <ctime>
#include <cmath>
#include <windows.h>

using namespace std;

void displayMenu()
{
	cout << "\t\tWelcome to my Rock, Paper, Scissors Game!\n" << endl;
}

string computerSelection()
{
	int randomNum = 0;
	string computerChoice = "";

	srand((unsigned)time(0)); 
	randomNum = (rand() % 3) + 1;

	if (randomNum ==1)
	{
		computerChoice = "Rock.";
	}

	else if (randomNum == 2)
	{
		computerChoice = "Paper.";
	}
	else
	{
		computerChoice = "Scissors.";
	}
	
	return computerChoice;
}
string userSelection (int userInput)
{
	string userChoice = "";

	cout << endl;
	if (userInput == 1)
	{
		userChoice = "Rock.";
		cout << "You're Choice: " << userChoice << endl;
		Sleep(1000);
		cout << endl;
		cout << "Computer's Choice: " << computerSelection() << endl;
		Sleep(1000);
	}

	else if (userInput == 2)
	{
		userChoice = "Paper.";
		cout << "You're Choice: " << userChoice << endl;
		Sleep(1000);
		cout << endl;
		cout << "Computer's Choice: " << computerSelection() << endl;
		Sleep(1000);
		
	}

	else
	{
		userChoice = "Scissors.";
		cout << "You're Choice: " << userChoice << endl;
		Sleep(1000);
		cout << endl;
		cout << "Computer's Choice: " << computerSelection() << endl;
		Sleep(1000);
	}

	return userChoice;
}

void compareChoice(string userResult)
{
	string computerResult = "";
	computerResult = computerSelection();
	
	cout << endl;

	if (userResult == computerResult)
	{
		cout << "Tie, you both picked " << userResult;
		Sleep(1000);
	}

	else if (userResult == "Rock." & computerResult == "Scissors.")
	{
		cout << "Congrats! You Win!";
		Sleep(1000);
	}
	else if (userResult == "Paper." & computerResult == "Rock.")
	{
		cout << "Congrats! You Win!";
		Sleep(1000);
	}
	else if (userResult == "Scissors." & computerResult == "Paper.")
	{
		cout << "Congrats! You Win!";
		Sleep(1000);
	}

	else
	{
		cout << "Sorry, you lose!";
		Sleep(1000);
	}

	cout << "\n\n";
}

Any help, suggestions, and comments are greatly appreciated.

isdigit(char) returns a boolean value indicating whether the argument recieved was numeric or else.You must include <cctype> in order to use this function.

How do I go about detecting when the user enters anything but these numbers?

There are a number of ways, but none of them are the one-liner that everybody wants. ;) However, the pattern for managing input and covering the cases for each option is fairly straightforward and consistent:

#include <cstdlib>
#include <iomanip>
#include <ios>
#include <iostream>
#include <limits>

using namespace std;

void play(int player, int computer);

int main()
{
    bool done = false;
    int choice;

    while (!done) {
        // Step 1) Prompt for input
        //
        cout<< "Press 1 for Rock, 2 for Paper, 3 for Scissors, or '0' to quit: ";

        // Step 2) Try to get the requested input
        //
        if (!(cin>> choice)) {
            // Failure case: end-of-file or invalid input
            if (cin.eof())
                break;
            else {
                // Clear the error and remove any offending characters
                cin.clear();
                cin.ignore(numeric_limits<streamsize>::max(), '\n');

                // Since choice is still not set, give it an invalid option
                choice = -1;
            }
        }

        // Step 3) Process the selected option
        //
        switch (choice) {
        case 0:
            done = true;
            break;
        case 1:
        case 2:
        case 3:
            play(choice, rand() % 3 + 1);
            break;
        default:
            cerr<<"Invalid option\n";
            break;
        }
    }
}

void play(int player, int computer)
{
    const char *opt[] = { "", "rock", "paper", "scissors" };

    cout<<'\n'
        << left << setw(15) << "Player" <<"Computer\n"
        << left << setw(15) << opt[player] << opt[computer] <<'\n';
}

At a glance:

>srand((unsigned)time(0));
>randomNum = (rand() % 3) + 1;

It's generally best to call srand() once when the program starts (or wide intervals for long running programs).

>userResult == "Rock." & computerResult == "Scissors."
& is not the logical AND operator, it's the bitwise AND operator. There's subtly (or wildly) different behavior in certain cases. You probably want to change this to the logical AND operator (&&).

Narue,

Thanks for the informative post. There are a couple of header files and functions that I do not recognize but it looks like it made my code a lot more simple. I am going to do some research on those functions and try to fully understand exactly what you did.

It's generally best to call srand() once when the program starts (or wide intervals for long running programs).

What is the best practice to do so? Should srand() be called at the beginning of main() along with my variables? I notice that the numbers are not entirely random in my program and are generated in sequential order (1,2,3,1,2,3...etc).

& is not the logical AND operator, it's the bitwise AND operator. There's subtly (or wildly) different behavior in certain cases. You probably want to change this to the logical AND operator (&&).

Ah. This is probably why my logic is failing in determining who wins.

Thanks again for the reply.

Should srand() be called at the beginning of main() along with my variables?

That's the most common method, yes.

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.