PDA

View Full Version : How to get random, yet weighted numbers?



doomtoo
August 1st, 2009, 04:18 PM
I have an inventory system for a game, btu want to return a random, but weighted number.

So for instance:

1. Regular sword; Rarity:1
2. Super sword; Rarity:5
3. Super sword good condition; Rarity:20
4: Super Mega Death sword; Rarity:100

5. Regular armor; Rarity:1
6. Super armor; Rarity:5
7. Super armorgood condition; Rarity:20
8: Super Mega Death armor; Rarity:100

I want to find a random item, but want it more likely to find things that have a lower rarity.

Is there an easy way to do this, or would I have to try to make my own random number generator?

flyingmonkey456
August 1st, 2009, 04:26 PM
for each object, generate a random number with the rarity being it's range. if the number chosen is, say, 1 then that item will be found. if it is any other number, it won't. if you want multiple items to be found at once, you would just run through this for every object. if you want only one object to be found at once, you can either add every object that is found to an array and choose a random one or simply stop checking for objects after one object has been found. the second one makes objects that are checked last much less likely to be found because their being found depends on every object before them also not being found, and their rarity. the first option works much better.

doomtoo
August 1st, 2009, 04:44 PM
Cool, thanks, that sounds like a good strategy!

TOdorus
August 1st, 2009, 08:23 PM
I would do something similair to that first suggestion. I like to be able to exactly define the chance to get something.

1. Regular sword; chance: 75
2. Super sword; chance: 20
3. Super sword good condition; chance: 5

Math.round(Math.random() * 1000)

if the number is:
[0-75] Give regular sword
[76-95] Give super sword
[96-100] Give super sword good condition
[101-1000] Give nothing

Gnoll
August 1st, 2009, 08:59 PM
Yes I would also do what Todorus suggests, that is much simpler and easy to manage. :D

Gnoll

flyingmonkey456
August 1st, 2009, 09:42 PM
@TO & Gnoll

yeah, that was the way i used to do it but multiple finds require running through it several times. it's about the same amount of code for each one, it just depends on what you need.

TOdorus
August 2nd, 2009, 12:00 AM
The amount of code isn't the quality I measure with. The problem with doing a chance check per itemtype is that: you need through loop through all itemtypes per find (thus using more cpu) and that the first items in the list have a higher chance of bieng found.

For example let's use doomtoo's list. I removed the 1 rarity items because they would have a 1/1 change to be found. The problem is, that for an item to be found all preceding items need to be "not found".

2. Super sword; Rarity:5; P = 1/5
3. Super sword good condition; Rarity:20; P = (4/5) * (1/20)
4: Super Mega Death sword; Rarity:100; P = (4/5) * (19/20) * (1/100)
6. Super armor; Rarity:5; P = (4/5) * (19/20) * (99/100) * (1/5)
7. Super armorgood condition; Rarity:20; P = (4/5) * (19/20) * (99/100) * (4/5) * (1/20)
8: Super Mega Death armor; Rarity:100; P = (4/5) * (19/20) * (99/100) * (4/5) * (19/20) * (1/100)

So despite of objects having the same rarity, there is a different chance that they will be found, because it is dependent on the previous objects' rarity values. This makes it a very hard system to control.

It actually is a pretty good idea for yes/no checks. Say someone has 20 skills in melee attack and his opponent 5 skills in melee defense. Then you could use it to see if there was a succesfull block:



function succesfullBlock(ATTACKSKILL:int, DEFENSESKILL:int):Boolean{
var Outcome:Number = Math.random() * ATTACKSKILL //since we're checking for a block, you use the skill you need to beat
if(Outcome <= DEFENSESKILL){
return(true)
} else {
return(false)
}
}

flyingmonkey456
August 2nd, 2009, 02:25 AM
The amount of code isn't the quality I measure with. The problem with doing a chance check per itemtype is that: you need through loop through all itemtypes per find (thus using more cpu) and that the first items in the list have a higher chance of bieng found.

For example let's use doomtoo's list. I removed the 1 rarity items because they would have a 1/1 change to be found. The problem is, that for an item to be found all preceding items need to be "not found".

2. Super sword; Rarity:5; P = 1/5
3. Super sword good condition; Rarity:20; P = (4/5) * (1/20)
4: Super Mega Death sword; Rarity:100; P = (4/5) * (19/20) * (1/100)
6. Super armor; Rarity:5; P = (4/5) * (19/20) * (99/100) * (1/5)
7. Super armorgood condition; Rarity:20; P = (4/5) * (19/20) * (99/100) * (4/5) * (1/20)
8: Super Mega Death armor; Rarity:100; P = (4/5) * (19/20) * (99/100) * (4/5) * (19/20) * (1/100)

So despite of objects having the same rarity, there is a different chance that they will be found, because it is dependent on the previous objects' rarity values. This makes it a very hard system to control.

It actually is a pretty good idea for yes/no checks. Say someone has 20 skills in melee attack and his opponent 5 skills in melee defense. Then you could use it to see if there was a succesfull block:



function succesfullBlock(ATTACKSKILL:int, DEFENSESKILL:int):Boolean{
var Outcome:Number = Math.random() * ATTACKSKILL //since we're checking for a block, you use the skill you need to beat
if(Outcome <= DEFENSESKILL){
return(true)
} else {
return(false)
}
}


i've already argued this with gnoll, each one has different advantages and disadvantages. as i said in my previous message, it depends on what you need :)

TOdorus
August 2nd, 2009, 08:33 AM
i've already argued this with gnoll, each one has different advantages and disadvantages. as i said in my previous message, it depends on what you need :)

