C++ 2 dice rolling 10 million times BEGINNER - c++

I am trying to create a program that will roll 2 dice 10 million times, and output how many times each number is rolled. Along with this, I am tasked with creating a histogram (*=2000) for the outputs.
Here is what I have so far.
/*
Creating a program that counts outcomes of two dice rolls, then show a
histogram of the outcomes.
Section 1 : Simulate ten million times rolls of two dice, while counting
outcomes. (Hint: Use an array of size 13.)
Section 2 : Show the outcome, the numbers of outcomes, and the histogram
(one * designates 20000). Your output must align properly.
*/
#include <iostream>
#include <iomanip>
#include <ctime>
using namespace std;
int main()
{
int i, j, ary[13] = {};
cout << "Please enter the random number seed.";
cin >> j;
srand(j);
for (i = 0; i < 10000000; i++)
ary[die() + die()]++;
for (i = 2; i <= 12; i++)
{
cout << setw(3) << i << " : " << setw(6) << ary[i] << " : ";
for (j = 0; j < ary[i]; j += 2000)
cout << "*";
cout << endl;
}
return 0;
}
EXAMPLE OUTPUT: https://imgur.com/a/tETCj4O
I know I need to do something with rand() % 6 + 1; in the beginning of the program. I feel like I am close to being complete but missing key points! I also realize I have not defnied die() in my ary[]

I recommend creating random seeds from high precision timers such as std::chrono::high_resolution_clock. Then they are not dependent on the user and are actually random. Create the seed always before calling std::rand.
#include <chrono>
auto time = std::chrono::high_resolution_clock::now();
auto seed = std::chrono::duration_cast<std::chrono::milliseconds>(time);
std::srand(seed)
Millisecond precision makes the seed usually unique enough but if the seed is required close to 1000 times a second then i recommend using nanosecond or microsecond precision to be really random.
Best would be to create a function that creates the random seed using high precision timer and the random value and finally makes sure the return value is between 0 and 5 (for 6 sided dice).

Related

Usage of arrays to generate random numbers

I'm trying to generate N random floats between 0 and 1 where N is specified by the user. Then I need to find the mean and the variance of the generated numbers. Struggling with finding the variance.
Already tried using variables instead of an array but have changed my code to allow for arrays instead.
#include <cstdlib>
#include <ctime>
#include <cmath>
using namespace std;
int main(){
int N, i;
float random_numbers[i], sum, mean, variance, r;
cout << "Enter an N value" << endl;
cin >> N;
sum = 0;
variance = 0;
for (i = 0; i < N; i++) {
srand(i + 1);
random_numbers[i] = ((float) rand() / float(RAND_MAX));
sum += random_numbers[i];
cout << random_numbers[i] << endl;
mean= sum / N;
variance += pow(random_numbers[i]-mean,2);
}
variance = variance / N;
cout << " The sum of random numbers is " << sum << endl;
cout << " The mean is " << mean << endl;
cout << " The variance is " << variance << endl;
}
The mean and sum is currently correct however the variance is not.
The mean you calculate inside the loop is a "running-mean", ie for each new incoming number you calculate the mean up to this point. For the variance however your forumla is incorrect. This:
variance += pow(random_numbers[i]-mean,2);
would be correct if mean was the final value, but as it is the running mean the result for variance is incorrect. You basically have two options. Either you use the correct formula (search for "variance single pass algorithm" or "running variance") or you first calculate the mean and then set up a second loop to calculate the variance (for this case your formula is correct).
Note that the single pass algorithm for variance is numerically not as stable as using two loops, so if you can afford it memory and performance-wise you should prefer the algorithm using two passes.
PS: there are other issues with your code, but I concentrated on your main question.
The mean that you use inside the variance computation is only the mean of the first to i element. You should compute the mean of the sample first, then do another loop to compute the variance.
Enjoy

Random generating of numbers doesn't work properly

