SFML how to make various shapes move in random directions? - c++

I am having troubles in making shapes moving in random directions, with the code that i currently have they all move in the same direction and then change to another direction randomly.
Here is the code
for(int i = 0; i < 50; i++)
{
int randomMoveX = rand() % 2 + (-1);
int randomMoveY = rand() % 2 + (-1);
circleObjectArray[i].move(randomMoveX,randomMoveY);
while(randomMoveX == 0)
{
randomMoveX = rand() % 2 + (-1);
}
while(randomMoveY == 0)
{
randomMoveY = rand() % 2 + (-1);
}
cout << "randomMoveX: " << randomMoveX << endl;
cout << "randomMoveY: " << randomMoveY << endl;
}
How can i change my code to be able to do move them in random directions individually?
Thank you for your time :D

When you run your app, a seed is set for random as srand(1).
To use different value in rand you need to change the seed of random.
Then use the function srand and save it in a unsigned int to use different rand for different shape.

Related

How come rand is not producing random numbers in my code? [duplicate]

This question already has answers here:
Why do I always get the same sequence of random numbers with rand()?
(12 answers)
Closed 3 years ago.
I want to randomize variables a and b to output a random number 1 through 4 in the format of a,b. However, when I run my following code, the output is always the same no matter how many times I run it. For example, the output is always: 4,3 (same output shown 10 times.)
What did I do wrong here? Can someone point me in the right direction?
Thanks!
#include <iostream>
using namespace std;
int main()
{
int x;
int a, b;
a= rand() % 4 + 1;
b= rand() % 4 + 1;
x = 0;
while (x < 10) {
x++;
cout << a << "," << b << endl;
}
return 0;
}
You need to set the time seed first then call rand() otherwise you'll get always the same values:
int a, b; //store random number
std::srand(std::time(0)); // set the time seed
for(int i = 0; i != 10; ++i)
{
a = rand() % 4 + 1;
b = rand() % 4 + 1;
cout << a << "\t" << b << endl;
}
Don't forget to include <ctime> header.
What did I do wrong here? Can someone point me in the right direction?
Thanks!
You are setting a and b once and therefore they have the same value. To fix this, set them inside the loop to give them a new value each iteration:
while (x < 10) {
x++;
a = rand() % 4 + 1;
b = rand() % 4 + 1;
cout << a << "," << b << endl;
}
If you don't want the same values each time, you can call
srand(time(0)); // before the loop

Why isn't vector.clear() working while in a loop?

I am trying to create an application to calculate multiplicative persistence, like in this video: https://youtu.be/Wim9WJeDTHQ?t=197.
However my problem is that it does not appear that my vector is being cleared during iterations of the while loop. Which means the output produced is growing exponentially instead of working down to 0.
I am very new to coding c++ so any feedback would be appreciated.
std::vector<int> per;
int input;
int result;
int new_total = 1;
int loop_total;
std::cin >> input;
//Moving the user input into a vector
while (input > 0)
{
result = input % 10;
input = input / 10;
per.push_back(result);
}
//loops to multiply new sets of numbers together until "new_total" is 0
while (new_total > 0) {
for (int i = per.size() - 1; i >= 0; i--)
{
new_total = new_total * per[i];
}
per.clear();
std::cout << "\n" << new_total << "\n";
loop_total = new_total;
while (loop_total > 0)
{
result = loop_total % 10;
loop_total = loop_total / 10;
per.push_back(result);
}
}
I expected for the vector to be cleared each time so that the new sets of numbers were moved into the vector to be multiplied.
However the previous set of numbers appeared to remain present in the vector.
Thanks for all the help everyone. The solution to my problem was fixed by setting new_total=1; at the beginning of the while loop which makes sense as before new_value was being continually multiplied into.
Thanks for all the help :)

how to write a loop that sorts numbers by odd, even, and zero from random numbers