But I disagree. Using that you have argued about this earlier as an argument is a sophism, unless you can present the arguments you made then. The situation you pose in your unedited post (multiple items), shows the same disadvantages: more CPU, dependence on previous items. It also shows the inability of the method to find multiple items of the same kind.


for only one item at a time, your code is the best. for multiple items, mine is the best.
as i said in my previous message, it depends on what you need :)

CPU time:
Say 3 items are found. By looping through itemtypes you can have 3 (the first three items are found) to "the amount of items on the list" (< 3 items are found) iterations. By using a probability distribution it always has 3.

Similair finds:
Since looping through itemtypes continues to the next itemtype regardless if an item is found or not, you can never find two items of the same kind. To use a wellknown probability visualization: you're not putting the marbles back in the bag.

The probability distribution can actually be adjusted to do the same. Add up all the possibilities and then make your pick. Remove the possible outcomes that would give the item and repeat.

first iteration
1. Regular sword; chance: 75
2. Super sword; chance: 20
3. Super sword good condition; chance: 5
4. Nothing; chance: 900

Math.round(Math.random() * (75+20+5+900))

if the number is:
[0-75] Give regular sword
[76-95] Give super sword
[96-100] Give super sword good condition
[101-1000] Give nothing

Say the Super sword is found.

second iteration:
1. Regular sword; chance: 75
2. Super sword; chance: 0
3. Super sword good condition; chance: 5
4. Nothing; chance: 900

Math.round(Math.random() * (75+0+5+900)

if the number is:
[0-75] Give regular sword
[75-95] Give super sword good condition
[96-980] Give nothing

Dependence on previous items:
With multiple finds the chance of finding nothing is the same as with one find. I find this very counterintuitive.


Really to each his own. I'm not trying to talk you out of doing it that way, but by claiming that the method has certain advantages is misinforming doomtoo.

flyingmonkey456
August 2nd, 2009, 10:55 AM
if you want multiple items to be found, you just loop through each individual item's code, say, 10 times if you want a maximum of 10 finds. in yours, you would have to run through the entire thing several times and any object could be gotten more than once, even the super mega death armor. in mine, you can set a maximum number of finds for each individual item.

btw, i wasn't using my previous argument as an argument, i was stating it as a fact. oh, and what's the significance of my post being unedited?

TOdorus
August 2nd, 2009, 12:08 PM
if you want multiple items to be found, you just loop through each individual item's code, say, 10 times if you want a maximum of 10 finds. in yours, you would have to run through the entire thing several times

You misunderstood me. The function itself wouldn't loop.



//========================
//Hardcoded and effecient
//========================

var RegularSwordChance:int = 75
var SuperSwordChance:int = 20
var SuperSwordGoodConditionChance:int = 5
var NothingChance:int = 900
//
function findItem():Item {
var totalChance:int = 1000
var outcome:int = Math.random() * totalChance
var theItem:Item
//
if(outcome >= 101){
theItem = new Nothing()
} else if (outcome >= 96){
theItem = new SuperSwordGoodCondition()
} else if (outcome >= 76){
theItem = new SuperSword()
} else {
theItem = new RegularSword()
}
return(theItem)
}

//===================
//Dynamic and slower
//===================

var itemList:Array
function findItem():Item {
var totalChance:int = itemList.length
var outcome:int = Math.random() * totalChance
var theItem:Item
//
theItem = itemList[outcome].clone()
return(theItem)
}



Here's how I understand yours


var itemList:Array [
//
function findItem():Item {
var theItem:Item = new Nothing()
var testedItem:Item
var outcome:Number
//
var i:int
var Length:int = itemList.length
//
for(i = 0; i < Length; i++){
testedItem = itemList[i]
outcome = Math.random()*testedItem.rarity
if(outcome <= 1){
theItem = testedItem.clone()
break;
}
}
return(theItem)
}



So to my understanding: if you would find multiple items your method would give a nested loop.


and any object could be gotten more than once, even the super mega death armor. in mine, you can set a maximum number of finds for each individual item.

This is the first actual advantage of your proposed method. As I understand you'd only need to have several slots in the array occupied by the same item. To do that with my proposition you'd need an adaptation (use a splice command to remove the items from the array in the dynamic method), which would probably take away it's CPU advantage when it happens. This however is an exceptional event (unique items are.. wel unique), so in practice it will still have a CPU advantage.

There are some pitfalls with that method though. If you would have more finds then itemtypes it could throw an error. I'll give you that it's also an exceptional event, but it's a gamecrasher so worth looking out for.


btw, i wasn't using my previous argument as an argument, i was stating it as a fact. oh, and what's the significance of my post being unedited?

You used the conclusion of your previous argument as a conclusion to this one. I don't think stating a conclusion in another conext as fact is valid, even besides conclusions bieng subjective in nature. Your unedited post posed an argument which went into my own, feeding the discussion instead of ending it unfinished.

What I can't really understand is how you can ignore control over the chance to find an item. Isn't that what weighted randomness is actually about, that you want to control the probability distibution? What am I missing?

doomtoo
August 2nd, 2009, 01:15 PM
Cool, thanks guys for the extra info! Todorus, I had thought of doing something like that at first, but was not sure whether it would be slower than the way I decided on, and hadn't thought through whether I could make it dynamic for X items.

I'm loading an external XML file with all my possible items, which is right now 1 of 4 different types + gold in the code.

I am putting the rarity paired with each item, and doing it simmilar to flying monkey, but haven't checked the distribution yet.

I first gave them a 1 in 2 chances of finding some item/gold:
if(Math.floor(Math.random() * (1+high))==1) //high=2

Then I pull the length of the types of items, and choose a random one
var item_type:int=Math.floor(Math.random() * (1+items.children().length()));

if item_type==number of items, then I return a piece of gold, so 1 in 5 chances of getting gold if getting an item(so far)

Then I find a random item in the item category, find a random number with a range based on it's rarity, see if I got an item, if not, I continue looking through the item category until I find something:
while(found_item==null)
{
if(Math.floor(Math.random() * (1+items.children()[item_type].children()[item_type_number].rarity))==1)
{
trace("The type of item is"+item_type);
var item:XML = items.children()[item_type].children()[item_type_number];
//0=a weapon
//1= an armor
//2=a helmet
//3= a shield
if(item_type==0)
found_item = new Weapon(item, pos, stage1);
else if(item_type==1)
found_item = new Armor(item, pos, stage1);
else if(item_type==2)
found_item = new Helmet(item, pos, stage1);
else if(item_type==3)
found_item = new Shield(item, pos, stage1);
}
}

It seems to work fine so far, but it is probably slower than the one you had, since picking a random number 1-10000 would probably be faster than picking a random number 1-10 20x. I did the while loop to guarantee if a type of item was picked, that something would be found.

But how would I make it dynamic so the random number corresponded to whatever set of numbers?

possible pseudo code:

var final_item:item = null;
var item_number:int=Math.floor(Math.random() * (items.length()));
var baseline:int=0;
for ( var item in all_items)
{
if(item_number>baseline&&item_number<baseline+item.rarity)
final_item=item;
else
baseline+=item.rarity
}

I'll have to try to get both methods working and see what comes out faster + distribution. I also have to probably sub-divide my item lists depending on players level- so that a level 1 player can't end up with a level 50 item, and likewise so that a level 50 player gets weapons within +/- 10 or so levels.

Also, I am only calling the "get random item" method once whenever an enemy is killed, and I can't see having more than a few enemies dying at a time.

Thanks for the help guys!

flyingmonkey456
August 2nd, 2009, 04:06 PM
here's some code, maybe it will explain it better :P


var allitems:Array = new Array("sword", "shield", "armor"); //every item that exists
var itemsquant:uint = allitems.length; // the total number of items that exist
var maxquant:int; //the maximum quantity of a given item that can be found at one time
var rarity:int; //the probability of finding the item
var rndnum:int; //the random number
var found:Array; //contains every item found
var inventory:Array; //contains every item in the inventory
var foundlngth:uint; //the length of the "found" array
var itemnum:int; //the ID number of the item being tested

//this loop would be run through each item, replacing the values with those defined in doomtoo's xml, i left out that code because it isn't relevant
for(i = 0; i < itemsquant; i++)
{
for(i = 0; i < maxquant; i++)
{
rndnum = Math.random(rarity);
if(rndnum = 1)
{
foundlngth = found.push(itemnum);
}
}
}
//this loop will push the found items into the inventory
for(i = 0; i < foundlngth; i++)
}
inventory.push(found[i]);
}