I'm trying to create a programm that makes sudoku's. But when I try to let the programm place numbers at random spots it doesnt use every position.
I tried to use rand(); with srand(time(0));
and random number generators from <random>.
In the Constructor i use this:
mt19937_64 randomGeneratorTmp(time(0));
randomGenerator = randomGeneratorTmp;
uniform_int_distribution<int> numGetterTmp(0, 8);
numGetter = numGetterTmp;
While I have randomGenerator and numGetter variable so i can use them in another function of the sudoku object.
And this is the function where i use the random numbers:
bool fillInNumber(int n){
int placedNums = 0, tries=0;
int failedTries[9][9];
for(int dim1=0;dim1<9;dim1++){
for(int dim2=0;dim2<9;dim2++){
failedTries[dim1][dim2] = 0;
}
}
while(placedNums<9){
int dim1 = numGetter(randomGenerator);
int dim2 = numGetter(randomGenerator);
if(nums[dim1][dim2]==0){
if(allowedLocation(n,dim1,dim2)){
nums[dim1][dim2] = n;
placedNums++;
} else {
failedTries[dim1][dim2]++;
tries++;
}
}
if(tries>100000000){
if(placedNums == 8){
cout<< "Number: " << n << endl;
cout<< "Placing number: " << placedNums << endl;
cout<< "Dim1: " << dim1 << endl;
cout<< "Dim2: " << dim2 << endl;
printArray(failedTries);
}
return false;
}
}
return true;
}
(The array failedTries just shows me which positions the program tried.
and most of the fields have been tried millions of times, while others not once)
I think that the random generation just repeats itself before it used every number combination, but i don't know what i'm doing wrong.
Don't expect random numbers to have an even distribution over your matrix - there's no guarantee they will. That would be like having a routine to randomly generate cards from a deck, and waiting until you see all 52 values - you may wait a very very long time to get every single card.
That's especially true since "random" numbers are actually generated by pseudorandom number generators, which, generally utilize multiplying a very large number and adding an arbitrary constant. Depending on the algorithm, this might cluster in unanticipated ways.
If I may make a suggestion: create an array of all of the possible matrix positions, and then shuffle that array. That's how deck shuffling algorithms are able to guarantee you have all the cards in the deck covered, and it's the same problem you're having.
For a shuffle, generate two random positions in the array and exchange the values - repeat as many times as it takes to get a suitably random result. (Since your array is limited to 9x9, I might shuffle an array of ints 0..80: extract the columns and rows with a /9 and a % 9 for each int).
I wrote a simple program that should be equivalent to your code, and it works without issues:
#include <iostream>
#include <random>
#include <vector>
using namespace std;
int main()
{
std::default_random_engine engine;
std::uniform_int_distribution<int> distr(0,80);
std::vector<bool> vals(81,false);
int attempts = 0;
int trueCount = 0;
while(trueCount < 81)
{
int newNum = distr(engine);
if(!vals[newNum])
{
vals[newNum] = true;
trueCount++;
}
attempts++;
}
std::cout << "attempts: " << attempts;
return 0;
}
Usually it prints around 400 attempts which is the statistical average.
You most likely have a bug in your code. I am not sure where though, as you don't show all of your code.

How do add random array values together into another array and then display them while counting how many values appear? C++

