Tracking where a user has landed in a board game - c++

The idea of the program is that it simulates a game board with a user-inputted number of sides, and cells per side. The program then needs to simulate the user rolling two six-sided dice continuously until the starting tile is landed on or passed.
The problem I'm having is with a required function that records the spot the user landed on the most, per side of the game board (like a Monopoly board has 4 sides). For example, a Monopoly board with 4 sides, 10 cells on each side.
Side 1 has Cells 1 - 10
Side 2 has Cells 11 - 20
Side 3 has Cells 21 - 30
Side 4 has Cells 31 - 40
I'd need to report which cells I landed on the most for each of those four sides, or however many sides the gameboard has.
I have no idea how to start this function. I don't want the code to be written out for me, just a nudge in the right direction. As for the rest of the program, this is what I have:
#include <iostream>
#include <cmath>
#include <ctime>
#include <cstdlib>
using namespace std;
int rollNDice(int nDice, int nSides) {
int diceSum = 0;
for (int i = 0; i < nDice; i++) {
int randnum = 1 + (rand() % (nSides - 1 + 1));
diceSum = diceSum + randnum;
}
return diceSum;
}
int mostLandings(const int boardVector, int startInterval, int endInterval) {
}
int main() {
srand(333);
int boardSides = 0;
int boardSpotsPerSide = 0;
int numberOfSims = 0;
int diceMove = 0;
int startInterval = 0;
int endInterval = 0;
const int boardVector = 0;
cout << "How many sides of the board are there? ";
cin >> boardSides;
cout << "How many spots on each side? ";
cin >> boardSpotsPerSide;
cout << "How many simulations? ";
cin >> numberOfSims;
for (int i = 0; i < boardSides;) {
const int boardVector = boardSides * boardSpotsPerSide;
int spotsPerInterval = boardVector / boardSides;
startInterval = spotsPerInterval / spotsPerInterval + (10 * i);
endInterval = spotsPerInterval * (i + 1);
mostLandings(boardVector, startInterval, endInterval)
i++;
}
}

One possible approach would be to start by calculating the total amount of squares on the board. The amount of squares q can be given by
q = 2s + (s-1)(n-1) = sn + s- n + 1
where s is the amount of squares on each side and n is the amount of sides. Next, store each roll value and loop over the sum of the roll value and the player's previous position, and store those values in a separate array. Take each element in that array modulo q and store in a separate array. This array should be the index of each square landed on after each subsequent turn, which you can manipulate and read from as you like.

Related

Adding random generated numbers to arrays + averaging those arrays

HW Question: We will simulate the throwing of dice. Again we will use Top-Down_Design to improve the readability, etc.
Generate 20 dice throws of two dies. Each die can generate a number of dots from 1 to 6. Add the two numbers together to get the value of the throw.
In one pass generate the 20 throws and store the numbers in an array.
In a second pass calculate the average of the numbers and display that on the console.
Seed the Random Number Generator with 8193 one time before getting any random numbers.
NOTE : We have not talked about passing a Array to functions. So for this assignment you can make the array of Dice throws global.
//I'm just confused to the concepts of adding the random generated numbers to arrays and then averaging them through the Top Down method.
#include <iostream>
#include <cstdlib>
using namespace std;
void Gen_20_Throws_Of_2_Die_And_Add_Values();
void Output_Avg(); //Calculates the average of the sum of the 20 rolls
int ArraySum[13]; // array for the numbers of 0-12 (13 total). Will ignore index array 0 and 1 later. array[13] = 12
int main()
{
Gen_20_Throws_Of_2_Die_And_Add_Values();
Output_Avg;
cin.get();
return 0;
}
void Gen_20_Throws_Of_2_Die_And_Add_Values()
{
srand(8193); //seed random number generator with 8193
int Dice_Throw_Number, Die1, Die2, Sum_Of_Two_Die;
for (int Dice_Throw_Number = 1; Dice_Throw_Number <= 20; Dice_Throw_Number++)
{
Die1 = (rand() % 6 + 1);
Die2 = (rand() % 6 + 1);
Sum_Of_Two_Die = Die1 + Die2;
ArraySum[Sum_Of_Two_Die] += 1;
}
}
void Output_Avg()
{
int Total_Of_20_Rolls, Average_Of_Rolls;
for (int i = 2; i <= 12; i++) //ignores index of 0 and 1
{
Total_Of_20_Rolls += ArraySum[i];
}
Average_Of_Rolls = Total_Of_20_Rolls / 20;
cout << "The average of 2 die rolled 20 times is " << Average_Of_Rolls;
}
Your code is a little confusing to follow, but I think I understand what's happening. Lets start with your Gen_20_Throws_Of_2_Die_And_Add_Values method.
int Dice_Throw_Number, Die1, Die2, Sum_Of_Two_Die;
for (int Dice_Throw_Number = 1; Dice_Throw_Number <= 20; Dice_Throw_Number++)
{
Die1 = (rand() % 6 + 1);
Die2 = (rand() % 6 + 1);
Sum_Of_Two_Die = Die1 + Die2;
ArraySum[Sum_Of_Two_Die] += 1;
}
You don't need to necessarily initialize int Dice_Throw_Number outside of the for loop. Feel free to make it inside the for loop. Also, I personally always find it easier to understand to start from zero and go up to only a < condition rather than a <=. So you'll have:
int Die1, Die2;
for (int Dice_Throw_Number = 0; Dice_Throw_Number < 20; Dice_Throw_Number++)
{
Die1 = (rand() % 6 + 1);
Die2 = (rand() % 6 + 1);
//increment position of sum by 1
ArraySum[Die1 + Die2] += 1;
}
Now in your Output_Average function, your logic is a lot off. You want to calculate what the average result was of throwing 2 die? Right now you're only adding how many times a certain total came up, not the total itself. So for example if you rolled 12 5 times, you'll adding 5 to the Total_Of_20_Rolls, not 60. That's easy to change, you just need to multiply.
int Total_Of_20_Rolls, Average_Of_Rolls;
for (int i = 2; i < 13; i++) //ignores index of 0 and 1
{
Total_Of_20_Rolls += ArraySum[i] * i;
}
Average_Of_Rolls = Total_Of_20_Rolls / 20;
cout << "The average of 2 die rolled 20 times is " << Average_Of_Rolls;
That should help you out!