TOdorus
August 2nd, 2009, 09:52 PM
I am putting the rarity paired with each item, and doing it simmilar to flying monkey, but haven't checked the distribution yet.

I won't go into the point that sequenced checks per type creates a long line of conditional probabilities again. Since you know the exact chances of something happening, and under what conditions they do happen, you can calculate them by hand. Math.random has a slight tendency to make a bellcurve (but only a quite flat one), so it shouldn't be too far off reality.



if(item_type==0)
found_item = new Weapon(item, pos, stage1);
else if(item_type==1)
found_item = new Armor(item, pos, stage1);
else if(item_type==2)
found_item = new Helmet(item, pos, stage1);
else if(item_type==3)
found_item = new Shield(item, pos, stage1);
}
}

Tip: since you're using constants here, you may wanna use a switch statement instead.




But how would I make it dynamic so the random number corresponded to whatever set of numbers?

Not sure what you mean. Do you mean that you can have variable itemlists and probabilities? I gave a setup for that in my dynamic example. Just feed it another itemList.



wimpyRabbit.itemList:Array = [RabbitFoot, RabbitFoot, RabbitFoot, Nothing, Nothing]
// 3/5 chance to get a RabbitFoot
superbadBlackKnight.itemList:Array = [AwesomeArmor, AwesomeSword, FancyBoots, FancyBoots, LotsGold, LotsGold, LotsGold, Nothing]
// 1/8 chance to get an AwesomeArmor or AwesomeSword; 2/8 to get FancyBoots etc..



Also, I am only calling the "get random item" method once whenever an enemy is killed, and I can't see having more than a few enemies dying at a time.

Yeah CPU isn't really an issue in practice. Probability is. As long as you use the previous items on the list as a condition then it becomes virtually uncontrollable. Your rarity would mean something different in every item list.

TOdorus
August 2nd, 2009, 10:00 PM
@flyingmonkey

I think you've made a mistake in your code. Now you can't really limit the maximum number of items that an enemy drops. It always is the sum of all the maxquant values. I take that wasn't what you were going for? And instead of that last extra loop, why not add it straight to the inventory array?

Ofcourse there remains the uncontrolled distribution problem.

