How can I implement vectors into my program?

I'm having trouble with what the author wants from me when he states, "Real randomness is too hard to provide just now, so just build a vector into the program, it will always play the same game, so maybe you should let the user enter some values. Try variation to make it less easy for the users to guess which move the machine will make next.

I didn't know how to do it with vectors so I tried to break the problem into more simpler terms where I can solve it, which I did. I did it without vectors. Here's my question, how could I implement vectors in my program? And what does he mean by real randomness is hard to do right now so use vectors? I am confused in what he wants.
It's summer right now, and I'm continuing my journey in learning C++. I'm also trying to prepare myself for my next CS class in August.


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
#include "std_lib_facilities.h"
void youWin()
{
	cout << "You win!";
}
void youLose()
{
	cout << "You lose!";
}
void youTied()
{
	cout << "It's a tied";
}
int get_playerChoice()
{
	int choice;
	cout << "Enter your choice";
	cin >> choice;

	return choice;
}
int get_cpuChoice()
{
	int choice = (rand() % 3) + 1;

	return choice;
}
int main()
{
	srand(time(NULL));
	char play;
	cout << "Enter any character to star the game of Rock Paper Scissors." <<'\n';
		cin >> play;
		while (play != '|')
		{


			cout << "Enter 1 - Rock, 2 - Paper, 3- Scissors." << '\n';
			int choice = get_playerChoice();

			switch (choice)
			{
			case 1:
				cout << "You selected Rock!" << '\n';
				break;
			case 2:
				cout << "You selected Paper!" << '\n';
				break;
			case 3:
				cout << "You selected scissors" << '\n';
				break;
			default:
				cout << "You selected an invalid choice";
				break;
			}

			cout << "Computer choice to enter 1-Rock, 2- Paper, 3 - Scissors." << '\n';
			int cpuChoice = get_cpuChoice();
			switch (cpuChoice)
			{
			case 1:
				cout << "Computer selected Rock!" << '\n';
				break;
			case 2:
				cout << "Computer selected Paper!" << '\n';
				break;
			case 3:
				cout << "Computer selected Scissors!" << '\n';
				break;

			}
			if (choice == cpuChoice)
			{
				youTied();
			}
			if (choice == 1)
			{
				if (cpuChoice == 2)
				{
					youLose();
				}
				else if(cpuChoice == 3)
				{
					youWin();
				}
			}
			else if (choice == 2)
			{
				if (cpuChoice == 1)
				{
					youWin();
				}
				else if (cpuChoice == 3)
				{
					youLose();
				}
			}
			else if (choice == 3)
			{
				if (cpuChoice == 2)
				{
					youWin();
				}
				else if (cpuChoice == 1)
				{
					youLose();
				}
				
			}
			cout << "\nEnter any character to continue to play or enter | to stop the program.";
			cin >> play;
			if (play == '|')
			{
				break;
			}
		}

	


	keep_window_open();




	return 0;
}
Here's my question, how could I implement vectors in my program? And what does he mean by real randomness is hard to do right now so use vectors?

We should know more about its context to give you any answer. It looks as if the author assumes you don’t know about rand() and pseudo-random numbers.

The rock-paper-scissor game, as any game with a little number of combinations, can be implemented by what are called lookup tables.
The logic is you can “inform” the program about all the possible combinations, so that it can just pick the correct one without any calculation.

If you have a look at the following table, I think you can easily guess what I’m talking about:

Rock, scissor, paper combination table:
---------------------------------------
                 Player 1
          |  rock    scissor   paper
Player 2  |---------------------------
    rock  |  draw    P2 wins    P1 wins
scissors  | P1 wins    draw     P2 wins
   paper  | P2 wins  P1 wins     draw


So, if you know what’s a bi-dimensional vector, you can re-write your code removing nearly any logic. The problem is I haven’t understood if you’ve already met vectors…

Another possible interpretation of the text is: “since you don’t know what a pseudo-random number is, just provide a number of computer ‘moves’ in random order and pretend your program is playing against the user”. I mean, perhaps the author suggests creating a vector which stores, let’s say 9 moves in random order, and then use them against the user:
A vector like:
1 - rock
2 – scissors
3 – paper
4 – paper
5 – scissors
6 – rock
7 – rock
8 – paper
9 – scissors
Getting through it several times can appear to be a player who ‘thinks’ about the answer, while it’s just the same pattern which repeats.

