Help with magic eight ball game

Hi,I've been having trouble with a magic eight ball game. I'm trying to print a random response and category from a struct but I can't seem to get it to work. Text prints out in the console but it seems to be random words from the struct and not the response and category it's suppose to print. Sometimes it only prints a category and nothing else. If anyone could help me figure out what I'm doing wrong that would be great.

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
 #include <iostream>
#include <fstream>
#include <cmath>
#include <string>
#include <algorithm>
using namespace std;

	struct magic{         //struct to store string values 
		string responses;
		string mood;
	}; 
	const int MAX_File =1000;
	
int ReadinResponses(magic responses[]);
void magicEightballGame( int size, magic ball[]);
void printResponse(const int last, magic organize[]);
void createResponsefile();
int main()
{
	char option;
	magic eightball[MAX_File]; // to hold stirng values from ReadinResponse function
	int size; //number of elements
	do{ //menu 
	cout << "a. Read responses from a file\n";
	cout << "b. Play Magic Eight Ball\n";
	cout << "c. Print out responses and categories alphabetically\n";
	cout << "d. Write responses to a file\n";
	cout << "f. Exit\n";
	cin  >> option;
	switch (option)
	{
		case 'A':
		case 'a': size=ReadinResponses(eightball); //function to read in values 
				for(int count=0; count<size; count++)
				{
					std::cout << eightball[count].responses << '\n'; // just for testing will remove when program fully functions
					std::cout << eightball[count].mood << '\n';	// just for testing will remove when program fully functions
				}
		break;
		case 'B':
		case 'b':	magicEightballGame( size,eightball); // function to play the game
					

		break;
		case 'C':
		case 'c':printResponse(size,eightball);
		break;
		case 'D':
		case 'd':createResponsefile(); // function to allow user to make their own response file.
		break;
		case 'E':
		case 'e': 
		break;
		case 'F':
		case 'f':cout << "Goodbye\n";
		break;
		default: cout << "Invalid input try again\n";


	}
} while(tolower(option)>='a'&& tolower(option)<='e');

}

int ReadinResponses(magic responses[]) //reads responses from file to struct and passes size to main
{
	
	int i = 0;
	string response;
	string mood;
	ifstream myfile("responses.txt");
	if (myfile.is_open())
	{

		while ((getline(myfile, response)) && i < MAX_File)
		{
			getline(myfile, mood);
			responses[i].responses = response;
			responses[i].mood = mood;
			

			i++;
		}

		

	}
	myfile.close();
	return i;
}



void magicEightballGame( const int size_p, magic ball[]) //plays magic eight ball
{
	if 	(size_p>0)
		{
			srand (time(0)); //seed random value
			int i = rand() % size_p;			
			cout << ball[i].responses <<  ' ' <<  ball[i].mood << '\n'; // prints out random response
		}
	else 
	cout << "No input please read an input file using option a\n";
}

void printResponse(const int last, magic organize[]) // prints responses and mood in alphabetical order
{

	 int maxElement;
		int index;

		if  (last!=0)
		{for (maxElement = last - 1; maxElement > 0; maxElement--) // sorts strut
		{
			for (index = 0; index < maxElement; index++)
			{
				if (organize[index].responses > organize[index + 1].responses)
				{
					
					
					swap(organize[index].responses, organize[index + 1].responses);
					swap(organize[index].mood, organize[index + 1].mood);

				}//if
			}//for
		}//for
		for(int index=0; index <last; index++)
				{
					std::cout << organize[index].responses << '\n'; // prints out random response
					std::cout << organize[index].mood << '\n';	// prints out random response 
				}}
	else cout << "No input please read an input file using option a\n";		
}

void createResponsefile() //allows the user to create a response file
{
	string new_response; // stores user entered response
	string new_mood; // stores category 
	char exit; // to exit the loop
	
	ofstream myfile;
	myfile.open("responsesOutput.txt");
	do // loop that alllows user to enter as many new responses and categories as they like 
	 {
	 	cout << "Enter a response\n";
	 	cin.ignore();
	 	getline(cin,new_response);	 	
	 	cout << "Enter a mood\n";
	 	getline(cin,new_mood);
	 	myfile<< new_response << '\n'  << new_mood;
	 	cout << "Would you like to enter another? n to exit\n";
	 	cin >> exit;
	 	
	 } while(tolower(exit)!='n'); 
	

	myfile.close();
	
}