Plotting Coordinates from a .txt File

I am finishing the second half of a two-part assignment on Conway's Game of Life. I created a function to generate a random array of 1s and 0s; the 1s represent a living cell and the zero an empty space. I created a separate function to inspect the neighborhood and make a count to determine how the game progresses. The rules: if a cell has 2 or 3 neighbors it survives, more than 3 or less than 2 it dies, and if an empty space has 3 neighbors it is "born". I even got help from you guys to wrap the screen using the modulus, but I am having trouble importing a .txt file to finish part two. Here is the code for part one:
#include <iostream> //includes input-output stream
#include <time.h> //includes time function
#include <iomanip> //includes setprecision function
#include <unistd.h> //includes sleep function
#include <fstream> //includes ifstream function
using namespace std; //using standard library
int master[24][79]; //initializes primary data array
int h = 24; // initializes height variable
int w = 79; // initialises width variable
int noOfCycles; //initialize cycles variable
void gen0 (int master[24][79]); // creates initial generation
void life(int master[24][79]); //initializes life function
void copy(int arrayX[24][79], int arrayY[24][79]); //initializes cycle update function
void print(int master[24][79]); //initializes print function
void fillPercent (int master[24][79]); //initializes percentage calculating function
int main() //initialize main function
{
cout << "How many cycles would you like to run?"; //prompt user to input cycles
cin >> noOfCycles; //user inputs cycles
srand (time(0)); //creates initial randomness
gen0(master); //creates initial generation
for (int k = 0; k <= noOfCycles; k++) //prints gen0 and cycles 50 times
{
print(master); //prints current array
fillPercent(master); //calculates/prints fill percentage
cout << " Cycle #" << k << " Author: Mikhail Morgan" << endl << endl;
//prints cycle number and signature
life(master); //calls life function
sleep(1); //delays output by 1 second
} //end width loop
} //end main function
void gen0 (int master[24][79])
{
for(int j = 0; j < h; j++) //height loop
{
for (int i = 0; i < w; i++) //width loop
master[j][i] = rand() % 2; //creates random generation 0
} //end height loop
}
void print(int master[24][79]) //Prints array
{
for(int j = 0; j < h; j++) //height loop
{
for(int i = 0; i < w; i++) //width loop
{
if(master[j][i] == 1)
cout << '0'; //print living cells as zeros
else
cout << ' '; //print dead cells as spaces
} // end width loop
cout << endl;
} // end height loop
} //end print function
void fillPercent (int master[24][79]) // calculates fill percentage
{
double fillNumber = 0; //resets every cycle
for (int i = 0; i < h; i++ ) //width loop
{
for (int j = 0; j < w; j++ ) //height loop
{
fillNumber += master[i][j]; //increments fill number
} //end height loop
} //end width loop
cout << endl << fixed << setprecision(2) << (fillNumber/(w*h))*100; //print percentage
} //end fillPercent function
void life (int master[24][79]) //generates/kills cells based on neighborhood
{
int temp[24][79]; //temporary array for manipulating data
copy (master, temp); //copy array onto temp
for(int j = 0; j < h; j++) //height loop
{
for (int i = 0; i < w; i++) //width loop
{
int count = 0; //intialize neighbor count variable
count = master[(j-1+h) % h][i % w] + //searches down
master[(j-1+h) % h][(i-1+w) % w] + //down left
master[j % h][(i-1+w) % w] + //left
master[(j+1+h) % h][(i-1+w) % w] + //up left
master[(j+1+h) % h][i % w] + //up
master[(j+1+h) % h][(i+1+w) % w] + //up right
master[j % h][(i+1+w) % w] + //right
master[(j-1+h) % h][(i+1+w) % w]; //down right
//cell dies if count falls below 2 or rises above 3
if(count < 2 || count > 3)
temp[j][i] = 0;
//cell stays alive if it has two neighbors
if(count == 2)
temp[j][i] = master[j][i];
//cell either stays alive or gets born if three neighbors
if(count == 3)
temp[j][i] = 1;
} //end width loop
}//end height loop
copy(temp, master); //copy temp back to main array
} //end life function
void copy(int arrayX[24][79], int arrayY[24][79]) //Copy machine
{
for(int j = 0; j < h; j++) //height loop
{
for(int i = 0; i < w; i++) //width loop
arrayY[j][i] = arrayX[j][i]; //temporary arrays used for copying
} //end height loop
} //end copy function
I know, using namespace std is lame af but it's mandated by my dinosaur-of-a-professor.
My problem is that for part two he wants us to stream the coordinates for the initial generation from a file that he supplied called GliderGun.txt. I am using Xcode and Im 99% sure that I have the file in the right location: I can see it in the right hand menu inside the same folder as main.cpp, and I can see the original copy in the Finder menu next to main.cpp. The first line is not a coordinate pair, it is the total number of coordinates in the file... Im not sure what the purpose of that is, and I suspect its whats messing me up. Here is the text from the file itself:
36
1 25
2 23
2 25
3 13
3 14
3 21
3 22
3 35
3 36
4 12
4 16
4 21
4 22
4 35
4 36
5 1
5 2
5 11
5 17
5 21
5 22
6 1
6 2
6 11
6 15
6 17
6 18
6 23
6 25
7 11
7 17
7 25
8 12
8 16
9 13
9 14
Here is the code for the function that replaces gen0. All I did was replace the call for gen0 with getPattern and altered the definition to look like this:
void getPattern (int master[24][79]) //generates Glider Gun
{
ifstream infile("GliderGun.txt", ios::in);
infile.open("GliderGun.txt", ios::in);//opens .txt file
int numOfCoordinates; // number of coordinate pairs
int i, j; // x, y coordinates
infile >> numOfCoordinates;
for (int a = 0; a < numOfCoordinates; a++)
{
infile >> i >> j;
master[j][i] = 1;
}
infile.close(); // closes .txt file
}
The console produces a blank 24x79 array. I sense that I have a looping problem but I dont know enough about how ifstream works to fix it. The coordinates are listed as (x y) or as defined by my other loops, (j i). I don't need the console to print the file I just need it to write 1s in the coordinates that are listed. Thanks for any advice!
Just from trying to reason about your code, there are two problems that arise from a drop-in replacement of getPattern where gen0 used to be:
You don't initialize any of the slots of your array to zero.
You're reading in the number of lines as an x-coordinate for one of the cells, all of the x-coordinates as y-coordinates, most of the y-coordinates as x-coordinates, and not reading the last y-coordinate.
There are two simple enough changes you can make to fix this.
Before reading from the file set the value in all cells of your 2D-array to 0.
Even if you're not doing anything with it, read in the number of lines from the file before looping over the coordinates.
Unrelated to your code, the text file does not need to be in the same directory as the source file, it needs to be in the same directory that the program is executed from. I don't know where the execution will be done from in XCode, but it might be worth testing directly from your computer's shell, if you know how.
Edit:
The part of getPattern where you read from the file could look something like this:
int num_coordinates; // This will be the number of coordinate pairs your file says it has.
int i, j; // These will be your x, y coordinates.
infile >> num_coordinates;
for (int loop_ct = 0; loop_ct < num_coordinates; loop_ct++) {
infile >> i >> j;
master[j][i] = 1;
}

