variable being used without being initialized

Hey, newbie here.

I'm trying (unsuccessfully) to write a rock, paper, scissors, lizard, spock game.
So far it keeps coming up:
'Run-Time Check Failure #3 - The variable 'userchoice' is being used without being initialized."
Where is this error taking place and how do I initialized an input variable that is being used with a pseudo number generator?

Can anyone see what I'm doing wrong?

int main()
{
char userchoice;

cout<<"Would you like to play a game?"<<endl; // introducing the game

cout <<"Choose (r)rock, (p)paper, (sc)scissors, (l)lizard, or (sp)spock:"<< userchoice << endl; //user options
cin>> userchoice;


cout<<"The computer choices:";
srand((unsigned) time(0));


int computerchoice;

computerchoice = (rand() % 5) + 1; // random variable and range
cout << fixed <<setprecision(1)<<computerchoice<<endl;

if(computerchoice ==1) // 1 is equal to rock

{
if(userchoice == 'r')
{
cout<<"Rock"<< endl;
cout<<"Tie game"<<endl;
}

else if (userchoice == 'l')
{
cout<<"Rock"<< endl;
cout <<"Rock crushes Lizard. You lose."<< endl;
}

else if (userchoice == 'sc')
{
cout<<"Rock"<< endl;
cout<<"Rock crushes sissors. You lose."<< endl;
}

else if (userchoice == 'p')
{
cout<<"Rock"<< endl;
cout<< "Paper covers rock. You win"<<endl;
}

else if (userchoice == 'sp')
{
cout<<"Rock"<< endl;
cout<<"Spock vaporizes rock. You win"<<endl;
}
}
// ending rock if statements

else if(computerchoice == 2) // 2 is equal to scissors

{

if (userchoice == 'sc')
{
cout<<"Scissors"<< endl;
cout<<"Tie game"<<endl;
}

else if (userchoice == 'l')
{
cout<<"Scissors"<< endl;
cout <<"Scissors cuts the head off of Lizard. You lose."<< endl;
}

else if(userchoice == 'r')
{
cout<<"Scissors"<< endl;
cout<<"Rock crushed scissors. You win."<< endl;
}

else if(userchoice =='p')
{
cout<<"Scissors"<< endl;
cout<< "Scissors cut paper. You lose"<<endl;
}

else if(userchoice == 'sp')
{
cout<<"Scissors"<< endl;
cout <<"Spock crushes scissors. You win"<<endl;
}
} //ending scissor if statments


else if(computerchoice == 3) // 3 is equal to Paper
{
if (userchoice == 'p')
{
cout<<"Paper"<< endl;
cout<<"Tie game"<<endl;
}

else if(userchoice == 'l')
{
cout<<"Paper"<< endl;
cout <<"Lizard eats paper. You win."<< endl;
}

else if(userchoice == 'r')
{
cout<<"Paper"<< endl;
cout<<"Rock crushed Paper. You lose."<< endl;
}

else if(userchoice == 'sc')
{
cout<<"Paper"<< endl;
cout<< "Scissors cut paper. You win"<<endl;
}

else if (userchoice == 'sp')
{
cout<<"Paper"<< endl;
cout <<"Paper disproves Spock. You lose"<<endl;
}
} //ending paper if statements

else if(computerchoice == 4) // 4 is equal to Lizard
{
if (userchoice == 'l')
{
cout<<"Lizard"<< endl;
cout<<"Tie game"<<endl;
}
else if (userchoice == 'p')
{
cout<<"Lizard"<< endl;
cout <<"Lizard eats paper. You lose."<< endl;
}
else if (userchoice == 'r')
{
cout<<"Lizard"<< endl;
cout<<"Rock crushed Lizard. You win."<< endl;
}
else if (userchoice == 'sc')
{
cout<<"Lizard"<< endl;
cout<< "Scissors cut Lizard. You win"<<endl;
}
else if (userchoice == 'sp')
{
cout<<"Lizard"<< endl;
cout <<"Lizard poisons Spock. You lose"<<endl;
}
} //ending Lizard if statements
else if(computerchoice == 5) // 5 is equal to Spock
{
if (userchoice == 'sp')
{
cout<<"Spock"<< endl;
cout<<"Tie game"<<endl;
}
else if (userchoice == 'p')
{
cout<<"Spock"<< endl;
cout <<"Paper disproves Spock. You win."<< endl;
}
else if (userchoice == 'r')
{
cout<<"Spock"<< endl;
cout<<"Spock vaporizes rock. You lose."<< endl;
}
else if (userchoice == 'sc')
{
cout<<"Spock"<< endl;
cout<< "Spock smashes scissors. You lose"<<endl;
}
else if (userchoice == 'l')
{
cout<<"Spock"<< endl;
cout <<"Lizard poisons Spock. You win"<<endl;
}
} //ending Spock if statements

else // if the user did not enter a valid choice
{
cout<<"You did not choose a valid choice"<<endl;
}


system ("pause");
return 0;
}
closed account (zb0S216C)
As the error points out, you need to initialize userchoice( at the top of the main entry-point ) before using it. For example:

1
2
3
4
5
6
int main( )
{
    char userchoice( '\0' );

    // Then the rest of your code...
}

Wazzak
Last edited on
Wow, that was fast. Thank you.

By initializing a char variable ('\0'), will that work with every undefined user input?

Also, I'm having problems when I test the variable options. Mainly sc and sp. The program is not acknowledging them as inputs.
closed account (zb0S216C)
With userchoice being of type char, it can only hold a single character. In order for it to hold multiple characters, consider using string[1], or char *.

References:
[1]http://www.cplusplus.com/reference/string/string/


Wazzak
Hello Cutegun,

I am a student at UAT, and I am current taking a C++ class. I was browsing the forums and I took an interest in your post. I like your game and would like to offer a suggestion to improve it: the ability to play multiple times. I also took Frameworks advise and changed the userchoice variable to a string.

At the top of your code you should replace:
1
2
3
char userchoice;

cout<<"Would you like to play a game?"<<endl; // introducing the game 

with this:
1
2
3
4
5
6
7
8
9
10
11
12
string userchoice;
int games(0);
int wins(0);
int losses(0);
int ties(0);
int computerchoice(0);

cout<<"How many games would you like to play?"<<endl; // introducing the game
cin >> games;

while (games > 0)
{


NOTE: I also moved the computerchoice variable to the top of the code.

You need to add this to the bottom:
1
2
3
4
5
6
games--;
}

cout << "\nGames Won: " << wins;
cout << "\nGames Lost: " << losses;
cout << "\nGames Tied: " << ties << endl;


In between this:
1
2
3
4
else // if the user did not enter a valid choice
{
cout<<"You did not choose a valid choice"<<endl;
}


And this:
 
system ("pause");


And finally you will have to add:
wins++; losses++; ties++;
in each appropriate if or if else statement.

I hope this helps you out. I had fun adding it in.
closed account (zb0S216C)
DJennings, please don't encourage the use of system( ). It's a security risk, and it relies on the Windows operating system, thus rendering the program platform dependent. You can make your own pause method, which may look like this:

1
2
3
4
5
void PauseConsole( void )
{
    std::cout << "Press any key to continue..." << std::endl;
    std::cin.get( );
}

Wazzak
Last edited on
I only left in the system() command that was in Cutegun's code. Honestly, I did not know that the use of that command was platform dependent. Thanks you for the info, I can use all the pointers I can get.
what you have listed is a C-like implementation (with the exception of iostream), which is fine, but when you are ready to learn more C++, take a look at the implementation below and refactor as much as you like:

disadvantages
- more complex than the C code/harder to understand, initially
- no error checking (I was lazy)
- looks like it's over-engineered

advantages
- when adding new choices, fix in 5 spots, as noted in the comments
- some separation of code vs the engine
- easier to maintain (data driven)
- encapsulation is not too bad
- methods are simple and easy to understand
- you can learn about STL, classes, operators, etc...

please refactor as much as you like - have fun!

One interesting note: I thought I would pump this code out in 10 minutes, but surprisingly, the strict less-than ordering of STL map killed me for a while (simplified on Lines 86-88) - when you use standard objects (like std::string) or plain-old-data (int) as the key, you don't have to worry about it, but once you use your own class, like Combination here, you have to define operator<() very carefully - otherwise, STL map will behave very badly.

Unfortunately, this experience is not unlike many experiences in C++ - I think I will pump out code quickly and then a small implementation detail has to be done correctly, or the project is a fail - that small part takes much longer than the rest.

Programmers who are experienced at C++ will likely look at this code and feel that it's not hard to understand at all. However, other programmers (like L. Torvalds or Pike/Thompson of Go/UNIX fame) will look at this code and say this is why we should use simpler languages!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include <stdlib.h>

#include <sstream>
#include <iostream>
#include <map>
#include <string>

using namespace std;

// NOTE: need to add entry/entries in FIVE PLACES (1-5 below)
// engine -------------------------------------------------------------- 
enum eCHOICE { kROCK=0, kPAPER, kSCISSORS, kLIZARD, kSPOCK, kMAX };  // 1. add entry
static char charChoices[] = { 'r', 'p', 'X', 'l', 'K' };             // 2. add entry
static const char* strChoices[] = { "Rock", "Paper", "Scissors", "Lizard", "Spock" };  // 3. add entry

