So I want to randomly pick different values from a table but with some rarer than others, how do I do this?
1 | local values = { "value1" , "value2" , "value3" } |
2 |
3 | local selectedvalue = math.random( 1 ,#values) |
4 | --this works, but how do I do it if vaule 1 has twice as much change to be selected than value 2 and 3? This just gives them all the same chance... |
One way of going about this is by duplicating the values in the table, like so:
1 | local values = { "value1" , "value1" , "value2" , "value3" } |
This way, however, can be long to type, so you could do something like this:
01 | -- For each entry, the first value is the actual value, and the second is the 'weight' or chance. |
02 | local values = { |
03 | { "value1" , 2 } , |
04 | { "value2" , 1 } , |
05 | { "value3" , 1 } |
06 | } |
07 |
08 | local SelectFrom = { } |
09 | local SelectedValue |
10 | for i, v in ipairs (values) do |
11 | for i 2 = 1 , v [ 2 ] do |
12 | table.insert(SelectFrom, v [ 1 ] ) |
13 | end |
14 | SelectedValue = math.random( 1 , #SelectFrom) |
15 | end |
This works like the first method, but compresses the values, then decompresses them when selecting.
There may be other (better) ways; this is just the first one I came up with. It is also untested.
The first method is a pretty good one, and I'd go with that because it's the first one I thought of too. The alternative is to have a weight table, wherein the selection is done in part of a single random number out of 1.
01 | local items = { |
02 | { item 1 , 2 } , |
03 | { item 2 , 3 } , |
04 | { item 3 , 1 } , |
05 | { item 4 , 1 } |
06 | } ; |
07 | local max = 0 ; |
08 | for i = 1 ,#items do max = max+items [ i ] [ 2 ] end ; |
09 | local selection,cnt = math.random(), 0 ; |
10 | for i = 1 ,#items do |
11 | cnt = cnt+items [ i ] [ 2 ] /max; |
12 | if cnt > selection then selection = items [ i ] [ 1 ] break end ; |
13 | end ; |
14 | if type (selection) = = 'number' then selection = items [ #items ] [ 1 ] end --Just in case |
selection
would at that point become your item. This is good because it can be mixed with other loot tables and have inheritance implemented with ease.