flyingmonkey456
August 3rd, 2009, 06:07 AM
i was talking about limiting the amount of any single item that can be found at one time. health potions usually have a pretty good chance of being found, say you want 30 of them to be able to be found at one time, but no more. with your code, you would have to run through the entire thing 30 times, possibly getting other items instead of health potions. with mine, you have the health potion's maxquant set to 30 and it will try to find a health potion 30 times and no other items. it's easy enough to add an if statement that only pushes the new item if foundlngth is below maxfound (that's where the found array is needed). i was only demonstrating the ability to limit each item individually.

oh, what do you mean by uncontrolled distribution?

Gnoll
August 3rd, 2009, 06:26 AM
My thoughts on your method:

http://img406.imageshack.us/img406/5950/probability.th.jpg (http://img406.imageshack.us/i/probability.jpg/)


Might be wrong but if my theory is right it will get more and more wrong as you add more items?
Gnoll

flyingmonkey456
August 3rd, 2009, 07:48 AM
i just noticed a massive flaw in your method. lets say you have 11 people. these people represent items. then you have a hat. this represents the common denominator that every item's chance is taken out of. the hat has 100 pieces of paper in it, and those represent the each chance out of 100, the common denominator in this example. one piece of paper has a word written on it. lets say everyone gets in a line and grabs a handful of paper out of the hat. the first 10 grab 10 pieces of paper each. there is nothing left in the hat for the 11th person. sure, you can put more paper in the hat but that lessens the chance of each person to have the word on one of their pieces of paper. with my method, everyone has their own hat and are grabbing only one piece of paper and every hat has a piece of paper with a word on it. everyone has a chance to get the right piece of paper, and multiple people could even get the word. i've been arguing this will gnoll for about an hour and he doesn't seem to understand it. do you, TO?

TOdorus
August 3rd, 2009, 10:40 AM
Aaaah, so that's what you're talking about. Well that's what I meant by not putting marbles back into the bag. The usual example in probability is having a bag with 2 or 3 colors of marbles and then taking marbles from the bag. Then you can put the marbles back into the bag OR you can leave them out (they don't have to be taken out). I think what you're thinking about is, that when an item is taken from the world it can't be found again. Probability is all about chances. And marbles, ofcourse. I'm not trying to be childish here, but this is the best example I know of so I'll use it to explain.

UNCONDITIONAL PROBABILITY:

Say you have a bag of 2 red, 3 blue and 4 green marbles. If I blindly take a marble out of the bag I have 2/9 change of a red, 3/9 for a blue and 4/9 for a green marble. Now I put the marble back, hussle the bag around a bit and again take a marble out of the bag. Let's say I do this 900 times. Taking a marble out, putting it back and taking another marble out. Now since I know the chance of getting a red, blue or green marble I can calculate how many times I can expect to draw each color.

E(X = Red) = (2/9) * 900 = 200
E(X = Blue) = (3/9) * 900 = 300
E(X = Green) = (4/9) * 900 = 400

You see there is a distribution of what you're expected to get from the bag. You can multiply the chances by even more by drawing more marbles out of the bag, but the distribution will stay the same. 2/9 of them will be red, 3/9 of them will be blue and 4/9 of them will be green.

CONDITIONAL PROBABILITY:

Now for Not putting back marbles. What happens is that when you take a marble out, then another and a third, is that the chances of what color you get are dependent on the previous draws. Let's do a scenario:

Jack draws his first marble. It's a red marble. Now the probability distribution looks like this: 1/8 to get a Red, 3/8 to get a blue and 4/8 to get a green. Jack draws a blue marble. Now he has: 1/7 chance to get a red, 2/7 to get a blue and 4/7 to get a green. Jacks third draw is a green one. You see the probabilities (and therefore the distribution) chances depending what happened earlier. This is called a conditional probability: a condition must be met before this probability distribution to be. In this case a certain color must be drawn to get the distribution for the second marble and third marble. You can calculute an expectancy value for every scenario by making a branching tree of all the possible draws and going through every scenario, but I'll only do one here.