Your code works, but it's really difficult to help you without a larger context. Or, at least, it’s really difficult for me since I’m not a native English speaker. Maybe someone else could work out more easily what the text requires.
Last edited on
Have a look at my demo. I guess you could replace the array with a vector.
http://hobbyprogrammer.byethost13.com/downloads/cpp/rock_paper_Scissor/
Hello BlackSky,

I think what the author may have in mind is 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
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
#include <iostream>
#include <string>
#include <vector>
#include <conio.h>    // _getch() This header and function will not work if run from this web site.
#include <chrono>     // For use in std::shuffle
#include <algorithm>  // For std::shuffle
#include <random>     // For use in std::shuffle


void LoadVector(std::vector<int>& vChoices);
int GetComputerChoice(std::vector<int>& vChoices, int& subScriptValue);

int main()
{
	int subScriptValue{ 0 };
	int computerChoice{ 0 };
	std::vector<int> vChoices;
	srand(time(NULL));


	LoadVector(vChoices);

	//  Prints out vector after shuffle
	for (size_t lp = 0; lp < vChoices.size(); lp++)
	{
		std::cout << vChoices[lp] << ((lp < vChoices.size() - 1) ? ", " : "");

	}

	std::cout << std::endl;

	std::cout << "\n\n\n\n Press anykey to continue";
	_getch();  // <--- My compiler requires this version getch().

	return 0;
}

void LoadVector(std::vector<int>& vChoices)
{
	// You could pass seed from main which would make the next line unnecessary.
	// But you would have to define seed in main.
	// Came form http://www.cplusplus.com/reference/algorithm/shuffle/
	unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();

	for (int lp = 0; lp < 10; lp++)
	{
		vChoices.emplace_back(std::rand() % 3 + 1);
	}

	// Format used from http://www.cplusplus.com/reference/algorithm/shuffle/
	std::shuffle(vChoices.begin(), vChoices.end(), std::default_random_engine(seed));

	//	_getch();  // <--- Used for testing.
}

int GetComputerChoice(std::vector<int>& vChoices, int& subScriptValue)
{
	return vChoices[subScriptValue++]; // <--- subScriptValue will have changed with each call to function.
}


Hope that helps,

Andy
@ Handy Andy, I do appreciate your feed back, and I will look at your code through a debugger to see exactly what it's doing, unfortunately I haven't learned about the algorithm libraries or the others yet. That's in chapter 21 Algorithms and Maps. I'm currently in chapter 4.

@Thomas 1965 Thank you for your feed back, I will compare your code to mine, and see what I can implement in changes of my code to add an vector.
.

Last edited on

@Enoizat So far the author introduce a little about vectors as in what is a vector, traversing vector, and a growing vector. Chapter 17-19 is where he teaches me everything I need to know about vectors. But as of now I only know a little bit what vector is and what it can do.

From your suggestion, would you suggested something like this?
Create a vector inside of the get_cpu function, with pushing back the random numbers 1-9 into the vector using a for loop.
And then add more case numbers for 4-9, as well add more conditionals statements to check? Or what are you suggesting if you can show me a little what to start with that would show me an idea how to do it.
Hello BlackSky,

Create a vector inside of the get_cpu function, with pushing back the random numbers 1-9 into the vector using a for loop.

No this would be the wrong place to create and load the vector. If you define the vector inside the "get_cpuChoice" function it will be lost when the function ends.

The idea of using a vector is to come up with choice for the computer that would appear more random. You could bypass a function to load the vector by defining it in main like std::vector<int> vChoices{ 1 ,3 ,2, 1, 2, 3 };. This would seem to have the appearance of being random. Then you would only need to pass the vector and "sunScriptValue" to the "get_cpuChoice" function to make use of it as I have shown you.

The vector should only contain numbere 1, 2 and 3 I do not understand what you mean by pushing back the random numbers 1-9.

And this does not make any sense to me And then add more case numbers for 4-9, as well add more conditionals statements to check because the game only has three choices.

