This is a rock, paper, scissor, lizard, spock game. The computer's decision making is set up in the class and all input/output must take place in main. I am struggling with a few things: Setting up a score keeper - unsure how to keep score by comparing the output of the computer class and the user input. As you can see I have a GetScore function but I am lost as to what to put inside of it when there aren't any global variables. I would be able to do this if all the variables were global but I heard that's bad practice so I am shying away from that. Secondly, how to terminate the game when the game reaches 3, 5 or 7 rounds. Thank you for your time.

  #include <string>
    #include <iostream>
    using namespace std;

    class ComputersChoice { //Class that contains the random number function for the AI player
        private:
            int randNum;

        public:

            ComputersChoice() {
                randNum = value();
            }
            int GetChoice() {
                return randNum;
            }
            int value() {
                randNum = rand() % 5 + 1;
                return randNum;
            }

            void printResult() {
            if (randNum == 1) {
                cout <<"The computer chose rock. ";
            }

            else if (randNum == 2) {
                cout<<"The computer chose paper. ";
            }

            else if (randNum == 3) {
                cout<<"The computer chose scissors. ";
            }

            else if (randNum == 4) {
                cout<<"The computer chose lizard. ";
            }    

            else {
                cout<<"The computer chose spock. ";
            }    

            }       
    };

    //How many rounds does the user want to play function
    int GetRounds() {  

        bool isValid = false;
        int rounds = 0;

        while (!isValid) {

        cout<<"Do you want to play 3, 5 or 7 rounds?" << endl;
        cin>>rounds;

        switch(rounds) {
            case 3:
            case 5: 
            case 7:
               isValid = true;
               break;
            default:
                cout<<"Invalid input. Enter 3, 5 or 7."<<endl;
                break;

    }

    }

        cout<<"You picked the best of " << rounds << " rounds." << endl;
            return rounds;

    }    

    //User input
    int GetUser() {

    int user_choice = 0;

    bool isValid = false;

    while (!isValid) {

    cout<<"Enter 1 for rock, 2 for paper, 3 for scissors, 4 for lizard, 5 for spock." << endl;
    cin>>user_choice;

    switch(user_choice) {
        case 1:
            isValid = true;
            cout<<"You chose rock. ";
            break;
        case 2: 
            isValid = true;
            cout<<"You chose paper. ";
            break;
        case 3:
            isValid = true;
            cout<<"You chose scissors. ";
            break;
           break;
        case 4:
            isValid = true;
            cout<<"You chose lizard. ";
            break;
        case 5:
            isValid = true;
            cout<<"You chose spock. ";
            break;
        default:
            cout<<"Invalid input."<<endl;
            break;
}
}
}

    int GetScore() {
        int compScore = 0;
        int humanScore = 0;

    }

    int main() {
        GetRounds();

        for (int i = 1; i <= 7; i++) {
        ComputersChoice A;
        srand(time(NULL));
        GetUser();
        A.printResult();

        cout<<"This was round " << i << "." << " On to round " << i + 1 << "." << endl;

    }

    }

Dani AI

Generated

A compact, practical plan that fixes the score, loop and comparison issues in 's code (and follows 's advice to break the problem into smaller pieces):

Keep the two score counters local to main (e.g. humanScore and compScore) and compute the number of wins needed as needToWin = rounds/2 + 1 (best-of-3 -> 2, best-of-5 -> 3, best-of-7 -> 4). Seed the RNG once at program start (before any ComputersChoice is created) and let main handle all printing. Make GetUser() return the user's choice and remove any I/O from the ComputersChoice class so the class only produces/returns the numeric choice.

A simple, robust compare function and loop pattern:

enum Choice { ROCK=1, PAPER, SCISSORS, LIZARD, SPOCK };

int CompareChoices(int human, int comp) {
    if (human == comp) return 0; // tie
    switch (human) {
        case ROCK:     return (comp==SCISSORS || comp==LIZARD) ? 1 : -1;
        case PAPER:    return (comp==ROCK || comp==SPOCK)     ? 1 : -1;
        case SCISSORS: return (comp==PAPER || comp==LIZARD)   ? 1 : -1;
        case LIZARD:   return (comp==SPOCK || comp==PAPER)    ? 1 : -1;
        case SPOCK:    return (comp==SCISSORS || comp==ROCK)  ? 1 : -1;
    }
    return -1;
}

int rounds = GetRounds();
int needToWin = rounds/2 + 1;
int humanScore = 0, compScore = 0, round = 0;
srand(time(NULL)); // once, at start

while (humanScore < needToWin && compScore < needToWin && ++round <= rounds) {
    int human = GetUser();         // must return a value
    ComputersChoice comp;          // RNG already seeded
    int c = comp.GetChoice();
    // main prints choices and result
    int r = CompareChoices(human, c);
    if (r == 1) ++humanScore;
    else if (r == -1) ++compScore;
}

Notes and troubleshooting:

  • GetUser() in the posted code lacks a return; that must be fixed. GetScore() as written is unnecessary if main tracks scores.
  • Seed once (calling srand(time(NULL)) inside the loop causes repeated identical seeds and bad randomness). Either seed before using ComputersChoice, or change the class so it does not generate in the constructor.
  • Decide whether ties consume a round; if ties should not count, don't increment round on a tie.
  • For more predictable RNG and testability, consider C++11 <random> (std::mt19937 + std::uniform_int_distribution) instead of rand().

Recommended Answers

All 3 Replies

The way that he did it, I would be able to do it that way too. What's catching me off guard is the computer class and the user input function and catching the information from them to create a score function as well as a function that compares user input to the computers'.

When you can't crack the problem, you break the problem down to smaller pieces.

Catching the information from the user is not something I worry about when I need a score function. Same be told about comparing choices.
Work each area at a time.

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.