I'm supposed to write a program in C++ that will generate a random number for each type of loop a random amount of times a sort the numbers by odd even and zero
what i have so far will run as many times as the while limit and by default always add to the odd value, any idea what's wrong with my code?
int main()
{
//establishes variables needed
int whilelimit, whilevalue, whileodd = 0, whileeven = 0, whilezero = 0,
forlimit, forodd = 0, foreven = 0, forzero = 0, forvalue, dowhilelimit,
dowhilevalue, dowhileodd = 0, dowhileeven = 0, dowhilezero = 0;
srand(time(NULL));
//while loop
whilelimit = rand() % 18 + 2;
whilevalue = rand() % 100 + 0;
while (whilelimit > 0)
{
// determine if the value is even odd or zero
if (whilevalue != 0)
{
if (whilevalue / 2 != 0 )
{
whileodd++;
}
else if (whilevalue / 2 == 0)
{
whileeven++;
}
}
else
{
whilezero++;
}
whilelimit--;
}
cout << "Zero: " << whilezero << "even: " << whileeven << "odd: " <<
whileodd << endl;
//for loop
//do while loop
system("pause");
return 0;
}
Use a modulus "%" as your check for odd or even instead of "/". The modulus give you the remainder of a division. That's what you're checking for 0 with to determine if a value is divisible by another number. Also this is a hw question. Go back into the chapter that it covers and find where it covers the modulus and read up on it.
as #epascarello mentioned, your whilevalue never changes. Try moving it into the loop:
whilelimit = rand() % 18 + 2;
while (whilelimit > 0)
{
whilevalue = rand() % 100 + 0;
//other code
}
It should be % not /
Currently you are just adding to odd because it is seeing if the number is divisible by 2 and not equal to zero which is true for most numbers.
while (whilelimit > 0)
{
// determine if the value is even odd or zero
if (whilevalue != 0)
{
if (whilevalue % 2 != 0 )
{
whileodd++;
}
else if (whilevalue % 2 == 0)
{
whileeven++;
}
}
else
{
whilezero++;
}
whilelimit--;
}
It's good to seed the rand() function with the current time using srand(). Also make sure to change the whileValue everytime.
srand(time(NULL));
int whileLimit = (rand() % 18) + 2;
unsigned numZeros = 0, numEvens = 0, numOdds = 0;
while(whileLimit-- > 0) {
int whileValue = rand() % 100;
// Assuming zero is not an even number
if (!whileValue) {
++numZeros;
continue;
}
++((whileValue % 2) ? numOdds : numEvens);
}
std::cout << "\n0s: " << numZeros << " Evens: " << numEvens << " Odds: " << numOdds << std::endl;

Checking an array for existing values in C++