I wanted to simulate rolling two dice using a random number generator from 1 to 6 and then add those two values together and I am required to set this in a loop that it does this a million times. After I have acquired the values I need to display how many sums of each number appears. How would I do this? Am I on the right track? I keep getting my core dumped so I think it's a memory issue.
Here is the text that I am suppose to follow:
"Suppose you have a game where you roll two dice, that follow these rules:
Roll 1-11: Get that value
Roll 12: Reroll and add one to the value
The “roll 12” rule can be hit multiple times. For example, if you roll (6,6) then (6,6) then (1,1),
your total value for that game will be 4 (as 1+1+2=4). Write a program that simulates one iteration of this game.
Then write a loop that runs this game 1,000,000 times, keeping track of how many of each value you saw, then display the results showing every value and what percent of the time you got that value.
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using namespace std;
int main ()
{
int i, k, l, y, ncount;
k=0;
l=0;
y=0;
int R[1000000];
int T[1000000];
int S[1000000];
srand(time(NULL));
for (i=0; i<1000000; i++)
{
R[k] = (rand() % 6 + 1);
T[l] = (rand() % 6 + 1);
S[y] = R[k] + T[l];
k++;
l++;
y++;
}
ncount = count (S, S+1000000, 1);
cout << "1 appears " << ncount << " times.\n";
return 0;
}
I liked this - quite cute - experiment.
Here's a sample bit of code you cannot use (it uses all kinds of library stuff and C++14 goodness that your course will definitely not allow, statistically speaking, and which would raise a good number of eyebrows if you turned it in).
However it can serve as inspiration and to validate your bias-free random number generation and correct statistics!
Live On Coliru
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <iomanip>
#include <iostream>
#include <random>
namespace ba = boost::accumulators;
namespace bat = ba::tag;
using namespace std;
static mt19937 engine { random_device{}() };
static uniform_int_distribution<unsigned> dist(1, 6);
auto single() {
return dist(engine);
}
auto dual() {
auto a = single(), b = single();
//cout << "Rolled (" << a << ", " << b << ")\n";
return a + b;
}
auto magic_roll() {
int eyes, extra = 0;
while (12 == (eyes=dual()))
extra += 1;
return extra + eyes;
}
int main() {
ba::accumulator_set<unsigned, ba::stats<bat::mean, bat::variance> > stats;
constexpr auto N = 15;
size_t histo[N] = { 0 }; // allow for quite extreme outliers
for (size_t i = 0; i < 1'000'000; ++i) {
auto score = magic_roll();
//cout << "score: " << score << "\n";
stats(score);
assert(score >= 2 && score < N);
++histo[score];
}
cout << "Mean: " << ba::mean(stats) << "\n";
cout << "Std Deviation: " << sqrt(ba::variance(stats)) << "\n";
auto peak = *max_element(begin(histo), end(histo));
auto scale = [peak](auto v) { return v * 60.0 / peak; };
auto bucket = 0;
for(auto v : histo)
{
cout << "Histo bucket: " << right
<< setw(2) << bucket++ << "\t"
<< setw(6) << v << " " << string(scale(v), '*') << "\n";
}
}
Output
Mean: 6.88604
Std Deviation: 2.29999
Histo bucket: 0 0
Histo bucket: 1 0
Histo bucket: 2 27806 *********
Histo bucket: 3 56229 *******************
Histo bucket: 4 84624 *****************************
Histo bucket: 5 113481 ***************************************
Histo bucket: 6 142361 **************************************************
Histo bucket: 7 170696 ************************************************************
Histo bucket: 8 143744 **************************************************
Histo bucket: 9 114814 ****************************************
Histo bucket: 10 86860 ******************************
Histo bucket: 11 57734 ********************
Histo bucket: 12 1611
Histo bucket: 13 39
Histo bucket: 14 1
As I interpret this assignment, it does not require a large array.
Then write a loop that runs this game 1,000,000 times, keeping track of how many of each value you saw,
Notice that you do not keep track of every value you saw; you merely keep track of how many times you saw it.
Moreover, the value you have to count is only the final value after you have "played" the game once, that is, rolled two dice repeatedly until you get something that is not double sixes. In the example you were given, rolling (6,6), then (6,6), then (1,1), those three rolls of the two dice are just one game, whose final value is 4. Therefore, after all these rolls you would add 1 to the number of times you have seen 4.
The data storage for this game only needs to store one integer for each value you might get at the end of a game. The bad news is that the game has no maximum theoretical value--in theory it is possible that you might roll (6,6) any number of times one right after the other, resulting in a high value for the game.
In practice, however, it is very unlikely that you will roll double sixes more than a few times in a row.
One well-known way to keep count of the number of times each value has occurred, when the range of possible values that may actually occur is not too large, is to allocate an array a little larger than the largest value you have to count. If you name the array count, then count[2] is the number of times a 2 has occurred, count[3] is the number of times a 3 has occurred, etc.
(This is not so convenient if you have to count how many times a negative number occurs, but you don't have to worry about that in this case.)
Other ways include data structures where you keep pairs of numbers: the first number of each pair is a value, the second is how many times the first number has occurred. The data structure could be anything that can store pairs of numbers: a linked list you designed yourself, an std::list, or an std::map.
But each time you "play" a game you have to search your data structure to see if the value of that game has occurred before, and then either add 1 to the number of times that value has occurred, or make a new pair of numbers in your data structure to count the first occurrence of that value.
then display the results showing every value and what percent of the time you got that value.
In other words, showing every different value once, along the percentage of games that had that value.
But it is generally not good practice to write some lines of code specifically for each value you want to print, the way you did in your example to show
how many times the value 1 occurs.
By the way, be sure to read the description of the game carefully.
Your initial attempt to program this will never produce the value 13, but the game can result in the value 13, or even 14 or higher.
For example, rolls of (6,6), then (6,6), then (6,5) make one game with a value of 1 + 1 + 11 = 13.
Another recommendation: do not create a multitude of differently-named
variables that you do not really need.
In your initial attempt at this program you have variables k, l, and y
whose only use is to index the arrays R, S, and T.
Never once when you use any of these variables for these purposes
will the value of any of these variables be different from i.
Your loop would have been better written
for (int i=0; i<1000000; i++)
{
R[i] = (rand() % 6 + 1);
T[i] = (rand() % 6 + 1);
S[i] = R[i] + T[i];
}
That loop does exactly what your loop does, but it is much clearer what it
actually does do when you see it in this form.
As explained above, however, much better still is not to write the loop
this way at all: you do want the for (int i=0; i<1000000; i++)
but not the stuff inside the loop.

C++ Random Number Generator For Loop

So, I have a small problem here with a rather large for loop. This program is to simulate random walks of 100 steps each - what I want to do is have the program perform 1 million of these random walk simulations (the random walk is done by the nested for loop essentially by simulating the flipping of a coin, as you can see in my code below) and take the resultant displacement from each of these random walks and print them to the console window and to the specified output file.
However, my code seems to be adding each final value of x from the nested for loop and then printing them to the console window (and saving to output file) - I don't want this, I just want the standalone net result from each random walk to be outputted for each value of j (which ranges from 1 to 1E6 as specified by the outer for loop).
Thus, any help would be greatly appreciated. Also, I would very much appreciate you to not just quote some code for me to use instead but rather explain to me where my program logic has gone wrong and why.
Thanks in advance, my code is below!
#include <iostream>
#include <ctime>
#include <fstream>
using namespace std;
int main(void) {
const unsigned IM = 1664525;
const unsigned IC = 1013904223;
const double zscale = 1.0/0xFFFFFFFF; //Scaling factor for random double between 0 and 1
unsigned iran = time(0); //Seeds the random-number generator from the system time
const int nsteps(100); //Number of steps
const int nwalks(1E6);
int x(0); // Variable to count step forward/back
ofstream randout;
randout.open("randomwalkdata2.txt");
// Table headers for console window and output file
cout << "Random Walk Number \t Resultant Displacement \n";
randout << "Random Walk Number \t Resultant Displacement \n";
for ( int j = 1 ; j <= nwalks ; j++ ) {
for ( int i = 1 ; i <= nsteps ; i++ ) {
// if-else statement to increment/decrement x based on RNG
if ( zscale * double( iran = IM * iran + IC ) < 0.5 ) //RNG algorithm
x++;
else
x--;
}
cout << j << "\t" << x << endl;
randout << j << "\t" << x << endl;
}
randout.close();
return 1;
}
You forgot to re-initialize x after each random walk.
cout << j << "\t" << x << endl;
randout << j << "\t" << x << endl;
x=0;
Should do the trick.

Outputting Max min and average from a randomized array?

I was wondering if anyone can help me with something I was struggling all day with.
In the code below I dictated an array of randomized numbers from which I have to have pull out the max the min and the average. It all looks fine and good (such a compact software!) But I attain a weird output. I believe I have a finger on what the problem is (say I'm finding the max for the first number but the next number is smaller the software will think that's the biggest number even though integer 14 may be bigger) but I have no idea how to go about fixing this. The minimum value I have no idea why it's wrong it keeps saying it's zero and the average value stays anywhere from 10-19 which is impossible considering the range of randomized numbers goes from 1 to 1000. I was never taught how to organize random numbers in an array, so I just have no idea how to go about fixing this. Any help will be super awesome! I really struggled with this program and even scrapped it multiple times, if it's only a simple mistake I overlooked I would feel awfully embarrassed I'll post the code and an example output below.
Thanks for taking your time, I hope you have a wonderful day!
#include <cmath>
#include <iostream>
#include<cstdlib>
#include <ctime>
#include <time.h>
#include <iomanip>
using namespace std;
int main()
{
//Defining variables
//DEFINE SIZE
const int ARRAY_SIZE =20;
//Index variable
int i;
//For finding average
double sum=0;
double max_value;
double min_value;
//Keep all numbers sane
cout.precision(5);
srand((unsigned)time(0));
double main_array[ARRAY_SIZE];
//Header
cout << "Element number \t\t" << "Random Number\n\n" << endl;
//Assigning random values into array.
for (i=0; i< ARRAY_SIZE; i++)
{
max_value=0;
min_value=0;
//Randomizer
double ran = 0 + (rand()/((float)RAND_MAX/(1000-0)));
main_array[i] = ran;
cout << "\t" << i << "\t\t" << main_array[i] << endl;
//Find average
sum= (sum + main_array[i]);
sum= sum/(ARRAY_SIZE+1);
//Initalizing
for (int i = 0; i < ARRAY_SIZE; i++)
{
if ( min_value > ran)
min_value = main_array[i];
if (max_value < ran)
max_value = main_array[i];
}
}
cout <<"Average Value is: " << sum << endl;
cout <<"\nThe Minimum Value Is: " << min_value << endl;
cout <<"\nThe Maximum value Is: " << max_value << endl;
system ("pause");
return 0;
}
An output example would be
Element number Random Number
0 791.62
1 542.04
2 879.57
3 875.39
4 38.057
5 73.702
6 973.27
7 22.431
8 830.26
9 444.59
10 276.89
11 888.12
12 827.17
13 900.45
14 883.72
15 201.15
16 317.64
17 649.83
18 443.98
19 683
Average Value is: 33.603
The Minimum Value Is: 0
The Maximum value Is: 791.62
Press any key to continue . . .
Unless you must do otherwise, use std::min_element to find the minimum, std::max_element to find the maximum, and std::accumulate to find the sum.
If you absolutely must do this on your own, you usually want to initialize your minimum and maximum to the first element in the collection, then look for others that are smaller/larger:
int mininum = array[0];
int maximum = array[0];
for (int i=1; i<array_size; i++) {
if (array[i] < minimum)
minimum = array[i];
if (array[i] > maximum)
maximum = array[i];
}
Before you start looping, create a min, max, and total. Then when you are creating each element of the array, also check whether it is less than the min or more than the max. Also add that number to your total. At the end, outside the loop, divide the total by the number of elements to get your average.
You definitely shouldn't be iterating through the whole array each time you add an element, and you shouldn't be resetting your min and max each time through the loop. You also shouldn't set your min to 0 if all your numbers are going to be more than 0, because it will never be updated.