Показать сообщение отдельно
Старый 09.10.2018, 13:20
Tails вне форума Посмотреть профиль Отправить личное сообщение для Tails Найти все сообщения от Tails
  № 4  
Ответить с цитированием
Tails
 
Аватар для Tails

блогер
Регистрация: Dec 2008
Адрес: г. Чебоксары
Сообщений: 2,259
Записей в блоге: 6
Цитата:
Сообщение от 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;
}
Вроде всё прекрасно работало, но потести на всякий случай.
__________________
Дети не должны знать о своих родителях