The chance of Jack's scenario happening is:
P(Red, Blue, Green) = (2/9)*(3/8)*(4/7) = .047619048 (P's are always out of 1)

Now we know that when we draw three marbles we have a .047619048 chance of getting a red one first, a blue one second and a green one third. So if we would draw 3 marbles one by one, put them all back do this over and over again we expect it to happen a certain amount of times.

3 sequential draws ten times:
E(Red, Blue, Green) = 10 * .047619048 = .47619048 (= 0) (so we don't expect it to happen even once)
3 sequential draws a thousand times:
E(Red, Blue, Green) = 1000 * .047619048 = 47.619048 (= 47)

BACK ON TOPIC:

Your method actually uses something different, but it's still conditional (dependent on previous occurences). Let's say your first item has a rarity of 5 and the second item a rarity of 20. What I read from this, is that your first item, should be found four times as much, as the second item.

P(X = item1) = 1/5
P(X = item2) = 1/20
P(X = no item) = 1 - (1/5) - (1/20) = 17/20

So when I kill an enemy that drops 1 item... say a thousand times:
E(X = item1) = 1000*(1/5) = 200
E(X = item2) = 1000*(1/20) = 50
E(X = no item) = 1000* (17/20) 850

(not sure if you've noticed but the the total P should always be 1 and the total E should always be the number of repetitions)

Now you know how much of an item you could expect to be dropped. With your method you introduce conditional logic. I'll do a scenario with only two items and one item will be dropped.

First item1 with a rarity of 5 is checked, only if it Isn't found (P = 4/5) item 2 is checked, only if that isn't found (P = 19/20) nothing is found.

P(item1) = 1/5 = 20/100
P(item2) = (4/5) * (1/20) = 4/100
P(no item) = (4/5) * (19/20) = 76/100

So you see the second item actually is 5 times as rare as the first item, because P(item1) is 5 times bigger then P(item2). From your rarity properties this should be 4. It gets more deformed when you start adding more items, as I've shown in my 2nd post and Gnoll in his/her last one (this is what Gnoll was talking about and at the same time inferring to a skewed distribution, favouring the first items).

IN REPLY:

You say that when there are too many people, the hat will be empty. That would be the case if I used a conditional probability, but I don't. All the papers are put back into the hat after a person has drawn, looked at it and put it back.

I hope that after reading this you understand that there is no common denominator with conditional logic. After the first draw there are only 90 pieces of paper left, then 80 and so on. So basicly people aren't drawing from their own hat. With each item you check, it's like there's a new person coming to the hat, looking for a specific word/item to grab. You see the example doesn't really apply well to your method.

flyingmonkey456
August 3rd, 2009, 12:00 PM
you don't understand, i'll use your example.

Your Method
lets say you have 3 red, 3 blue, and 3 green marbles. works fine, no problems. lets say you want to add 3 yellow marbles to the bag. now the chances of getting any of the other marbles have just decreased from 3/9 to 3/12.

My Method
my method would have 9 blue marbles and one red marble. you pick a marble. it's blue. no health potion for you. you put it back and draw again. blue. no short sword for you. you put it back and draw a third time. this time it's red. you get a steel helmet.

of course, my method wouldn't use the same 1:9 ratio every single time, but you should get the basic idea. your method decreases the chances for every item based on how many items there are. mine keeps the same odds no matter how many items.

Charleh
August 3rd, 2009, 12:16 PM
On re-reading this it seems flyingmonkey does have a valid piece of logic going on here. The probability ratios for each item are not weighted against other items, and the code is run once per item that could possibly be found on one inventory 'drop' (with the maxquant loop taking effect per item check)

This means that the chance of a drop is tested <maxQuant> number of times - and for each test the probability of receiving the item is the same due to the weighting.

So potentially you could limit a 'super sword' at 1 per drop, and set the rarity to be very high, and have this item drop at that same probability along with 10 other items which drop at a low rarity without altering or jeapordising the probability of any other item drop.

It's sound code, I think there's some misunderstandings going on here!

Not sure about how it would perform with huge item sets, but it's an inventory drop, it's not happening 100 times a second :)

flyingmonkey456
August 3rd, 2009, 12:21 PM
finally someone who agrees, i thought i was losing my sanity :)

TOdorus
August 3rd, 2009, 12:36 PM
What the code you posted does is this. Say you've got 1/9 chance to get the item and so a 8/9 chance to NOT get the item, so as you call it: the odds stay the same. In my understanding of the terminology is that I've got the same change to get item1, item3, item4 ... itemN.

P(item1) = 1/9
P(item2) = (8/9) * (1/9) = 8/89
P(item3) = (8/9)^2 * (1/9) = 64/729
P(item4) = (8/9)^3 * (1/9) = 512/6561

(and so on, until you reach the residu chance of getting nothing)

This is because if an enemy drops one item you loop through your list until you find an item and then stop. This hardly gives "the same odds". The chance to get an item differs even between items of the same rarity.

What you're saying in your last two posts(which makes this discussion confusing), is a binomial distribution. Every item on the list is checked and then it returns a succes. You can't control the amount of items the enemy drops this way, as every item needs to be checked and every item needs to be able to be found with every drop. This means that with some bigger itemlists the drops will become HUGE. The method sacrifices control.

EDIT:
Now I see the misunderstanding. When talking about limiting the amount of items per drop I ment the total amount. I understand now that you were talking about the amount per item.

glosrfc
August 3rd, 2009, 12:47 PM
The misunderstanding is that the monkey is always choosing from an infinite number of possible items, whereas Tod is choosing from a finite number. In other words, monkey's bag will always contain 3 red, 3 blue, and 3 green marbles. Tod's bag started with the same marbles, in the same proportions, but the number of marbles is reduced by one each time an item is picked.

The difference is in the way they've chosen to limit the actual availability of items. Tod's method is, mathematically, the more accurate...once 3 red, 3 blue, and 2 green marbles have been allocated, the probability that the last remaining item is a green marble must equal 1, or 100% because it's the only item left in the bag. But the probability of selecting a green marble with any of the previous picks actually changes as marbles are drawn from the bag.

Monkey's method relies on the simple expediency of checking to see if all the green marbles have been allocated. If they have, then you must keep picking from the bag until either a red or a blue marble is selected. The advantage of this method is that the probability of selecting a green marble will remain constant.

In statistical terms, Monkey's method is the same as predicting how many times it's possible to call Heads each time a coin is tossed. The coin has no memory of any previous calls so the probability will remain constant at .50
Tod's method is the same as predicting how many times it's possible to predict a sequence of calls with a given number of coins, i.e. predicting HTH with 3 pennies. In this case, although the coins possess no memory, the sequence itself does. If a Tail is thrown first, then the probability of success is zero. But, if a Head is thrown, the probability of a successful outcome is dependent upon the next throw...and then the next throw...and so on.

flyingmonkey456
August 3rd, 2009, 12:57 PM
i think the main difference between our methods is that i'm changing the denominator where he is changing the numerator. the problem with his method is that the sum of all of the numerators can never be greater than the denominator. my method doesn't have that limit.

TOdorus
August 3rd, 2009, 01:43 PM
i think the main difference between our methods is that i'm changing the denominator where he is changing the numerator. the problem with his method is that the sum of all of the numerators can never be greater than the denominator. my method doesn't have that limit.

The sum of all possibilities is always 1. It's the case with your method and mine, as both methods are based on probability. The sum of "our" numerators are therefore always equal to the denominator.

To be honest, the misunderstanding started when we were talking about adapting the original methods we proposed to counter the disadvantages we saw in both. This was the exact post for my total brainfarting:


if you want multiple items to be found, you just loop through each individual item's code, say, 10 times if you want a maximum of 10 finds. in yours, you would have to run through the entire thing several times and any object could be gotten more than once, even the super mega death armor. in mine, you can set a maximum number of finds for each individual item.

Flyingmonkeys couldn't control the amount of items a per drop (this is left to chance) and I couldn't control the amount of a specific item per drop (this is left to chance). When we continued talking we kept talking about the term amount in the way that it would give our own method the advantage over the other.

But now we understand each other, I'm going to fuel this fire yet again:

By using the adaption of conditional probability instead of unconditional probability I can limit the amount of the super mega death armors per drop, without breaking my logic. Your method can't limit the amount of items dropped as it would break the logic and favor items early on in the list. Now I know you're going to say that my method still doesn't have the exact same odds per amount of itemtypes, but that isn't my point. I'm looking for control over what a creature drops.

I can say a strong creature will drop one item, but it will give stronger items more often.

Say the wimpyRabbit has these properties


max amount of items it can drop = 3

items it has to drop:
4 * weak healthpotion
2 * strong healthPotion
10 * nothing


And the superbadBlackKnight


max amount of items it can drop = 1

items it has to drop:
4 * strong armor
2 * ultimate armor
10 * nothing


This way I can neatly control the max amount of powerfull armors bieng dropped.

Your method doesn't stop when it finds one strong armor, but continues to the ultimate armor and checks for that too. The superbadBlackKnight would be able to drop a strong armor and ultimate armor at the same time, leaving you with less control over the drops, as they can vary a lot more.

I'm sure your method has an advantage over mine in another department so shoot.

flyingmonkey456
August 3rd, 2009, 02:07 PM
i'm basically taking your method and breaking it up for each item. you would have a random number between 1 and 1000 and that number decides which item out of many would be received. i'm scaling this down to only one item at a time and running through it several times for each item. but there is still a huge, crippling flaw in your method. the more items you have, the lower the probabilities have to be. it's impossible to have a lot of items with high probabilities. even two items with probabilities above 50% would be impossible using your method. as i said in my first metaphor, every item is taking their chances out of the same hat. maybe i'm missing something, but i don't think i am.

TOdorus
August 3rd, 2009, 02:59 PM
but there is still a huge, crippling flaw in your method. the more items you have, the lower the probabilities have to be. it's impossible to have a lot of items with high probabilities. even two items with probabilities above 50% would be impossible using your method.

Sorry flyingmonkey, I've taken the time to understand your logic flyingmonkey, now please do the same for mine. There is no need to have a probability over 50% in my design, so it's not a flaw. There is need for it in your method, but not in mine. You're using a old school of math as do I. What the methods are supposed to do is control the content of a drop, which consists of several items. They both create a probability distribution but have different ways of getting there. That is their nature, so bashing that makes as much sense as saying that apples are flawed compared to pears. I thought we were past this and reached a middle ground on which we can both agree and could discuss their practical implications. To discuss in what situation you'd be better of with the vitamine content of an apple and in what situation the vitamin content of a pear.

What I'm afraid of, is that with your method you could get potentially huge drops and very small ones in the same game. Say a creature can drop 1 of every awesome item. There is a (small) probability that it drops all those awesome items, but it could also drop nothing. I find it hard to control a drop that way and this may have some serious influence on the gameplay experience. Some people can get a few lucky drops and become very powerfull very quick, while others need to spend a lot of time to get those items. This makes balancing areas harder as you'd be able to breeze to one and be stuck in another one until you get some good drops.

flyingmonkey456
August 3rd, 2009, 03:45 PM
i'm pretty sure i understand your method, i used to use it or at least something similar to it. i somehow never realized this problem until now, though. in your method, you have a set range and that range is sectioned. if the random number falls within the section for a sword, you would get a sword. if it falls within the section for a helmet, you get a helmet. am i right? this means that in order to add new items, you have to decrease the probability of the existing ones. you're squeezing all of your numerators into one denominator and that gives you a lot of limits. please tell me if i'm wrong on this, but i'm pretty sure i'm not. am i missing something? am i just not understanding your method?

TOdorus
August 3rd, 2009, 04:19 PM
i'm pretty sure i understand your method, i used to use it or at least something similar to it. i somehow never realized this problem until now, though. in your method, you have a set range and that range is sectioned. if the random number falls within the section for a sword, you would get a sword. if it falls within the section for a helmet, you get a helmet. am i right? this means that in order to add new items, you have to decrease the probability of the existing ones. you're squeezing all of your numerators into one denominator and that gives you a lot of limits. please tell me if i'm wrong on this, but i'm pretty sure i'm not. am i missing something? am i just not understanding your method?

Yes that is correct. But I don't think you realize the "squeezing" also happens in your method. It's just the nature of probability. In my method this is more explicit then in yours. Let me show you what I mean.

For both methods have possible outcomes with each drop. You can have one weak item, one good and one weak item, no items etc. These are all possible outcomes of the drop. If you would add a new outcome the probability of the other outcomes is diminished.

To apply that to your method: A draw has two different outcomes: either you find it or you don't, but you also have ranges of outcomes when you start to look at the complete drop. Say you have two different items. Item one can be found 4 times and item two 2 times. For the sake of example let's not look at rarity. Now you have 2^2 * 2^4 = 64 possible outcomes, so the chance of getting one of those outcomes is 1/64. Now you add another item to the mix which can be found 3 times. Now you have 2^2 * 2^4 * 2^3 = 512 outcomes and a 1/512 chance for each outcome. Now if I add up all of the chances I will allways get 1.

So I'm not really interested in the result of the individual draw but the effect of all of them combined: the drop.

flyingmonkey456
August 3rd, 2009, 05:01 PM
i'm a bit confused now, what do you mean by the effect of all of them combined? in my method, the probability for each item is completely separate. there is no "combined".

Gnoll
August 3rd, 2009, 06:46 PM
flyingmonkey you can't do anything like that in probability without somehow combining it in the end. (To a total of 1 or 100% as TO said)

If you test each item and multiple return 1 what do you do. Your first suggestion to me was push all the found ones in the array then generate a random number based on the length of the array. This also skews your results because if you finally find your super death armor chances are you also find a health potion reducing your chances by 1/2 again.

If you keep looping through till you only get 1 you still somewhat face this problem, but then you come back to that infinite loop you were trying to say the other method had. (Even though computerised random numbers are deterministic.)

Correct me if i'm wrong,
Gnoll

TOdorus
August 3rd, 2009, 08:29 PM
i'm a bit confused now, what do you mean by the effect of all of them combined? in my method, the probability for each item is completely separate. there is no "combined".

I know that the chance for each item to be found is seperate. But your function gives a result ( I called it an outcome in my last post), which is a combination of several seperate chances. All possible results are a possiblity. Every possible result is a combination of items. You can calculate the chance for each possibility (or combination, if you will). I'll try again with another example.

Say you have two dice. What is the chance that a dice throws 3? You know it's 1/6. The chance that the other dice throws 3 is also 1/6. Like you said: "the probability for each item is completely separate" (this is called independent). But now we throw the two dice. What is the chance to throw seven? What is the chance to throw 8? You can calculate these by writing down all possible combinations that make a seven (or 8) and divide it by the total possible combinations. This way you can calculate an expected frequency for every combination to occur when you throw the two dice X times.

It's the same with your method for finding items: what is the chance to get 3 health potions and a death armor? What is the chance to get 2 swords and a helmet? So the drop is a sequence (I called it combination last time) of independent probabilities, which form a probability distribution.

I'm running out of energy a bit here, so here (http://en.wikipedia.org/wiki/Probability_distribution)

EDIT:
@gnoll

Sorry to ignore you there a bit.

He doesn't limit the amount of items per find. A healt potion has a p chance to be found. The maximum amount of healt potions a drop can give is 4. Then it just tests it 4 times to see how many health potions it will give. The next item is a sword which can be 2 per drop. Then it tests 2 times to see how many swords are found. And so on for every itemtype.

EDIT2:
@glosrfc
I'd like to thank you for so expertly summarizing it. That helped out a lot.

flyingmonkey456
August 4th, 2009, 05:26 AM
But now we throw the two dice. What is the chance to throw seven? What is the chance to throw 8? You can calculate these by writing down all possible combinations that make a seven (or 8) and divide it by the total possible combinations.

you're wrong. i'm not finding the probability of finding, say, a sword AND a shield. i'm finding the probability of finding a sword, THEN the probability of finding a shield. they are completely separate rolls of the dice that result in completely separate numbers. they never interact.

Charleh
August 4th, 2009, 08:30 AM
I think you are now arguing over pedantics and terminology. Calling the distribution of items in monkeys drop a probability distribution is technically correct. The items in one particular drop will form one of 'x' number of combinations. Perform this drop a billion times and you will eventually get a set of results based on the probability of the drops of the individual items that could be dropped. This may be a bell curve for items with varying levels of rarity - "3 potions" (common/mid level) vs "2 potions a mega armour and a mega sword" (rare drop)

However, each method has advantages and disadvantages, and the method you use should feel right to you.

I'd probably go with a category selection probability such as:

Choose category:
Gold: Common
Potions: Common
Weapons: Medium
Armour: Medium
Magic Items: Sparse
Unique Items: Very Rare

Then once the category was selected, perform a second probability calculation to determine which of these items were dropped. That way you can on very odd occasion ensure that the player gets a rare item, and then choose the level of 'rareness' of the rare item. You get a double probability check, but at least you know the probability distribution won't get too skewed by multiple nested dependant checks.

Gnoll
August 4th, 2009, 08:37 AM
Good thoughts Charleh, I should have gone and looked at the ol' D&D books. I forgot about that :glasses: kind of a double TO method.

Gnoll

TOdorus
August 4th, 2009, 09:13 AM
Yeah I was thinking about something like that too Charleh, as a certain combination can be more valuable then the other. A huge pile of gold could be the same as a good item.
A way of accomplishing that would be to give each creature drop points. Every category has a value.

Gold: Common = 1
Potions: Common = 2
Weapons: Medium = 4
Armour: Medium = 8
Magic Items: Sparse = 16
Unique Items: Very Rare = 32

When you start the double roll, you first exclude all the categories with a bigger value then the drop points. Now you do the double roll (rarity followed by item). Then subtract the number of points of the rarity class and repeat until the drop points are zero.

Another way: Instead of doing a double roll, you could also say that a creature has, 2 common and 1 rare item. Then you do the rolls in each category. Ofcourse every category has a no item category to still keep it somewhat random.

I like the points system best though as you have less control over the exact content, but the drops will have roughly the same value.

Just realized we're going for controlled randomness. Crazy humans.


I think you are now arguing over pedantics and terminology.

I don't know, but I'm done.

EDIT:

Wasn't D&D's double roll (or triple or...) designed to get smaller chances then 1/6? So if you need to roll for a certain ultra armor you would need to roll 1/6 * 1/6 = 1/36. Wouldn't that be the same as just throwing all the items in one roll and give the ultra armor 1/36 chance of getting picked?

flyingmonkey456
August 4th, 2009, 10:00 AM
dnd does it more similarly to my way. i'm rolling a n-sided die once for each item, rather than multiple rolls of a 6-sided die. my "rarity" value for each item is basically the same as dnd's probability gotten from the category. you're rolling a thousand sided die one time for every item at once.

you didn't really give an opinion on the dnd method, so i'm not sure if you realized that or not. just thought i'd point it out.

Gnoll
August 4th, 2009, 10:06 AM
DnD for item generation you do a 100 sided (2 10s) and that picks a rarity, then you subsequently do another roll for which rarity you get, same for the room generation techniques etc in the DM guide to :) (v3.5).

