Write some C++ code that simulates an 8-car race. In the code each car will advance, in each step, a distance determined by a random probability between 0 and 1.
• If the probability is greater than 0.8, the runway is free and will advance 83 meters
• if it is between 0.6 and 0.8, there is competition and it will advance 50 meters
• if it is between 0.4 and 0.6, you will have to slow down a bit and you will only go 30 meters
• if it is between 0.2 and 0.4, it needs a pit stop and will stop three steps
• if it is less than 0.2, they block his way and he will go back 10 meters
Each advance or retreat will be counted as a step, with the exception of the pit-stop, which is 3 steps. The one who travels 300 km in the fewest steps will win.
Generate a code that simulates car racing and prints the list of the top three finishers and the number of steps required to win. Each car must have a name.
For example, a result of the code could be:
Ganador: Mercedes, cantidad de pasos: 11852
2do puesto: McLaren, cantidad de pasos: 11984
3er puesto: Ferrari, cantidad de pasos: 12041
I tried to do it with a void function and this is what I got:
#include <iostream>
using namespace std;
void autos(int nombre);
void autos(int nombre, string _auto) {
int m = 0;
float v;
do {
v = (rand() % 9 + 1) / 10.0;
if (v > 0.8) {
m += 80;
nombre += 1;
}
else if (v > 0.6 && v < 0.8) {
m += 50;
nombre += 1;
}
else if (v > 0.4 && v < 0.6) {
m += 30;
nombre += 1;
}
else if (v > 0.2 && v < 0.4) {
nombre += 3;
}
else {
m -= 10;
nombre += 1;
}
} while (m < 300000);
cout << _auto << ", cantidad de pasos: " << nombre << "\n";
}
int main(){
srand((unsigned int)time(NULL));
int mercedes = 0, ford = 0, ferrari = 0, lamborghini = 0, audi = 0, porsche = 0, lexus = 0, toyota = 0;
string auto1 ="Mercedes", auto2 ="Ford", auto3 ="Ferrari", auto4 ="Lamborghini", auto5 ="Audi", auto6 ="Porsche", auto7 ="Lexus", auto8 ="Toyota";
autos(mercedes,auto1);
autos(ford,auto2);
autos(ferrari,auto3);
autos(lamborghini,auto4);
autos(audi,auto5);
autos(porsche,auto6);
autos(lexus,auto7);
autos(toyota,auto8);
}
However, in the output I have to order the number of steps. So what would be a method to sort random values? should I save them in a vector?
What if it happens to
v == 0.8
? In that case, given is not going to be fulfilledv > 0.8
and neither is it fulfilled thatv<0.8
... in the end it will enter the last oneelse
and the car will go back 10 steps. You should decide which of the two conditions gets the border value.On the other hand, the beauty of chains
if-else if
is that the code can only take one of the many paths that are available. That is, if the code reaches the first, it is because the initialelse if
condition has not been met .if
A possible way to leave the sequence of conditionals could be:
Note that now the sequence is cleaner
Another aspect of this function to improve is the issue of variable names. If it is no
m
longer a name that means absolutely nothing,nombre
it also gives the wrong idea about the information stored by this variable.Try that the different elements of the language (structures, functions, variables, aliases,...) have names that give an idea of the function they fulfill in the code. This practice will allow for more readable code and many bugs will find themselves.
And well, answering your questions:
Well, the first thing would be to devise a mechanism so that the function could return the number of steps that the car had to take to reach the goal.
Your function currently receives an integer that is useless
Note that
nombre
it is neither a pointer nor a reference, soautos
it will get a copy of the value or variable that you pass to it during the function call. Beingnombre
a copy of another value, changes you make to this variable will have no impact outside the function.On the other hand, since the final value of
nombres
depends only on the execution of said function and not on external conditions, your thing would be to use thereturn
.On the other hand, I don't see the need to call
cout
insideautos
. If we remove this call we no longer need the parameter either_auto
:On the other hand, the random number generator is not being treated correctly. The program is supposed to generate numbers in the range 0..1, but your program does not generate extreme values (it does not generate 0.0 or 1.0), so the probabilities returned by your program are not equiprobable:
v > 0.8
v > 0.6
v > 0.4
v > 0.2
else
The truth is that the real probability is not exactly this because
rand()
it does not generate numbers in a multiple range of 10. The range is given by a base 2, the operationrand() % 9
does not generate equiprobable results.You could redesign your formula, but it will almost be easier to use C++'s own random number generator. To make use of this mechanism you have to import the
random
.The initialization of the generator would look like this:
It seems a bit complicated but it is very simple:
seed
is a hardware based random number generator. This generator is the best at generating random numbers, but the drawback is that it is a bit slow. It is used to initialize a generator fasterrnd
is another random number generator. This generator is much faster at generating random sequences but it is less random , that is, its sequences are predictable from the initial seed. The initial seed is obtained fromseed
dist
is a utility that receives a random number and applies a transformation to it so that the distribution of the results is the desired one. In this casedist
it will return floating point numbers evenly distributed over the interval[0, 1)
. The libraryrandom
has other utilities to get different distributions, but the one you need right now is this one.Well, once the random number generation is initialized, all that remains is to use it:
All this applied to your function would leave it like this:
Ok, the function would already be fixed. Now you have to collect the results for each vehicle and sort the results. Indeed for this you need an array (or a list).
Since you now have 2 data for each vehicle
His thing would be to create a structure so that these values always go together:
If you don't want to create a structure you could also use a
std::pair
or astd::tuple
.You already have the structure, now you could create the array:
Note that since we have already given an initial value to
num_pasos
it is no longer necessary to explicitly give that value to each element of the array.Once the array is already created, we calculate the number of steps:
Now you have to sort the array. I am going to use the function
sort
:sort
I configure the function with a functionlambda
. If you don't like / won't be allowed to use these kind of functions, you can use an old-fashioned function:And that would be it, you would already have the array sorted in descending order. It only remains to present it:
You can see the code working here