Homework help - issues with the code

Hiya.

I am finishing up my intro to C++ course at college and thus far, I havent had much trouble. However, I cant seem to grasp functions well enough.

The code I am writing creates a simple guessing game with several functions and the program is supposed to loop. I am going to include the entire code because im not sure exactly where I am going wrong.

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
163
164
165
166
167
168
169
170
171
172
// A simple guessing game where the user tries to guess a random number that the program selects. Program also offers guidance for incorrect entries, non-existant configuration
// files and invalid number range.

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
using namespace std;

void displayMenu();
void playGame();
void configureGame();
void writeConfiguration();
void quitGame();
int initialize(int& num1, int& num2);

int main ()
{
    char choice;
    
    displayMenu();
    
    
if((choice!='a') && (choice!='b') && (choice!='q'))
{
cout << choice <<" is an invalid Selection! Please try again." << endl;
cin >> choice;
}

switch (choice)

{
       case 'a': playGame();
       break;
       
       case 'b': configureGame();
       break;
       
       case 'q': quitGame();
       break;
       
}
system ("pause");

return 0;	
}

int initialize(int& num1, int& num2)
{
     int num;
     
     ifstream inputfile; 
     inputfile.open("C://Temp/Config.txt");      
     
     while (inputfile.is_open())
     {
     if(inputfile.fail())
     {
     cout << "Error opening config file! Goodbye!" << endl;
     system ("pause");
     }else
     {
     inputfile >> num1;
     inputfile >> num2;
     inputfile.close();
     }
     srand(time(0));
     num=num1+rand()%num2+1;
     }
     
     return num;
     
     
};

void displayMenu()
{
    char choice; 
     
    cout << "#########################################################" << endl;
    cout << "#                    Guessing Game v1.0                 #" << endl;
    cout << "#########################################################" << endl;
    cout << " " << endl;
    cout << "Please select from the following menu options:" << endl;
	cout << "       a) Play the game" << endl;
    cout << "       b) Configure the game" << endl;
	cout << "       q) Quit the game" << endl;
	
	cin >> choice;
};	


void playGame()
{
     
     int num1=0;
     int num2=0;
     int num;

     num=initialize(num1, num2);
     int count=0, guess;
     
     cout << "I am thinking of a number between "<< num1 << " and " << num2 <<"..." << endl;
     cout << "What is your guess?" << endl;
     
     cin >> guess;
     
     
     if ((guess<num1) && (guess>=num2))
     {
                     
           cout << "Your guess is out of range. You just wasted a guess :-(" << endl;
           count++; 
           cout << "What is your guess?" << endl;
           cin >> guess;
         
     }else if (guess<num)
           {
              cout << "Higher!" << endl;
              count++;
              cout << "What is your guess?" << endl;
              cin >> guess;
           }else if (guess>num)
                 {
                      cout << "Lower!" << endl;
                      count++;
                      cout << "What is your guess?" << endl;
                      cin >> guess;
                      }else if (guess=num)
                            {
                                 cout << "Great job! You guessed correctly! It took you " << count << " attempts." << endl;
                            }
};

void configureGame()
{
     int num1, num2;
     
     cout << "Enter the range of numbers to choose from separated by a space: " << endl;
     cin >> num1, num2;
     
     if (num1>num2)
     {
         cout << "Your selection was not valid." << endl;
         cout << "Enter the range of numbers to choose from separated by a space: " << endl;
         
     }else
          {
                writeConfiguration();
           }
};

void writeConfiguration()
{               
                int num1, num2;
                
                ofstream outputFile;
                outputFile.open("C://Temp/Config.txt");
    
                outputFile << num1 << endl;
                outputFile << num2 << endl;
    
                outputFile.close();
    
                cout << "Write Complete!" << endl;
                
};
void quitGame()
{
     exit(1);
 };

Ive been working on it for about 4 days and I either must be missing something obvious or I am entirely too stressed to figure it out.

On top of that, I also have to write another version of the same program using a bool query for the loop process instead of my if statements. Both versions must perform exactly the same. I have so far been avoiding using bool because to be honest, I missed class that day and did not learn how to use it (havent used it all semester - still making an A though).

Any assistance will be greatly appreciated. If you guys need further info, let me know.