I like it myself :)
Gnoll

(It is just nested more and more for types of items etc)

Charleh
August 4th, 2009, 10:13 AM
Alternatively you could go down the Diablo II route where I think something like the base item was generated (with the exception of rares and sets), then the properties of that item were added as a chance, with the number of effects and the effect magnitude selected at random.

Well that's what it felt like - you could get 'xxxxx sword of the xxxxx' lots of times with different xxxxx's, I doubt that someone created all the possible combinations of item by hand.

TOdorus
August 4th, 2009, 10:38 AM
dnd does it more similarly to my way. i'm rolling a n-sided die once for each item, rather than multiple rolls of a 6-sided die. my "rarity" value for each item is basically the same as dnd's probability gotten from the category. you're rolling a thousand sided die one time for every item at once.

you didn't really give an opinion on the dnd method, so i'm not sure if you realized that or not. just thought i'd point it out.

Well the reason for not giving an opinion on it is that I don't want to restart our argument. Charleh posed a method with subcategories, which I asked if it isn't the same as the inital method I posed with only one big category. If you would throw all the items in the subcategories in one big category, you'd just need to adjust the chances by multiplying the probability of each item with the probability of the items category. The method would behave in the same way.

Then Gnoll said Charlehs way is the DnD way of doing it (you guys are SO nerdier then me!), so I infered that the reason DnD uses categories may be because dice have a limited number of sides (a sixsided dice was just an example you nerdy purists!). So in short: I've given my opinion on it a lot :)

