- Home /
Randomize values without exceeding a value?
Hi guys, I have some time thinking the following, I want to make a button to randomize whole values of some skills. The question is that I have 10 points to distribute between 4 skills, the idea is to have selected randoms numbers without exceeding 10 points.
I had thought in this
public int startPts = 10, usedPts = 0;
public int skill1 = 0, skill2 = 0, skill3 = 0, skill4 = 0;
public void ButtonRandom(){
startPts = 10;
usedPts = 0;
skill1 = Random.Range( 1, 10 );
usedPts += skill1;
skill2 = Random.Range( 1, usedPts );
usedPts += skill2;
skill3 = Random.Range( 1, usedPts );
usedPts += skill3;
skill4 = Random.Range( 1, usedPts );
usedPts += skill4;
startPts = startPts - usedPts;
}
I also try with several conditionals and repetitive methods, but I do not get the desired result. Since sometimes it surpasses the 10 points, leaves points without using or only changes the first 2 values when I put the conditions.
Thank you, guys.
I think you should use Random.Range(1, 10 - usedPts), since this gives you a number between one and the points you have left, ins$$anonymous$$d of the points you have used..
Answer by oStaiko · Mar 01, 2017 at 06:27 PM
I did something similar to this in my current project, but it used floats instead of whole numbers. Basically what you need is to factorize them numbers (I think that's what its called idrk), something where you generate all numbers randomly, and then adjust the total to be 10. It's easy with float, not as easy with ints!
For floats, it looks like...
sum = num1 + num2 + num3 + num4;
factor = 10 / sum;
num1 *= fac;
//so on
Again, this works perfect for floats, the new sum would = 10. You can apply this principle and get your stats as floats, and then just round. It wont always be 10, but you could just add 1 to a random spot.
Another method if you want random ints, would be to just pick a random stat and add 1 to it, 10 times!
int[] skills = new int[4];
int max = 10;
int sum = 0;
while (sum < 10)
{
if (skills[Random.Range(0,4)] >= max)
continue;
skills[Random.Range(0,4)]++;
sum++;
}
skill1 = skills[0];
//So on...
I would recommend keeping your skills as an array, it makes it a lot easier to loop through them, and keeps your code cleaner!
This is very similar to the desired result, thank you man.
This Helps me a lot with my game too! But is there a way i can do this while all of my skills start at a base value of one?
If its the first method, just make the sum smaller than the actual sum by the number of stats, complete it as normal, and then add 1 to the end results. Ex. Set sum to 15 if you have 5 stats and want actual sum to be 20, then add 1 to each of the 5 to reach the 20.
For the second method, just add 1 to each of the stats before, and then keep the sum the same.
Answer by eldruz · Mar 01, 2017 at 02:56 PM
From quickly looking at your code, it appears you don't specify the correct range in your random function.
public int startPts = 10, usedPts = 0;
public int skill1 = 0, skill2 = 0, skill3 = 0, skill4 = 0;
public void ButtonRandom(){
startPts = 10;
usedPts = 0;
skill1 = Random.Range( 1, startPts );
usedPts += skill1;
skill2 = Random.Range( 1, startPts - usedPts );
usedPts += skill2;
skill3 = Random.Range( 1, startPts - usedPts );
usedPts += skill3;
skill4 = startPts - usedPts;
usedPts += skill4;
startPts = startPts - usedPts;
}
I did not test it but with this you should not go over your start points, and use all of the remaining points in the fourth skill.
I think this still needs a bit more work to produce desired results.
Random.Range with integers never produces the latter argument (only values smaller than it) and that should be taken into account.
With this code the highest value a skill can get is 9 for Skill1, 8 for Skill2, 7 for skill3 etc. The values could for example be put into a temporary list and picked from there from a random index for each skill so each skill gets an equal chance of getting the highest possible value.
Also if skill1 gets 9 as its value, there's not enough points to give 1 point for each of the remaining skills. So startPts should probably be reduced by the number of skills to begin with.
The issues you mention are definitely spot on, there's a lot that could be done to the repartition of the values on the different skills. These are definitely areas op needs to ponder.
Lacking more information about the intent of op I opted to just correct the matter at hand.
Answer by nlbi21 · Mar 04, 2017 at 09:09 AM
I did it this way, in case someone else has the doubt. :D
public int startPts = 10, usedPts = 0;
public int skill1 = 0, skill2 = 0, skill3 = 0, skill4 = 0;
public void ButtonRandom(){
startPts = 10;
usedPts = 0;
int[] skills = new int[4];
for (int i = 0; i < 4; i++){
skills[i] = 1;
}
for (int i = 0; i < (startPts - skills.Length); i++) {
int tempRandom = Random.Range (0, 4);
skills [tempRandom]++;
}
for (int i = 0; i < 4; i++){
usedPts += skills[i];
}
startPts = startPts - usedPts;
skill1 = skills[0];
skill2 = skills[1];
skill3 = skills[2];
skill4 = skills[3];
}
Hi!
A bit late to the party, but I'm writing a loot system in this moment in Unity. Right now I have a button that instantiate a random item with random stats. I have a similar function built like yours.
The thing is that every iteration in the loop, it's adding one point to a random index in the array, right? The problem I have with this is that it's not really randomizing the stats. It's still based on probability. Like if you roll a dice 1000 times, the result for how many times you rolled 1-6 is going to be pretty much the same on each value, leaving my items with similar values on all attributes. Is this loop doing the same? Let's say you have 1000 points to distribute to all of your skills, wouldn't it distribute them pretty equally (plus-$$anonymous$$us a few values)?
Your answer
Follow this Question
Related Questions
How to make random number generation more random? 2 Answers
Random.Range is not changing? 1 Answer
How to know what random number is chosen 2 Answers
How can I do random choices 1 Answer
An array of bools with random true and false elements 2 Answers