I am a C++ amateur and I am planning to create a special program for a future competition.
To understand I'll provide all the details: I have been playing for a long time the video game called Team Fortress 2 which features an unique crafting and trading system.
My competition idea is to craft a hat by gathering the necessary materials from the participants and then giving it by chance to one lucky player.
To craft a random hat you need to combine 3 refined metals. In order to make a refined metal you need to combine 3 reclaimed metals. Lastly, a reclaimed metal is created by combining 3 scrap metals. Each player is allowed only once to give 1 scrap, 2 scraps or 1 reclaimed.
As seen in the diagram, players that give 1 scrap metal have a 3,7% chance win chance. Players that give 2 scraps have a 7,4% win chance and players that give 1 reclaimed have a 11,1% win chance. Depending on the quantity each player provides, the total number of participants will always be between and including 9 and 27. This adds up to 99,9%.
I was thinking of a more simplistic approach in which I create a double vector “player[28]” to include all the players and then input each of their percentages since I will know how many there will be and how much they will give. After that, a function should take all the players and return a winner based on their percentages (the higher the %, the higher the chance). I don’t know if I am doing it right so I would appreciate a code example.
So all you want is a function that takes an array with some doubles, that add up to 100 and choose one in such way that their values represent chances to pick them?
That's really simple:
1 2 3 4 5 6 7 8
int choose_random( double arr[], double random ) {
int i = 0;
while( random > arr[i] ) {
random -= arr[i];
i++;
}
return i;
}
Notes:
It doesn't matter how long is the array you pass to this function is, as long as values in it add up to random (which is in your case at most 100).
I've added the argument "random" so that instead of rand() you can use something fancy, like http://www.random.org/
Also, note that there is no reason to use percents. You need 27 items, a player can give you 1, 2 or 3. If you fill an array with the number each player gave, randomize a number from 1 to 27 and replace the doubles in my snippet with ints, you'd avoid that little imprecision. Now there is a slight chance that you'll roll 100 and call this function on an array that sums up to 99,9 .
Thank you for the help but I was looking for something a bit different. Let me give you another clear example of what I want to do: I have a key which opens a box that contains only one of 5 known objects. Object 1 has 30% chance, object 2 has 20% chance, object 3 has 20% chance, object 4 has 15% chance and object 5 has 15% chance. The lesser the chance, the more valuable is the object. Each object percentage is a part of the same 100% that all add up to.
My question is how can I create the chance algorithm so the pick will be based on the respective object percentage (the higher, the more likely to pick)? Is it possible with a mathematical formula or still using a random number?
I would recommend using rand()%100, and using if/switch statements to "zone" each item. Make sure the less valuable items are closer to 0 than 100, as it may tend to lean towards those items.
#include <cstdlib>
#include <ctime>
#include <iostream>
int choose_random( int arr[], int random ) {//changed to avoid imprecision
int i = 0;
while( random > arr[i] ) {
random -= arr[i];
i++;
}
return i;
}
int main(){
constint SUM = 9;
int arr[] = {4, 2, 3};//adds up to SUM
srand( time(0) );
int res[3] = {0};
for( int i = 0; i < 100; i++ ){
int random = rand()%SUM + 1;//a random number from 1 to 10
res[ choose_random( arr, random ) ]++;//count how many times each number was rolled
}
for( int i = 0; i < 3; i++ )
std::cout << i << " was rolled " << res[i] << " times, with a probability of " << arr[i]*100.0/SUM << "%\n";
std::cin.get();
}
Again I thank you but the program shows all the numbers with a weird percentage that don't add up to 100%.
I know how many players there are, I know the percentage each player will be based on the number of materials he will give me (1- 3,7%, 2- 7,4%, 3- 11,1%). I might not have understood your previous code, hamsterman, but let me make things straight by including one more example of how I intend to run the competition:
Player1 gives 1 scrap, his chance of win is 3,7% (Total: 1/27 scraps, 3,7%/99,9%)
Player2 gives 2 scraps, his chance of win is 7,4% (Total: 3/27 scraps, 11,1%/99,9%)
Player3 gives 3 scraps, his chance of win is 11,1% (Total: 6/27 scraps, 22,2%/99,9%)
Player4 gives 3 scraps, his chance of win is 11,1% (Total: 9/27 scraps, 33,3%/99,9%)
Player5 gives 2 scraps, his chance of win is 7,4% (Total: 11/27 scraps, 40,7%/99,9%)
Player6 gives 1 scrap, his chance of win is 3,7% (Total: 12/27 scraps, 44,4%/99,9%)
Player7 gives 1 scrap, his chance of win is 3,7% (Total: 13/27 scraps, 48,1%/99,9%)
Player8 gives 2 scraps, his chance of win is 7,4% (Total: 15/27 scraps, 55,5%/99,9%)
Player9 gives 3 scraps, his chance of win is 11,1% (Total: 18/27 scraps, 66,6%/99,9%)
Player10 gives 1 scrap, his chance of win is 3,7% (Total: 19/27 scraps, 70,3%/99,9%)
Player11 gives 1 scrap, his chance of win is 3,7% (Total: 20/27 scraps, 74,0%/99,9%)
Player12 gives 1 scrap, his chance of win is 3,7% (Total: 21/27 scraps, 77,7%/99,9%)
Player13 gives 2 scraps, his chance of win is 7,4% (Total: 23/27 scraps, 85,1%/99,9%)
Player14 gives 2 scraps, his chance of win is 7,4% (Total: 25/27 scraps, 92,5%/99,9%)
Player15 gives 2 scraps, his chance of win is 7,4% (Total: 27/27 scraps, 99,9%/99,9%)
So 15 players will participate in this competition and the amount of materials and chance for each is known. All I need to do now is to input the data into the program and have it return me a single player based on the chances known. Nothing more.
I hope you're understood my intent and thanks again for all your help so far.
0 was rolled 49 times, with a probability of 44.4444%
1 was rolled 27 times, with a probability of 22.2222%
2 was rolled 24 times, with a probability of 33.3333%
How does that not add up to 100% ?
The code chooses a random element 100 times to show that the probabilities to roll each number is corresponding to that numbers value.
#include <cstdlib>
#include <ctime>
#include <iostream>
int choose_random( int arr[], int random ) {
int i = 0;
while( random > arr[i] ) {
random -= arr[i];
i++;
}
return i;
}
int main(){
//arr is an array containing how much each player gave.
//I used the values from your example.
//It doesn't matter how many values there are as long as they add up to 27.
int arr[] = {1, 2, 3, 3, 2, 1, 1, 2, 3, 1, 1, 1, 2, 2, 2};
srand( time(0) );
std::cout << "Player " << choose_random( arr, rand()%27+1 ) +1 << " wins a hat!";
std::cin.get();
}
Hey I'm pretty new and I just wanted to check and make sure its ok if I copy your code their hamsterman. Its just to mess around with. Its right around where my max understanding of c++ is at and I think if I messed around with it a bit it might make my understanding or arrays and random numbers better
For some reason when I compiled your previous code it showed 22,22% on each of the 3 players, that's why it didn't add up. Now it works.
I can't thank you enough, hamsterman. I owe you a hat or two if I ever encounter you in Team Fortress 2.
Also, it's ok to use the code, Menne31.