I've got this project I'm working on and it is an rpg game running in the cmd. The player navigates his character through the keyboard and fights enemies to level up and so on. I'm using a 2D array as a grid/map and in the demo version everything is working OK.
Problem: Now, in the more advanced version, I have a class which is used to load game/start new game. The function, that starts a new game, basicly creates .txt save files in which the information is stored. The problem is in the function that generates an enemy list. The enemy characteristics that are being generated, and where the problem is, are the X and Y coordinates. Here is a little bit of code showing the process:
void enemyGenerator(int level)
/* Declare the random generator */
std::default_random_engine generator((unsigned)time(0));
std::uniform_int_distribution<int> coordsX(1, 28); //There are 30 rows, from which the first and the last are border
std::uniform_int_distribution<int> coordsY(1, 48); //50 columns; first and last are border
/* Declare some variables */
int x, y;
bool ready = "False";
/* Check what level is demanded, for example level 1 */
if (level == 1)
{
while(true)
{
//Generate X and Y
x = coordsX(generator);
y = coordsY(generator);
//Now where the problem appears to be
//There will be 600 enemies = 1200 coordinates, so I have declared an array in the .h file
//Called coordinates[1200] = {}; now I want to check it bottom to top if
//the newly generated coordinates are already existing, so:
for (int i = 0; i < 1200; i += 2) //1200 = array size; += 2, because we're checking x & y at once
{
if (x != coordinates[i] && y != coordinates[i + 1] && x + y != 2) //x + y can't be 2, because this is where the player starts (1, 1)
{
if (i == 1198) //If these are the last x and y in the array
{
ready = "True";
break;
//Break the for loop with status ready
}
else
{
continue;
//If it isn't the end of the array simply continue checking
}
}
else
{
ready = "False";
break;
//If the x and y match with the ones in the array, then break with status not ready
}
}
if (ready)
{
break;
//If status is ready then break the loop and assign the rest of the stats
}
else
{
continue;
//If status is not ready then continue generating random values
}
}
//Here I define the values of the stats in private variables of the class
eX = x;
eY = y;
eLVL = 1;
//etc...
}
This is the generating code. And here is how I use it:
void newGame()
....
//I've reached to the point where I want to deploy for example 10 enemies of level 1
for (int i = 0; i < 10; i++)
{
enemyGenerator(1);
//I have an already defined fileWriter (std::fstream; std::ios::out)
fileWriter << eX << " " << eY << " " << eLVL; //<< " " etc...
}
....
Everything seems logical to me, the only illogical thing is that it is not working. The output in enemyList.txt I get is for example 3 5 1 (other stats) 3 5 1 (other stats) 3 5 1 (other stats), you get it.
Question: Can you spot any error? Can you show me the right way? If more of the code is required I can even send you the source file, just for the sake of curing my headache.
The problem there is with your random generator.
You are setting the seed of the generator everytime enemyGenerator() is called with the current time. But since you call enemyGenerator multiple times in the same fraction of a second, the time value is the same, hence the random generator seed is the same everytime, which will give you the same random pattern each successive call.
Either use the same generator for all the calls
...
std::default_random_engine random_generator((unsigned)time(0));
//I've reached to the point where I want to deploy for example 10 enemies of level 1
for (int i = 0; i < 10; i++)
{
enemyGenerator(random_generator, 1);
//I have an already defined fileWriter (std::fstream; std::ios::out)
fileWriter << eX << " " << eY << " " << eLVL; //<< " " etc...
}
....
with the enemyGenerator function is defined as
void enemyGenerator(std::default_random_engine& generator, int level)
or seed your generator with a different value each time.
Edit:
Well it seems it isn't the cause of your problem but you should still consider what I wrote.

Vector cannot be overwritten