Thanks!
Last edited on
You have error here:
1
2
3
4
else if (guess=num)
                            {
                                 cout << "Great job! You guessed correctly! It took you " << count << " attempts." << endl;
                            }


it must be 'else if (guess==num)'
Hi uataneja,

taking a quick look, I saw that in displayMenu() you read a char choice from the default input stream but you don't return it, hence since char choice is local to displayMenu() it is destroyed, and the built-in int choice that you declared earlier that you then go on to use is default initialised to garbage. Hence, whatever the user entered in displayMenu() isnt being used.

Redefine displayMenu() to the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
char displayMenu()
{
    char choice; //this is local to the function
     
    cout << "#########################################################" << endl;
    cout << "#                    Guessing Game v1.0                 #" << endl;
    cout << "#########################################################" << endl;
    cout << " " << endl;
    cout << "Please select from the following menu options:" << endl;
	cout << "       a) Play the game" << endl;
    cout << "       b) Configure the game" << endl;
	cout << "       q) Quit the game" << endl;
	
	cin >> choice;

    return choice; //return copy of local variable
};	


and assign this returned type to another char choice using:

char choice = displayMenu()

This should help.
@RisteMK

Thank you for that - I completely missed it.

@dangrr888

This changed the program completely - now it wont even compile. The compiler doesnt see char displayMenu() as a function anymore even if I try to assign to another char choice (dont know why).

The reason I didnt return it is because in all of the void functions, the function is not supposed to return anything.

Is there something im missing?

Edit: I changed int choice to char choice and reflected that in the code.
Last edited on
You need change the declaration of displayMenu() to char displayMenu().

I am checking the rest of the code now ...

I had a bit of a problem with getting initialize() to read a file (did you experience this), so I changed it to the way I usually use ifstream's

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int initialize(int& num1, int& num2)
{
  int num;

  ifstream inputfile("Config.txt");
  if(!inputfile)
    throw logic_error("file not found!");

  inputfile >> num1;
  inputfile >> num2;

  num=num1+rand()%num2+1;
  cout << "num =" << num << endl;
  return num;
};


with Config.txt formatted like

//start of file
[num1 goes here] 
[num2 goes here]
//end of file


I also am getting num > num2, so I will check that out as well.
Regarding

I also am getting num > num2, so I will check that out as well.


and using the example on http://www.cplusplus.com/reference/clibrary/cstdlib/rand/

I find that the following works

num = num1 + (rand() % (num2 - num1));
also on the note of booleans, theyre very simple. they can have two values true or false
they are declared like this, and can be incredibly useful.
1
2
3
4
5
6
7
bool myBoolean = true;
myBoolean = false;

if (!myBoolean)
{
    cout << "Hello, world!";
}


as you can guess this would output Hello, world! because even though myBoolean is set to false
the ! operator means not so the statement is saying if myBoolean is not true execute the statement. for a more indepth explanation read the following:
http://www.cplusplus.com/doc/tutorial/variables/

hope this helps :)
Last edited on
I understand what you are saying about the displayMenu, however, the instructions from the professor state:

---
displayMenu This function does not return anything and does not take in any parameters. It simply prints out the main menu with the various game options. The menu should look like the following:

#########################################################
# Guessing Game v1.0 #
#########################################################

Please select from the following menu options:
a) Play the game!
b) Configure the game
q) Quit the game

>
---