Back in the day when I was in my first computer language class the teacher was useless, but one thing he said went something like this. Read ahead i the book because if you wait until I lecture on something you will not have enough time to complete your lab assignment.So I read the whole textbook and was trying to do things with my programs ahead of what was needed. Mostly worked, but sometimes did not.

In the top left corner of this page there are links to tutorials, reference and articles all which are good places to research what you may not know. I find these very useful especially the reference link that I use most every day because I do not have any books to use. Until you learn and get use to the syntax of the language to here you can code with really thinking about it you will find that you will be referencing books and looking things up online until you are familiar with them.

When you ask a question here you are likely to get code that you do not understand or that is farther ahead of where you are at. Do not let that intimidate you, but use it to learn from. There has been many pieces of code that I have copied and go back to later for ideas or code that I have put in a program just to understand how it works.

The code I gave you in my earlier post I can see now that it contains more than what you have learned so far. It is a workable idea, but I can make it more simple to just cover the basics. Refer to the earlier paragraph where I defined and initialized the vector.

The code I showed you in an earlier message is something you can add to what you already have. I just wrote it as a stand alone program so you could see what could be done. I gave you the opportunity to figure out how to add to the code you have.

If there is anything unclear let me know.

Hope that helps,

Andy
Hi Handy Andy,

Thank you for your feedback and I really do appreciate. As a beginner I am often intimidated when I see other solutions on here that are more than what I know. I am glad that I do not have to be intimidated anymore and can now accept that it's part of the learning experience.

If you do not mind making a more simple solution where it just covers the basics from what I have learned so far, this would help me a lot. That way I am able to see from your point of view what you did, and what I should do. Also here's a question is it possible to redefine the function as a return vector type? Maybe by doing so I can create a vector inside of that function and it will return all the elements in that function.

Or should I just get rid of the get_cpu function, and initialized the vector in the main function with random numbers ranging from 1-3? Like you mention in your last comment. If I do this then I need to figure out how I can pass my vector of ints into my switch statement. Or maybe get rid of the switch statement and use if and else statements where I can check for the end of the vector? I'm not sure what I am really talking about just thinking out loud.

During the mean time I just move on to chapter 5, where the author talks about errors and what I should be aware of.

I usually work on a set of problems maybe 4 or 5 during the week, so one problem a day and after that I move to the next chapter. As the author stated in chapter 2, it's important to do the drills but it's not needed to do all the exercises given, some exercises are trivial and others not so much. If you can't do an exercise it does not mean you are not meant for this, you are still learning, and it will take time.

I've noticed I tend to feel stupid or get frustrated when I can't solve the problem on my own, after failing multiple times I look up a solution. I copy and paste it, but not literally I rewrited on VS, and I used a debugger and follow what's going on and from there once I understand it, I write my own version of it. I've done it with 2 out of the 5 problems I did for chapter 4.

The rock paper scissors I was not sure how to approach that one, so I try to look up solutions for it, but still felt confused on the idea. So I looked it up on youtube found a really basic version of it. After watching that video and the way that person explained the why. I knew how to write my own version of it which did help a lot. I guess what I lack on was the logic of it, once I saw the logic I knew how to executed my way.

As a beginner I need to realize programming it's a different way of thinking. If you tell me to add two numbers on paper, and do not use any negative numbers. That's easy, but if you tell me to create a return function and add two numbers in it, then have values to check the user does not enter any negative values, that is easy now, but when I first started learning functions I had to think about it. And plan what I need it to do. I need to create a void function or I can have it all in one function. I need a while loop to check if the user input is not less than 0, if it is ask them to enter a positive statement, etc...

Last edited on
closed account (48T7M4Gy)
An alternative approach:
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
#include <iostream>
#include <vector>

using namespace std;

