Getting Started
If you missed lab or failed to copy my code from the projector during lab session, the files I typed/utilised during lab sections 1 and 2 are available here: [LINK]
Synopsis
So by now, you probably know that there is a better way to actually store values besides making a lot of variables for them. If you wanted to store a "grid" of data, you can use an array. In this lab, you will have values in an array that you will pull from to generate a password.
RNG [Random Number Generator]
Ever played an FPS game and wondered how the gun's bullets are almost never on spot with your aim? Maybe a gambling game that has you rolling a dice where you have a "chance" of achieving a certain number? The computer does this by using a random number generator. Of course, these numbers are not truly random by any means. The numbers are generated (hence the name) based on a seed. If you played Minecraft and noticed how entering the same seed gives you the same map every time, that is the exact concept all RNGs use.

Introducing srand() and rand()

To utilise the RNG, you must specify a seed with "srand()". Afterwards, you can call "rand()" and it will generate a number for you. Let's generate a few:
#include <iostream>
#include <cstdlib>

using namespace std;

int main() {
    //Set the RNG's seed to 2 and generate a few numbers
	srand(2);
	for (int i = 0; i < 5; i++) {
        cout << rand() << endl;
	}
}
The output might look like this (You may get different numbers)
1505335290
1738766719
190686788
260874575
747983061

Generating numbers between certain values

There are a few ways you can do this. Let's say you wanted to generate numbers between 0 and 20 (excluding 20), you can utilise modulo division:
int value = rand() % 20;
Now, if you wanted to generate numbers between 10 and 20 (again, excluding 20), we can modify the formula a little:
int value = 10 + rand() % (20 - 10);
What about actually including 20 though? Then we will do this:
int value = 10 + rand() % (20 - 10 + 1);
See how it is working? "20 - 10 + 1" is "11", and "rand() % 11" can go up to 10 without going back down to 0. Then we simply add 10 to it. This will force the value to be between 10 and 20.

Overall, your formula for generating numbers including the bounds is:
int value = MIN + rand() % (MAX - MIN + 1);

How seeding really works

If you specify the same seed, you will get the same "random" numbers. For instance:
#include <iostream>
#include <cstdlib>

using namespace std;

int main() {
	srand(2);               //Set the RNG's seed to 2.
	cout << rand() << endl; //Print out generated value
	srand(2);               //Set the RNG's seed to 2 again
	cout << rand() << endl; //Print out generated value... again
}
If you noticed, the output will be the same for both couts, even though we called rand() twice!
1505335290
1505335290
The reason behind this is because the RNG is like a mathematical equation. If you think of a linear equation in math, like y = 2x + 1, at y(0), you will get 1. At y(1), you will get 3, etc. The random number generator starts at position 0 of some bizarre function, and goes up on every call of "rand()". But if you call "srand()", it will go back down to 0. And if the seed is the same, it will generate the same numbers because it will run across the same equation. That is why it generates the same numbers if the same seed is given.

So if you are wondering why you are generating the same numbers constantly, take a look at if you are calling "srand()" more than once in your program. That is likely the reason why.
Arrays
Arrays are like a grid or a matrix of data that we can store and access from in the program. Let's say you wanted to calculate the average for your tests in a class and there were 4 tests:
int main() {
	int test1 = 100; //Easy test
	int test2 =  90; //Somewhat Easy
	int test3 =  65; //Had a bad night prior
	int test4 =  75; //Cs get degrees

	double average = (double)(test1 + test2 + test3 + test4) / 4;

	cout << average << endl;
}
Just for flavour, here is the program's output:
82.5
If there are 4 tests, this code is good. Though it looks very messy. Why declare 4 different variables whenever we can have one variable store all 4 of them in one go? That is what arrays are for. Observe:
int main() {
	int test[4];
	test[0] = 100;
	test[1] =  90;
	test[2] =  65;
	test[3] =  75;

	double average = (double)(test[0] + test[1] + test[2] + test[3]) / 4;

	cout << average << endl;
}
Introducing arrays. Now we can simply store the index of the test in the [X] operator in the variable, as long as it doesn't go past the size we specified. So if I declared "test[4]", we can access 0, 1, 2, and 3, but not 4. This is because 0 is included in the mix.

We can up the game once more. What about an initialiser list? We can simply those 4 assignment operators to one line like this:
int test[4] = { 100, 90, 65, 75 }; //Array of tests
We can also make it support multiple varieties of tests too by making the number of tests into a constant that we can change later on. We can then loop through the values, add them, and then divide them. The program would end up looking like this:
#include <iostream>
#include <cstdlib>

using namespace std;

const int TEST_NUM = 4;

int main() {
	int test[TEST_NUM] = { 100, 90, 65, 75 }; //Array of tests
	double average = 0;                       //Declare average
	for (int i = 0; i < TEST_NUM; i++)
	    average += test[i];                   //Add all of the tests together
	average /= TEST_NUM;                      //Divide by number of tests

	cout << average << endl;                  //Print it out
}
And so if we wanted to add a fifth test:
#include <iostream>
#include <cstdlib>

using namespace std;

const int TEST_NUM = 5;

int main() {
	int test[TEST_NUM] = { 100, 90, 65, 75, 100 }; //Array of tests
	double average = 0;                            //Declare average
	for (int i = 0; i < TEST_NUM; i++)
	    average += test[i];                        //Add all of the tests together
	average /= TEST_NUM;                           //Divide by number of tests

	cout << average << endl;                       //Print it out
}
The Lab

The rundown

The code will ask for three inputs:
Enter seed:
Enter password length:
Accept password? 
Few things to note here:
  • There are spaces after each of the fields. Include those in your cout statements.
  • "Accept password? " is printed out after the user is done generating the password. So it will come after the password is generated.

Breakdown of password generation

You will have your array store the following values (as written in the lab writeup):
Array Element:  0    1    2    3    4    5    6    7    8    9
Array Value  : 'a', 'b', 'c', 'd', 'E', 'F', '!', '*', '6', '2'
So if we told the program to have the seed "2" and a length of "4", for instance, the program will set the seed to 2. Then it will pull characters from the array pseudo-randomly and toss it into the string. The password will have 4 characters as we told it to generate 4. So at the start, it will be nothing:
Password:
          ^^^^
So now we will call our random_character function to generate a random character from the array. It must choose a value between 0 and 9. Let's say it chose 2. It will go into the array at element 2, and return 'c'.
Password: c
          ^^^^
It will repeat the process until it has chosen 4 characters. Let's run it again and let's say the function chose element 7:
Password: c*
          ^^^^
Let's say the numbers chosen for the third and fourth was 3 and 5 respectively. It would just slap on 'd' and 'F'.
Password: c*dF
          ^^^^
Now that that is printed out, ask the user "Accept password? " and if they type y or Y, terminate the program.