2d array finished mine sweeper board program

Hello I am attempting to write a program and I seem to be stick. This program is in the end supposed to display two variants of a single 10 by 10 mine sweeper board. One of which where if there is a mine in that location it displays an asterisk(*) and if there is no mine it displays a period. The second variant also needs to display an asterisk where the mines are located on the board. But instead of a period it has to display the number of mines located 1 space away in any direction. I can't seem to think of how to easily write a program that will add up each of the mines located around each point. I also can't figure out why my program asks the initial question twice even if it meets the criteria for stopping the loop the first time around.
/*
Program: minesweeper(sort of)
The intention of this program is to display essentially two mine sweeper game boards one of which displays a *
where all of the mines would be located and a . where no mines are located. Then the second display
should display a * where all of the mines are and then display a number based on how many mines surround that space.
*/
#include <iostream>
#include <time.h>
#include <math.h>
using namespace std;
double get_probability();
int plant_mines(bool mineCells[10][10], double prob);
int print(bool mineCells[10][10]);
int count_mines(bool mineCells[10][10], int mineCounters[10][10]);
int main()
{
//used to hold true if there is a mine located at said location or false if there is no mine
bool mineCells[10][10];
//used to hold a value of -5 if the corrosponding value on mineCells is true and if the corrosponding value on
//minecells is false it should add up and hold the value of how many mines are surroudning it.
int mineCounters[10][10];
get_probability();
double prob = get_probability();
plant_mines(mineCells, prob);
print(mineCells);
int stop;
cin >> stop;
return 0;
}
//asks the user for a number between 0 and 1 to use as the probability of mines apearing laster on.
double get_probability()
{
double prob;
bool repeat;
do
{
cout << "Please enter a number between 0 and 1: ";
cin >> prob;
//should execute once asking the user for a input between 0 and 1 and if the input is not between those two it shoud
//then continue to repeat untill the permaiters set in the question are met.
if (prob >= 0 && prob <= 1)
{
break;
}
else
{
repeat = true;
}
}while (repeat = true);
return prob;
}
//takes the probability given by the user and then uses it to generate that percentage of mines on the field
int plant_mines(bool mineCells[10][10], double prob)
{
srand((unsigned int)time(NULL));
for (int count = 0; count < 10; count++)
{
for (int counter = 0; counter < 10; counter++)
{
//generates a random number between 0 and 1 and sets it equal to the variable random
double random = static_cast<double>(rand()) / RAND_MAX;
//is the variable random is less than or equal to the probability then the array is set to true meaning
//there is a mine located at that position
if (random <= prob)
{
mineCells[count][counter] = true;
}
//iff the random number is greater than the user input than there is no mine located at said position
else
{
mineCells[count][counter] = false;
}
}
}
return mineCells[10][10];
}
//Should count up the mines surronding the location to be output later on
//(the mines surrounding the location do include all mines 1 space diagonal, vertical and horizontal from said location)
int count_mines(bool mineCells[10][10], int mineCounters[10][10])
{
for (int count = 0; count < 10; count++)
{
for (int counter = 0; counter < 10; counter++)
{
if (mineCells[count][counter] == 1)
{
mineCounters[count][counter] = 0;
}
else
{
}
}
cout << endl;
}
return 0;
}
//displays a * where ever a mine is locate and a . where ever a mine is not located
int print(bool mineCells[10][10])
{
for (int count = 0; count < 10; count++)
{
for (int counter = 0; counter < 10; counter++)
{
if (mineCells[count][counter] == 1)
{
cout << "*";
}
else
{
cout << ".";
}
}
cout << endl;
}
return 0;
}