int main()
{
    // Make up a list of labels
    vector<string> label{"scissors", "paper", "rock"};
    
    // Make up a series of 'random' turns the computer makes
    vector<int> computer_turn {0,1,2,2,0,0,1,1,1,2,0,0,0,1};
    int series_size = computer_turn.size();
    
    int player_turn = 0;
    char keep_going = 'y';
    int next_turn = 0;
    
    // Play the game
    while(cout << "CONTINUE? <y/n> " && cin >> keep_going && keep_going == 'y')
    {
        cout << "Your move 0,1 or 2 ";
        cin >> player_turn;
        
        cout << "        You played " << label[player_turn]<< '\n';
        cout << "   Computer played " << label[computer_turn[next_turn]] << '\n';
        
        // Lots of stuff goes here to analyse the current move
        
        next_turn++;
        next_turn = next_turn % series_size; // % to keep within vector bounds
    }
    
    return 0;
}
Last edited on
closed account (48T7M4Gy)
As it turns out I see that the above code of mine is very similar to what @Enoizat is driving at in the second part of his/her post. Great minds think alike I guess :)
closed account (48T7M4Gy)
And after a bit of tinkering:
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
#include <iostream>
#include <vector>

using namespace std;

int main()
{
    // MAKE UP A LIST OF LABELS
    vector<string> label{"scissors", "paper", "rock"};
    
    // MAKE UP A SERIES OF 'RANDOM' COMPUTER TURNS
    vector<int> computer_turn {0,1,2,2,0,0,1,1,1,2,0,0,0,1};
    size_t series_size = computer_turn.size();
    
    int player_turn = 0;
    int next_turn = 0;
    
    int score = 0;
    
    // PLAY THE GAME
    while(
          cout << "Your move <0,1 or 2 anything else to quit> "
          && cin >> player_turn
          && player_turn < 3
          && player_turn >= 0
          )
        
    {
        cout << "     You played " << label[player_turn]<< '\n';
        cout << "Computer played " << label[computer_turn[next_turn]] << '\n';
        
        score = 10 * player_turn + computer_turn[next_turn];
        
        switch(score)
        {
            case 0: case 11: case 22:
                cout << " Game is a draw\n";
                break;
                
            case 1: case 12: case 20:
                cout << "        You win\n";
                break;
                
            case 2: case 10: case 21:
                cout << "  Computer wins\n";
                break;
                
            default:
                cout << " ** Invalid game\n";
                break;
        }
        next_turn++;
        next_turn = next_turn % series_size; // % TO KEEP WITHIN VECTOR BOUNDS
    }
    
    return 0;
}
Hello BlackSky,

There are two ways to make what I did simple:

1. in the "LoadVector" function remove everything except the for loop.

2. Or in main define the vector and initialize it with the choices for the computer choice std::vector<int> vChoice{ 1, 2, 3, 2, 3, 1 }; where the numbers are s many as you will want and in any order you want. Then in your switch at line 59 you could use switch (vChoices[subScriptValue]). Just remember that in the case statements to add 1 to "subScriptValue" so the next time through it will use the next element of your vector. BTW this will eliminate the need for the "LoadVector" and "get_cpu" functions.

kemort has a good solution also. Notice that his use of the vector "computer_turn" is different because it works with the vector "label". doing it this way you have to remember that any type of array will start at zero not one.

I see that you are using VS. A hint for using rand():
1
2
srand(time(NULL));
rand();

You could say that this is a quirk with VS and Windows, but as I have read here calling "rand()" after "srand()" will give you a better number on the second call to "rand()".

The way you work through the problems in the book is a good learning experience. Do not be afraid to read ahead in your book and do not be afraid to try something that is not covered in your book or that has not been talked about yet. The beauty of C++ is that you do not always have to know what is between the {} of a function to use it, but what parameters are needed by the function and knowing what the function returns. I use the reference pages here most every day to remind me of how some function works or to look up something that I am not familiar with. When you have the time reading here about other people's problems is very helpful in understand how C++ works.

Hope that helps,

Andy
kemort wrote:
Great minds think alike I guess :)

You were talking about Handy Andy and you, were you?

Let me say this solution of yours:
next_turn = next_turn % series_size; // % TO KEEP WITHIN VECTOR BOUNDS
IMO is a real stroke of genius.
closed account (48T7M4Gy)
You were talking about Handy Andy and you, were you?

No it was you I was referring to Enoizat. But now I will include Handy Andy. I hadn't read either of the posts in detail until after I'd posted - so credit where credit's due because you two had already suggested it.

FWIW I googled the original question in Stroustrup's book which gives a hint to what he means by fake randomness and how to use a vector to simulate it.
:)
Topic archived. No new replies allowed.