So, I dont really know if im allowed to change that... I dont mean to be argumentative... I have strict guidelines to follow =(
Ok, thats fine. Just don't read choice in using displayMenu, read it in immediately afterwards:

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
// A simple guessing game where the user tries to guess a random number that the program selects. Program also offers g\
uidance for incorrect entries, non-existant configuration                                                               
// files and invalid number range.                                                                                      

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <stdexcept>

using namespace std;

void displayMenu();
void playGame();
void configureGame();
void writeConfiguration();
void quitGame();
int initialize(int& num1, int& num2);

int main ()
{
  displayMenu();

  char choice;
  cin >> choice;

...


Also, you'll want to add a do-while loop when you play the game since at the moment the program terminates after two attempts:

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
void playGame()
{

  int num1 = 0;
  int num2 = 0;
  int num = 0;

  num = initialize(num1, num2);

  int count = 1, guess;

  cout << "I am thinking of a number between "<< num1 << " and " << num2 <<"..." << endl;

  do
    {
      cout << "What is your guess?" << endl;
      cin >> guess;

      if ((guess<num1) && (guess>=num2))
        {
          cout << "Your guess is out of range. You just wasted a guess :-(" << endl;
          count++;
        }
      else if (guess<num)
        {
          cout << "Higher!" << endl;
          count++;
        }
      else if (guess>num)
        {
          cout << "Lower!" << endl;
          count++;
        }
    }
  while(guess!=num);

  if(count > 1)
    cout << "Great job! You guessed correctly! It took you " << count << " attempts." << endl;
  else
    cout << "Great job! You guessed correctly! It took you " << count << " attempt." << endl;
};


The "a" option of the game now works fine for me.

Edit: Except that you should change

if ((guess<num1) && (guess>=num2)) to

if ((guess<num1) || (guess>=num2)).
Last edited on
Okay,

I tweaked the program as you suggest and now option 'a' works - except that in the "int initialize" function, if there is no config file, it should read

cout << "Error opening config file! Goodbye!" << endl;

And then exit out.

So if you choose option a with no config file, it should read that error then exit out.
Then you reopen program, choose option B, have enter in the numbers to random between.
After writing the config file, go back to displayMenu() and run the game normally.

Is it just me, or this getting extremely complicated?

Honestly, youre being a bigger help than my classmates and the professor combined. I really do appreciate your assistance.
Last edited on
Lastly, with regards to the option (b) part of the application you have several errors:

In configureGame you should have

cin >> num1 >> num2;

rather than

cin >> num1, num2;.

You also need to pass num1 and num2 to writeConfiguration when you call it in configureGame and redefine & redeclare it to take 2 integer arguments:

void writeConfiguration(int num1, int num2)

and remove the declaration of the local variables int1, int2 since these are default initialized and you will find that regardless of what values you enter, you will end up with two zeros in Config.txt.

So it looks something like this:

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
void configureGame()
{
  int num1, num2;

  cout << "Enter the range of numbers to choose from separated by a space: " << endl;
  cin >> num1 >> num2;

  if (num1 >= num2)
    {
      cout << "Your selection was not valid." << endl;
      cout << "Enter the range of numbers to choose from separated by a space: " << endl;
    }
  else
    writeConfiguration(num1, num2);
};

void writeConfiguration(int num1, int num2)
{
  ofstream outputFile;
  outputFile.open("Config.txt");

  outputFile << num1 << endl;
  outputFile << num2 << endl;

  outputFile.close();

  cout << "Write Complete!" << endl;
};


which works fine for me when I run the program.

Hi there,

I tweaked the program as you suggest and now option 'a' works - except that in the "int initialize" function, if there is no config file, it should read

cout << "Error opening config file! Goodbye!" << endl;

And then exit out.

So if you choose option a with no config file, it should read that error then exit out.
Then you reopen program, choose option B, have enter in the numbers to random between.
After writing the config file, go back to displayMenu() and run the game normally.

Is it just me, or this getting extremely complicated?


initialize should throw an exception if no Config.txt file is found and then terminate. The user must run option (b) or supply a correctly formatted Config.txt file themselves (with the correct path and filename) and then run option (a) to play the game.

I think this is what you want. If it isn't I hope it helped. Good luck!
dangrr888 - if you were in the DC area, I would buy you a beer for your help.

After fixing the code like you said, I tweaked it some more to allow the option of choosing to continue to play.

And now it works like a charm.

Honestly, I cannot thank you enough - I appreciate the time and effort you put in to helping me here.
Your Welcome!
Nobody has mentioned yet that he is putting semicolons after his function definitions. You're only supposed to do that in the declaration of the function. A function should look like this.

1
2
3
void test {
    // some code
}


...and not like this:

1
2
3
void test {
    // some code
};


The only time you should have a semicolon after a closing bracket is in a class, struct, or enum.
@packetpirate
Nobody has mentioned yet that he is putting semicolons after his function definitions.

Well spotted. However, it should be made clear that an additional semicolon is purely benign. But in the interests of efficiency, yes, the semicolon shouldn't be there.
Topic archived. No new replies allowed.