How to get a balanced result when choosing a random element from an array?

As a fun project, I am developing a game of cricket simulator, and one of the main aspects of this is the random result at each distribution.

In general, in Test Cricket there is the following possibility:

"0", "1" occur very often (60% of the time)

"2", "3" occur moderately (25% of the time)

"FOUR", "SIX", "EXIT" are rare (10% of the time)

"WIDE BALL", "NO BALL" occurs very rarely (2% of the time)

If I have an array, for example:

var possible_outcomes = ["0","1","2","3","FOUR","SIX","OUT","WIDE BALL","NO BALL"];

What could be the best way to get the aforementioned probability when pulling a random element from possible_outcomesover a fixed number of iterations, say 60.

PS: , . , , , .

+4
6

.

, .

.

function getRandomIndexByProbability(probabilities) {
    var r = Math.random(),
        index = probabilities.length - 1;

    probabilities.some(function (probability, i) {
        if (r < probability) {
            index = i;
            return true;
        }
        r -= probability;
    });
    return index;
}

var i,
    action = ["0", "1", "2", "3", "FOUR", "SIX", "OUT", "WIDE BALL", "NO BALL", "other"],
    probabilities = [0.3, 0.3, 1 / 8, 1 / 8, 1 / 30, 1 / 30, 1 / 30, 0.01, 0.01, 0.03],
    count = {},
    index;

action.forEach(function (a) { count[a] = 0; });

for (i = 0; i < 1e6; i++) {
    index = getRandomIndexByProbability(probabilities);
    count[action[index]]++;
}

console.log(count);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Hide result
+1

0 100. 0 < < 10 0, 20-25, 2 . , 100, .

+1

IMO - , - :

var possible_outcomes = ["0","0","0","0","0","0","0","0","0","0",
"0","0","0","0","0","0","0","0","0","0",
"0","0","0","0","0","0","0","0","0","0",
"1","1","1","1","1","1","1","1","1","1",
"1","1","1","1","1","1","1","1","1","1",
"1","1","1","1","1","1","1","1","1","1",
,and so on...,
,"WIDE BALL","WIDE BALL","NO BALL","NO BALL"];

. .

PS. , 100 "0" , , .

+1

, , " ". Javascript, , , . , , . .

In the logic of your cricket game, you can use a loop to pull out random results until the dough comes out, something like this:

function weightedRand(spec) {
  var i, j, table = [];
  for (i in spec) {
    for (j = 0; j < spec[i] * 10; j++) {
      table.push(i);
    }
  }
  return function() {
    return table[Math.floor(Math.random() * table.length)];
  }
}

var outcomes = weightedRand({
  '0': 0.3,
  '1': 0.3,
  '2': 0.125,
  '3': 0.125,
  'FOUR': 0.033,
  'SIX': 0.033,
  'OUT': 0.033,
  'WIDE BALL': 0.01,
  'NO BALL': 0.01
});

$('button').click(function() {
  clearInterval(interval);
  $('.innings').empty();
  $(this).prop('disabled', true);

  var interval = setInterval(function() {
    var item = outcomes();
    $('.innings').append('<div>' + item + '<div>');

    if (item == 'OUT') {
      clearInterval(interval);
      $('button').prop('disabled', false);
    }
  }, 1000);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Start innings</button>
<div class="innings"></div>
Run codeHide result

Note that the probabilities will not match what you indicated in the code above, since they do not sum up to 1.00, but the values ​​can be easily changed.

+1
source

A simple plug-in solution will be as follows:

var cricket = [
    {
        name: 0,
        weight: 30
    },
    {
        name: 1,
        weight: 30
    },
    {
        name: 2,
        weight: 13
    }
    // ...
];

// Create the chances array by putting as many instances of a value in it, as it weight

var chances = [];
for (var i = 0; i < cricket.length; i++) {
    for (var j = 0; j < cricket[i].weight; j++) {
        chances.push(cricket[i].name);
    }
}

// getting a value

var value = chances[Math.floor(Math.random() * chances.length)];
+1
source

Forgive me for my awkward code, but I hope you can consider this a solution ?: D

function repeatArray(value, len) {
  if (len == 0) return [];
  var a = [value];
  while (a.length * 2 <= len) a = a.concat(a);
  if (a.length < len) a = a.concat(a.slice(0, len - a.length));
  return a;
}

var zeroes = repeatArray("0", 30);
var ones = repeatArray("1", 25);
var twos = repeatArray("2", 15);
var threes = repeatArray("3", 10);
var fours = repeatArray("FOUR", 5);
var sixes = repeatArray("SIX", 5);
var wickets = repeatArray("OUT", 5);
var extras = repeatArray("Extra", 5);
var finalArr = [];

finalArr = finalArr.concat(zeroes, ones, twos, threes, fours, sixes, wickets, extras);
for (var i = 0; i < 20; i++) {
  var idx = Math.floor(Math.random() * finalArr.length);
  $("#out").append(finalArr[idx]+", ");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="out"></div>
Run codeHide result
+1
source

Source: https://habr.com/ru/post/1663611/


All Articles