Цитата:
Сообщение от Appleman
Зная вероятность наступления события, получать значение типа "истина-ложь".
|

Код AS3:
var chance:Number = 0.1; // 10%
var result:Boolean = Math.random() > chance;
Цитата:
Сообщение от Appleman
Имея несколько событий с разной вероятностью, определить то из них, которое произойдёт.
|
Когда-то делал нечто подобное. Суть в том, чтоб сложить все id и их вероятность в список, а затем случайно выбирать их оттуда:

Код AS3:
var events:RangeArray = new RangeArray();
events.setRange(1, 10); // Событие 1, шанс 10
events.setRange(2, 50); // Событие 2, шанс 50
events.setRange(3, 80); // Событие 3, шанс 80
trace(events.getItemByRangeIndex(Math.random() * events.summ)); // Случайное событие.

Код AS3:
package volkov.collection
{
/**
* Массив с доступов по диапазону значений.
* Позволяет обращаться к элементам массива по диапазону индексов.
* @author Roman A.V.
*/
public class RangeArray
{
// Приват
private var _vec:Vector.<RangeArrayItem>;
private var _hash:Object;
private var _summ:uint;
private var _length:uint;
private var _updated:Boolean;
/**
* Создать массив.
*/
public function RangeArray()
{
_vec = new Vector.<RangeArrayItem>;
_hash = new Object;
}
// ПАБЛИК
/**
* Получить элемент списка.
* Возвращает элемент списка как из обычного массива, где index должен быть от 0 до length - 1.
* @param index Индекс элемента в списке.
* @return Возвращает элемент списка как из обычного массива, где index должен быть от 0 до length - 1.
*/
public function at(index:uint):uint
{
return _vec[index].id;
}
/**
* Получить элемент спика по его индексу диапазона.
* Возвращает элемент списка диапазон которого содержит переданный индекс или 0, если такого элемента нет в списке.
* @param index Индекс диапазона от 0 до summ - 1 включительно.
* @return Возвращает элемент списка диапазон которого содержит переданный индекс или 0, если такого элемента нет в списке.
*/
public function getItemByRangeIndex(index:uint):uint
{
if (_updated)
update();
// Бинарный поиск.
// Взято с вики и адаптировано: https://ru.wikipedia.org/wiki/%D0%94...B8%D1%81%D0%BA (C#)
if (_length === 0 || index > _vec[_length - 1].lastIndex)
return 0;
var first:uint;
var last:uint = _length;
while (first < last)
{
var mid:uint = first + (last - first) / 2;
var item:RangeArrayItem = _vec[mid];
if (index < item.firstIndex)
last = mid;
else if (index > item.lastIndex)
first = mid + 1;
else
return item.id;
}
return _vec[last].id;
}
/**
* Установить/добавить диапазон индексов элементу списка.
* Если указанного id нет в списке - он добавляется.
* Если указанный id уже имеется в списке, обновляется значение его диапазона.
* Если диапазон передан как 0 - указанный id удаляется из списка. (Если есть)
* @param id ID Объекта.
* @param range Диапазон индексов.
*/
public function setRange(id:uint, range:uint):void
{
var item:RangeArrayItem = _hash[id];
if (range === 0)
{
if (item === null)
return;
_vec.removeAt(_vec.indexOf(item));
_length--;
delete _hash[id];
}
else
{
if (item === null)
{
item = new RangeArrayItem;
item.id = id;
item.range = range;
_vec[_length++] = item;
_hash[id] = item;
}
else
{
item.range = range;
}
}
_updated = true;
}
/**
* Очистить весь список.
*/
public function clear():void
{
_vec = new Vector.<RangeArrayItem>;
_hash = new Object;
_length = 0;
_summ = 0;
_updated = false;
}
// ПРИВАТ
private function update():void
{
_updated = false;
_summ = 0;
var i:uint;
var item:RangeArrayItem;
while (i < _length)
{
item = _vec[i++];
item.firstIndex = _summ;
item.lastIndex = _summ + item.range - 1;
_summ += item.range;
}
}
// ГЕТТЕРЫ
/**
* Количество элементов в списке.
*/
public function get length():uint
{
return _length;
}
/**
* Сумма всех диапазонов.
*/
public function get summ():uint
{
if (_updated)
update();
return _summ;
}
}
}
class RangeArrayItem
{
public var id:uint;
public var range:uint;
public var firstIndex:uint;
public var lastIndex:uint;
}
Вроде всё прекрасно работало, но потести на всякий случай.