You're actually contradicting that monkey, as you're saying that charlehs method isn't the DnD way of doing it, but I let you two bicker that out.


Alternatively you could go down the Diablo II route where I think something like the base item was generated (with the exception of rares and sets), then the properties of that item were added as a chance, with the number of effects and the effect magnitude selected at random.

Well that's what it felt like - you could get 'xxxxx sword of the xxxxx' lots of times with different xxxxx's, I doubt that someone created all the possible combinations of item by hand.

Yeah I think they did it that way. I think the name was based on fuzzy logic. Although in Diablo vanilla I once got an insanely powerfull unique, that alone would make my character 4 times as powerfull, by raising stats and whatnot. That made that playthrough a breeze, so the system isn't perfect.

flyingmonkey456
August 4th, 2009, 11:37 AM
my method is basically the same as what charleh said, i'm just putting every item in it's own category. if i am contradicting him, i don't see how. our methods are both basically the same as his, but the number of categories are different; you have the lowest possible amount of categories (1) and i have the the maximum amount of categories.

TOdorus
August 4th, 2009, 12:04 PM
my method is basically the same as what charleh said, i'm just putting every item in it's own category. if i am contradicting him, i don't see how.our methods are both basically the same as his, but the number of categories are different; you have the lowest possible amount of categories (1) and i have the the maximum amount of categories.