I tried coding my own simple moving average in C++

I want a function that works.
I believe my logic is correct, thus my (vector out of range error) must be coming from the lack of familiarity and using the code correctly.
I do know that there is long code out there for this fairly simple algorithm.
Please help if you can.
Basically, I take the length as the "moving" window as it loops through j to the end of the size of the vector. This vector is filled with stock prices.
If the length equaled 2 for a 2 day moving average for numbers 1 2 3 4. I should be able to output 1.5, 2.5, and 3.5. However, I get an out of range error.
The logic is shown in the code. If an expert could help me with this simple moving average function that I am trying to create that would be great! Thanks.
void Analysis::SMA()
{
double length;
cout << "Enter number days for your Simple Moving Average:" << endl;
cin >> length;
double sum = 0;
double a;
while (length >= 2){
vector<double>::iterator it;
for (int j = 0; j < close.size(); j++){
sum = vector1[length + j - 1] + vector1[length + j - 2];
a = sum / length;
vector2.push_back(a);
vector<double>::iterator g;
for (g = vector2.begin(); g != vector2.end(); ++g){
cout << "Your SMA: " << *g;
}
}
}
}
You don't need 3 loops to calculate a moving average over an array of data, you only need 1. You iterate over the array and keep track of the sum of the last n items, and then just adjust it for each new value, adding one value and removing one each time.
For example suppose you have a data set:
4 8 1 6 9
and you want to calculate a moving average with a window size of 3, then you keep a running total like this:
iteration add subtract running-total output average
0 4 - 4 - (not enough values yet)
1 8 - 12 -
2 1 - 13 13 / 3
3 6 4 15 15 / 3
4 9 8 16 16 / 3
Notice that we add each time, we start subtracting at iteration 3 (for a window size of 3) and start outputting the average at iteration 2 (window size minus 1).
So the code will be something like this:
double runningTotal = 0.0;
int windowSize = 3;
for(int i = 0; i < length; i++)
{
runningTotal += array[i]; // add
if(i >= windowSize)
runningTotal -= array[i - windowSize]; // subtract
if(i >= (windowSize - 1)) // output moving average
cout << "Your SMA: " << runningTotal / (double)windowSize;
}
You can adapt this to use your vector data structure.
Within your outermost while loop you never change length so your function will run forever.
Then, notice that if length is two and closes.size() is four, length + j - 1 will be 5, so my psychic debugging skills tell me your vector1 is too short and you index off the end.
This question has been answered but I thought I'd post complete code for people in the future seeking information.
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<double> vector1 { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
double length;
cout << "Enter number days for your Simple Moving Average:" << endl;
cin >> length;
double sum = 0;
int cnt = 0;
for (int i = 0; i < vector1.size(); i++) {
sum += vector1[i];
cnt++;
if (cnt >= length) {
cout << "Your SMA: " << (sum / (double) length) << endl;
sum -= vector1[cnt - length];
}
}
return 0;
}
This is slightly different than the answer. A 'cnt' variable in introduced to avoid an additional if statement.