text file used for testing

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
It is certain
positive
It is decidedly so
positive
Without a doubt
positive
Yes definitely
positive
You may rely on it
positive
As I see it, yes
positive
Most likely
positive
Outlook good
positive
Yes
positive
Signs point to yes
positive
Reply hazy try again
vague
Ask again later
vague
Better not tell you now
vague
Cannot predict now
vague
Concentrate and ask again
vague
Don't count on it
negative
My reply is no
negative
My sources say no
negative
Outlook not so good
negative
Very doubtful
negative
 

Hello MarbleHornets,

Thank you for including the ".txt" file. Very helpful.

Things that I have noticed so far.

1. You are missing the header file "<ctime>" for the use of "time" in "srand".

2. "srand" only needs to be called once and should be done at the beginning of main not at the beginning of the function. The way you have it could give you a responce that you do not want based on the seed producing the same random number two or more times. I once read that if you are using Windows that "srand" should be followed by a call to "rand" so that you are not using the very first number.

3. const int MAX_File =1000; is misleading. The name "MAXSIZE" or "MAX_SIZE" is a better term. "MAX_File" leads on to believe that it deals with files not an array.

4. In main in the do/while loop before the "cin" you could use a prompt asking
"Enter response" or something like that and after the "cin" the program could use a new line printed to the screen to make the output easier to read. And there are other places in the program that could use a blank line in the output to break it up and make it easier to read.

5. Call it a personal preference, but I like to put a menu in its own function where I can print the menu and verift/validate the input before returning the choice to where it was called from.

6. The "switch" looks good. I did not find any problems with that.

7. The "ReadinResponses" function appeared to work well. I did not find any problem with it.

8. The "magicEightballGame" function appeared to work well.

9. The "printResponse" function. What I noticed there is that the sort routine, which appeared to work properly, should be in its own function so it can be used from more than one place.

9A. The second for loop has a comment "// prints out random response". This is misleading because the loop prints the entire part of the array hat is used not a random response.

10. I did not try the "createResponsefile" function yet. I looks OK, but after entering something new you might want to sort the array.

Once I added the header file "<ctime>" the program seemed to work the way it should. I did not find any of the problems you mentioned.

I did find a problem with this bit of code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
	if  (last!=0)
		{for (maxElement = last - 1; maxElement > 0; maxElement--) // sorts strut
		{
			for (index = 0; index < maxElement; index++)
			{
				if (organize[index].responses > organize[index + 1].responses)
				{
					
					
					swap(organize[index].responses, organize[index + 1].responses);
					swap(organize[index].mood, organize[index + 1].mood);

				}//if
			}//for
		}//for
		for(int index=0; index <last; index++)
				{
					std::cout << organize[index].responses << '\n'; // prints out random response
					std::cout << organize[index].mood << '\n';	// prints out random response 
				}}
	else cout << "No input please read an input file using option a\n";


The indentation and placement of the closing brace } make it hard to read. When I put your code in my IDE it gave me this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
	if (last != 0)
	{
		for (maxElement = last - 1; maxElement > 0; maxElement--) // sorts strut
		{
			for (index = 0; index < maxElement; index++)
			{
				if (organize[index].responses > organize[index + 1].responses)
				{
					swap(organize[index].responses, organize[index + 1].responses);
					swap(organize[index].mood, organize[index + 1].mood);

				}//if
			}//for
		}//for
		for (int index = 0; index <last; index++)
		{
			std::cout << organize[index].responses << '\n'; // prints out random response
			std::cout << organize[index].mood << '\n';	// prints out random response 
		}
	}
	else cout << "No input please read an input file using option a\n";


As you can see the second code is easier to read.

The comments after your closing braces are good, but could be a little more descriptive like: "// End inner for" and " "// End outer for". This just helps to understand what they belong to along with the {} lining up in the same column.

If yo are still having problems be more precise as to what and where you believe the problem to be so I know where to look.

Hope that helps,

Andy
Thanks for the help Andy. Everything seems to be working after I added cmath and cleaned up the formatting is you suggested.
Topic archived. No new replies allowed.