class Choice
{
  public:
    Choice( eCHOICE choice ) : m_choice( choice ) { }
    Choice( char choice ) {
      switch( choice ) {
        case 'r': m_choice = kROCK;     break;                       // 4. add entry
        case 'p': m_choice = kPAPER;    break;
        case 'X': m_choice = kSCISSORS; break;
        case 'l': m_choice = kLIZARD;   break;
        case 'K': m_choice = kSPOCK;    break;
      }
    }
      
    static void GetMenu( string& menu ) {
      ostringstream oss;
      oss << "Choose ";
      for ( unsigned i=kROCK; i<kMAX; ++i )
        oss << "(" << charChoices[i] << ")" << strChoices[i] << " ";
      oss << ": ";
      menu = oss.str();
    }

     Choice& operator=( const Choice& rhs ) {
      if ( this==&rhs ) return *this;
      m_choice = rhs.m_choice;
      return *this;
     }

    int intval() const {
      return static_cast<int>( m_choice );
    }

    bool operator==( const Choice& rhs ) const { return m_choice==rhs.m_choice; }

    friend ostream& operator<<( ostream& os, const Choice& rhs ) {
      os << strChoices[ rhs.intval() ];
      return os;
    }

  private:
    eCHOICE m_choice;  
};

struct Combination {
  Combination( const Choice& playerChoice, const Choice& computerChoice ) :
    m_player( playerChoice ), m_computer( computerChoice ) { }

  Combination( const Combination& rhs ) :
    m_player( rhs.m_player ), m_computer( rhs.m_computer ) { }

  Combination reverse() const {
    return Combination( m_computer, m_player );
  }

  Combination& operator=( const Combination& rhs ) {
    if ( this==&rhs ) return *this;
    m_player   = rhs.m_player;
    m_computer = rhs.m_computer;
    return *this;
  }

  int intval() const {
    return m_player.intval() * kMAX + m_computer.intval();
  }

  bool isTied() const {
    return m_player==m_computer;
  }

  bool operator<( const Combination& rhs ) const {
    return intval() < rhs.intval();
  }

  friend ostream& operator<<( ostream& os, const Combination& rhs ) {
    os << "Player="   << rhs.m_player << ", ";
    os << "Computer=" << rhs.m_computer;
    return os;
  }

  Choice m_player, m_computer;
}; 

class Judge {
  public:
    Judge() {
      // 5. add entries in ONE DIRECTION ONLY with Combination( winner, loser ) and proper comments
      m_results[ Combination( kROCK,     kLIZARD )   ] = "Rock crushes Lizard.";
      m_results[ Combination( kROCK,     kSCISSORS ) ] = "Rock crushes Scissors.";
      m_results[ Combination( kPAPER,    kROCK ) ]     = "Paper covers Rock.";
      m_results[ Combination( kPAPER,    kSPOCK ) ]    = "Paper disproves Spock.";
      m_results[ Combination( kSPOCK,    kROCK ) ]     = "Spock vaporizes Rock.";
      m_results[ Combination( kSPOCK,    kSCISSORS ) ] = "Spock smashes Scissors.";
      m_results[ Combination( kSCISSORS, kLIZARD ) ]   = "Scissors cuts the head off of Lizard.";
      m_results[ Combination( kSCISSORS, kPAPER ) ]    = "Scissors cuts Paper.";
      m_results[ Combination( kLIZARD,   kPAPER ) ]    = "Lizard eats Paper.";
      m_results[ Combination( kLIZARD,   kSPOCK ) ]    = "Lizard poisons Spock.";
    }

    void getResultFor( string& result, const Combination& combo )
    {
      if ( combo.isTied() ) {
        result = "Tie game.";
      } else {
        map< Combination, string >::const_iterator it;
        if ( (it=m_results.find( combo ))!=m_results.end() ) {
          result = it->second + " You win!";
        } else if ( (it=m_results.find( combo.reverse() ))!=m_results.end() ) {
          result = it->second + " You lose!";
        } else {
          cerr << "ERROR IN PROGRAM - could not find " << combo << " or " << combo.reverse() << endl;
        }
      }
    }

  private:
    map< Combination, string > m_results;
};

// main ---------------------------------------------------------------- 
int main()
{
  string menu;
  char userchoice;

  Choice::GetMenu( menu );
  cout << menu << endl;  
  cin >> userchoice;

  srand((unsigned) time(0));
  int computerchoice = (rand() % kMAX);

  Choice userChoice(     userchoice );
  Choice computerChoice( charChoices[ computerchoice ] );

  cout << "You chose           :  " << userChoice     << endl; 
  cout << "The computer chooses:  " << computerChoice << endl;

  // -------------------------------------------------------------------
  Judge       judge;
  string      result;
  Combination combo( userChoice, computerChoice );
  judge.getResultFor( result, combo );
  cout << result << endl;;

  return 0;
}
Last edited on
Wow, thanks guys.
This is still above the level that I'm at, but it clears up a lot of question.
Topic archived. No new replies allowed.