Finding perimeter of a recursively modified square

I have a square of side length 1 . Now, after each second, each square of side L will break into four squares each of side L/2.
I need the compute the total perimeter of the resulting figure, where total perimeter is defined as the sum of lengths of all line segments in the resulting figure. For example, the total perimeter of the image on the left is 4L while that on the right is 6L - 4L from the regular square edges and 2L from the internal line segments.
My code:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define mod 1000000007
int main() {
int s;
cin>>s;
long long int ans=4;
for(int i=1;i<=s;i++)
ans+=1<<i;
ans=ans%mod;
cout<<ans<<endl;
return 0;
}
Since the final answer might not fit in a 64-bit signed integer, I am required to compute the answer modulo 1000000007.
For example, after 0 seconds, the length is 4.
After 1 second, the length is 6.
I am not getting the correct output. PLease help
Solve it recursively - let P(L, n) be the "perimeter" of the figure obtained after n iterations, starting with an LxL square. So, P(L, n+1) = 4*P(L/2,n) - 2*L. Also, since the perimeter is linear, P(L/2, n) = P(L, n)/2, giving you P(L,n) = 2*P(L,n-1) - 2*L. Substitute L=1 and run your loop.
int s;
cin>>s;
long long int ans=4;
for(int i=1;i<=s;i++)
{
ans = 2*(ans-1);
ans=ans%mod;
}
The perimeter after s seconds will be : 4+2(2^s-1)
So,
int main()
{
int s;
cout << "Enter Time: ";
cin >> s;
cout << "Perimeter = " << (4 + 2 * (pow( 2, s ) - 1));
}
You have an undivided square. When you split the square into 4 equal squares, you are essentially adding half of the initial perimeter. The outer walls of the original square are included as is in the new perimeter, and add to that the length of the 2 lines drawn inside it, the length of each of which is equal to the side of the square.
noOfsqaures = 1;
oldSide = 1; //one sqaure of side 1
oldPerimeter = 4*oldSide;
loop for the number of seconds
newPerimeter = oldPerimeter + 2*oldSide*noOfSquares
oldSide = oldSide/2; //for the next iteration
oldPermiter = newPermeter //for the next iteration
noOfSquares = noOfSquares*4;
o/p: 4(initial value) +
2 + 4 + 8 + 16 + 32 + ...
I think it would help you for coding. If you need I will give you code
for(int i=1;i<=s;i++)
{
ans+=1<<i;
}