I'm trying to write a program for university. The goal of the program is to make a nurse schedule for a hospital. However, i'm really stuck for the moment. Below you can find one function of the program.
The input for the function is a roster which consists of the shift each nurse has to perform on each day. In this example, we have 32 rows (32 nurses) and 28 columns (representing 28 days). Each cell contains a number from 0 to 6, indicating a day off (0) or a certain shift (1 to 6).
The function should calculate for each day, how many nurses are scheduled for a certain shift. For example, on the first day, there are 8 nurses which perform shift 2, 6 shift 3 and so forth. The output of the function is a double vector.
I think the function is mostly correct but when I call it for different rosters the program always gives the first roster gave.
void calculate_nbr_nurses_per_shift(vector<vector<int>> roster1)
{
for (int i = 0; i < get_nbr_days(); i++)
{
vector<int> nurses_per_shift;
int nbr_nurses_free = 0;
int nbr_nurses_shift1 = 0;
int nbr_nurses_shift2 = 0;
int nbr_nurses_shift3 = 0;
int nbr_nurses_shift4 = 0;
int nbr_nurses_shift5 = 0;
int nbr_nurses_shift6 = 0;
for (int j = 0; j < get_nbr_nurses(); j++)
{
if (roster1[j][i] == 0)
nbr_nurses_free += 1;
if (roster1[j][i] == 1)
nbr_nurses_shift1 += 1;
if (roster1[j][i] == 2)
nbr_nurses_shift2 += 1;
if (roster1[j][i] == 3)
nbr_nurses_shift3 += 1;
if (roster1[j][i] == 4)
nbr_nurses_shift4 += 1;
if (roster1[j][i] == 5)
nbr_nurses_shift5 += 1;
if (roster1[j][i] == 6)
nbr_nurses_shift6 += 1;
}
nurses_per_shift.push_back(nbr_nurses_shift1);
nurses_per_shift.push_back(nbr_nurses_shift2);
nurses_per_shift.push_back(nbr_nurses_shift3);
nurses_per_shift.push_back(nbr_nurses_shift4);
nurses_per_shift.push_back(nbr_nurses_shift5);
nurses_per_shift.push_back(nbr_nurses_shift6);
nurses_per_shift.push_back(nbr_nurses_free);
nbr_nurses_per_shift_per_day.push_back(nurses_per_shift);
}
}
Here you can see the program:
Get_shift_assignment() and schedule_LD are other rosters.
void test_schedule_function()
{
calculate_nbr_nurses_per_shift(schedule_LD);
calculate_nbr_nurses_per_shift(get_shift_assignment());
calculate_coverage_deficit();
}
One more function you need to fully understand the problem is this one:
void calculate_coverage_deficit()
{
int deficit = 0;
for (int i = 0; i < get_nbr_days(); i++)
{
vector<int> deficit_day;
for (int j = 0; j < get_nbr_shifts(); j++)
{
deficit = get_staffing_requirements()[j] - nbr_nurses_per_shift_per_day[i][j];
deficit_day.push_back(deficit);
}
nurses_deficit.push_back(deficit_day);
}
cout << "Day 1, shift 1: there is a deficit of " << nurses_deficit[0][0] << " nurses." << endl;
cout << "Day 1, shift 2: there is a deficit of " << nurses_deficit[0][1] << " nurses." << endl;
cout << "Day 1, shift 3: there is a deficit of " << nurses_deficit[0][2] << " nurses." << endl;
cout << "Day 1, shift 4: there is a deficit of " << nurses_deficit[0][3] << " nurses." << endl;
}
So the problem is that each time I run this program it always gives me the deficits of the first roster. In this case, this is Schedule_LD. When I first run the function with input roster get_shift_assignment() than he gives me the deficits for that roster.
Apparently the nbr_nurses_per_shift_per_day[][] vector is not overwritten the second time I run the function and I don't know how to fix this... Any help would be greatly appreciated.
Let me try to summarize the comments:
By using global variables to return values from your functions it is very likely, that you forgot to remove older results from one or more of your global variables before calling functions again.
To get around this, return your results from the function instead.
Ex:
vector<vector<int>> calculate_nbr_nurses_per_shift(vector<vector<int>> roster1)
{
vector<int> nbr_nurses_per_shift_per_day; // Create the result vector
... // Do your calculations
return nbr_nurses_per_shift_per_day;
}
or if you do not want to return a vector:
void calculate_nbr_nurses_per_shift(vector<vector<int>> roster1, vector<vector<int>> nbr_nurses_per_shift_per_day)
{
... // Do your calculations
}
But clearly, the first variant is a lot less error-prone (in the second example you can forget to clear nbr_of_nurses again) and most compilers will optimize the return nbr_nurses_per_shift_per_day so the whole vector does not get copied.
The second possible issue is that ´get_nbr_days()´ might return numbers that are larger or smaller than the actual size of your vector. To work around this, use either the size() method of vector or use iterators instead.
Your first function would then look like this:
vector<vector<int>> calculate_nbr_nurses_per_shift(vector<vector<int>> roster1)
{
vector<vector<int>> nbr_nurses_per_shift_per_day;
for (vector<vector<int>>::iterator shiftsOnDay = roster1.begin(); shiftsOnDay != roster1.end(); ++shiftsOnDay)
{
vector<int> nurses_per_shift(6, 0); // Create vector with 6 elements initialized to 0
for (vector<int>::iterator shift = shiftsOnDay->begin(); shift != shiftsOnDay->end(); ++shift)
{
if (*shift == 0)
nurses_per_shift[5]++;
else
nurses_per_shift[*shift - 1]++; // This code relies on shift only containing meaningful values
}
nbr_nurses_per_shift_per_day.push_back(nurses_per_shift);
}
return nbr_nurses_per_shift_per_day;
}