Draw with different percentages

1

I have an "open boxes" system, which works as follows:

The box can have X items (amount you want) where each item will have Y% of gain, being: # or # .1% (no more decimal places)

That is: "Box one" can have 10 items, where:

  • 0.5% chanca to be won
  • 1% chance of being won
  • 4% chanca to be won
  • 4.5% chanca to be won
  • 5% chanca to be won
  • 15% chance of being won
  • 15% chance of being won
  • 15% chance of being won
  • 20% chanca to be won
  • 20% chanca to be won
  • Always the sum of percentage of victory of the items will be of 100% round

    Currently, I only have a simple function that takes any item from the array of items in the box:

    $vencedor = $items[array_rand($items)];
    

    And it brings me the item "drawn", what I need is that the percentage of each item is taken into account, and I'm not getting it

    I tried some things, none came to the desired result

        
    asked by anonymous 16.07.2018 / 04:50

    1 answer

    1

    The solution proposed by @bfavaretto in the comments works perfectly. Here is another suggestion if you have not been able to solve it.

    I made a solution based on a range of numbers that each element can have. The higher the chance percentage, the greater the number range of each element. Based on your example, I've created the following array:

    $items = array(
    
        "Item 1" => 0.5, // porcentagens
        "Item 2" => 1,
        "Item 3" => 4,
        "Item 4" => 4.5,
        "Item 5" => 5,
        "Item 6" => 15,
        "Item 7" => 15,
        "Item 8" => 15,
        "Item 9" => 20,
        "Item 10" => 20
    
    );
    

    With this, a new array is generated with the name of each element and its respective ranges through this code:

    $valor = 1000; // valor do peso máximo e total dos itens
    $inicio = 1;
    $ultimo_valor = 0;
    
    $array_elementos = array(); // array para sorteio
    
    // cria o array para sorteio
    foreach($items as $nome => $porcentagem){
    
        $val =  ($valor * $porcentagem) / 100;
        $valorFinal = $val + $inicio - 1;
        $array_elementos[$nome] = $inicio."-".$valorFinal;
        $inicio = $valorFinal + 1;
    
    }
    

    See how the $array_elementos array was:

    Array ( 
    
        [Item 1] => 1-5 
        [Item 2] => 6-15 
        [Item 3] => 16-55 
        [Item 4] => 56-100 
        [Item 5] => 101-150 
        [Item 6] => 151-300 
        [Item 7] => 301-450 
        [Item 8] => 451-600 
        [Item 9] => 601-800 
        [Item 10] => 801-1000 
    
    )
    

    Now just draw a random number and look in the array in which element is the number. So:

    // numero randômico "sorteio"
    // de 1 até o valor máximo
    $num_rand = rand(1, $valor);
    
    $elemento_sorteado = "";
    
    // procura o elemento sorteado
    foreach($array_elementos as $nome => $peso){
        $valores = explode("-", $peso);
        if($num_rand >= $valores[0] && $num_rand <= $valores[1]){
            $elemento_sorteado = $nome;
            break;
        }
    }
    
    echo $elemento_sorteado;
    

    See the code working ideone

        
    16.07.2018 / 21:07