Nah, I ment you were contradicting Gnoll in his statement that Charlehs way isn't the DnD way, but I'm not sure that I entirly follow you now, so that might not be the case. The way I understand we take different routes. Correct me if I'm wrong:

My initial proposal was one big category and just squeeze everything in there and see what number comes up.

Your initial proposal was to check every item to see what number comes up and if it's the right one, you add it to the drop.

Now I don't know about Charlehs because the way he explained he can mean both routes.

TOdorus:
Have a set number of items the creature can drop. Do a roll for which category the item will be in. Do a second roll to determine the item. Do this as many times as the creature has to drop items.

flyingmonkey:
Each item is it's own category and you would loop through every category to see if it is found (succes/ failure), so no roll for which category to check, you check all. Several categories can hold the same item, so that some items can be found more then once.

As I assume DnD knows A LOT of item- and roomtypes I also assume that they don't want players going through every one of them, and have split it up in multiple rolls (this would be the TOdorus route). Since Gnoll said Dnd method = Charleh method, I thought you two were contradicting each other. Now, I don't want ANY misunderstanding anymore whatsoever, so I'd like to point out that Gnolls claim that Dnd method = Charleh method does not have to be true. To know that we need to know Charlehs intended route (if he even has a preference). The only one to answer that is Charleh.

For the record: I'm going for the pointbased system I mentioned earlier if I ever need to have a itemdrop in a game.

Charleh
August 4th, 2009, 12:21 PM
My lips are sealed, muhahahahahhaha.

I'm prompted to make an RPG now in Flash... just to make the most awesome drop system ever! :)

flyingmonkey456
August 4th, 2009, 12:33 PM
actually, i take back what i said about my method being similar to charleh's. it is similar, but not in the way i said. my method does put every item in it's own category, but it rolls the die once for each category rather than once for every category.

Gnoll
August 4th, 2009, 06:27 PM
:P It's a friendly debate not an argument! Whats wrong with collecting opinions and ideas? I thought this was fun and I have gained a little insight. :)

TO I was saying that Charlehs pretty much was the same as D&Ds and yours, just a form with multiple loops. Then he brought out the diablo system which is also fun. :)

Ah well I guess it's over, can't wait for your game Charleh! :P

Gnoll

TOdorus
August 4th, 2009, 06:39 PM
TO I was saying that Charlehs pretty much was the same as D&Ds and yours, just a form with multiple loops. Then he brought out the diablo system which is also fun. :)

Well yeah, but I was thinking about covering my *** on all sides, not just one. I wanted a very safe ***.




Guess the spamfilter doesn't like donkeys.