Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 21.05.2011, 13:39
Lyso вне форума Посмотреть профиль Отправить личное сообщение для Lyso Посетить домашнюю страницу Lyso Найти все сообщения от Lyso
  № 1  
Ответить с цитированием
Lyso

Регистрация: Sep 2010
Адрес: Красноярск
Сообщений: 217
Отправить сообщение для Lyso с помощью Skype™
По умолчанию Процентый шанс ответа.

Как сделать систему шансов. Например у меня есть 10 чисел. При нажатии на кнопку выбирается одно из чисел. Если оно выбралось, оно будет выпадать чаще других. То есть шанса выпада этого числа повысится.
Я думал делать так:
Создать массив с вариантами (1,2,3,4,5,6,7,8,9,0)
Создать массив с шансами (10,10,10,10,10,10,10,10,10,10)

Потом делать рандом и выбирать шанс из массива, а потом выбирать число и когда оно выпадает, увеличивать шанс. Но у меня не получилось.

Подскажите как такое можно осуществить?

Добавлено через 2 минуты
И как вообще осуществить процентный шанс? Как сделать при увеличении одного параметра ,равномерное сниженое других, но учитывая, что все равно в общем должно выходить 100%..?

Старый 21.05.2011, 14:33
i.o. вне форума Посмотреть профиль Отправить личное сообщение для i.o. Найти все сообщения от i.o.
  № 2  
Ответить с цитированием
i.o.
 
Аватар для i.o.

Регистрация: Apr 2010
Адрес: Earth
Сообщений: 1,897
после выбора, добавить это число в исходный массив еще раз (или несколько раз). Теперь, в исходном массивет его будет 2 (или более), когда остальных по-прежнему останется по-одному. Шансы получить выбранное число повысятся.


Последний раз редактировалось i.o.; 21.05.2011 в 14:49.
Старый 21.05.2011, 14:42
Lyso вне форума Посмотреть профиль Отправить личное сообщение для Lyso Посетить домашнюю страницу Lyso Найти все сообщения от Lyso
  № 3  
Ответить с цитированием
Lyso

Регистрация: Sep 2010
Адрес: Красноярск
Сообщений: 217
Отправить сообщение для Lyso с помощью Skype™
Спасибо, попробую.

Добавлено через 6 минут
Получилось. Спасибо, оказалось проще, чем думал.

Добавлено через 4 часа 45 минут
Мне требуется другое решение. Так как иногда некоторые варианты могут отпадать. Например в процессе отключить цифру 5. А как сделать при вашем коде? Делать цикл по удалению всех полей с 5? Но тогда будет значение null, а это мне не подходит.


Последний раз редактировалось Lyso; 21.05.2011 в 19:29.
Старый 21.05.2011, 20:14
NAO111 вне форума Посмотреть профиль Отправить личное сообщение для NAO111 Найти все сообщения от NAO111
  № 4  
Ответить с цитированием
NAO111

Регистрация: Oct 2009
Сообщений: 155
так удаляйте со смешением, чтобы не было пустых null

Старый 21.05.2011, 21:35
mikhailk вне форума Посмотреть профиль Отправить личное сообщение для mikhailk Найти все сообщения от mikhailk
  № 5  
Ответить с цитированием
mikhailk
 
Аватар для mikhailk

Регистрация: Nov 2009
Адрес: СПб
Сообщений: 2,236
http://help.adobe.com/ru_RU/AS3LCR/F...l#splice%28%29

Старый 21.05.2011, 23:20
Crazy вне форума Посмотреть профиль Отправить личное сообщение для Crazy Посетить домашнюю страницу Crazy Найти все сообщения от Crazy
  № 6  
Ответить с цитированием
Crazy
[+1 23.05.11]
 
Аватар для Crazy

Регистрация: Dec 2001
Сообщений: 4,159
Цитата:
Сообщение от i.o. Посмотреть сообщение
после выбора, добавить это число в исходный массив еще раз (или несколько раз). Теперь, в исходном массивет его будет 2 (или более), когда остальных по-прежнему останется по-одному. Шансы получить выбранное число повысятся.

В общем случае проще оставить числа как есть, но добавить веса. Изначально вес каждого равен 1. Ели число выбрано -- его вес увеличиваем (до 2, 10, 1000 -- как нужно).

Далее формируем случайное число, причем в качестве диапазона берем сумму всех весов. Как потом найти выпавшее число, полагаю, достаточно очевидно.

Цитата:
Например в процессе отключить цифру 5.
Поставить ей вес 0.
__________________
GIT d++ s++:++ a C++$ UB++ P++ L+ E+ W+++ N++ w++ O+ M V- t-- 5-- X+ R+++ tv- b+++ D++

Старый 22.05.2011, 00:31
GBee вне форума Посмотреть профиль Отправить личное сообщение для GBee Найти все сообщения от GBee
  № 7  
Ответить с цитированием
GBee
 
Аватар для GBee

Регистрация: Jan 2009
Сообщений: 3,067
Записей в блоге: 3
Отправить сообщение для GBee с помощью Skype™
Цитата:
Как потом найти выпавшее число, полагаю, достаточно очевидно.
Я не понял, если честно? Поясните как? Пока вариант ИО элегантней :о))
__________________
Чтобы доказать, что вы не робот, причините вред другому человеку.

Старый 22.05.2011, 00:49
ShadowsInRain вне форума Посмотреть профиль Отправить личное сообщение для ShadowsInRain Найти все сообщения от ShadowsInRain
  № 8  
Ответить с цитированием
ShadowsInRain
 
Аватар для ShadowsInRain

Регистрация: Mar 2011
Сообщений: 35
Алгоритм древний и проверенный, но непосредственно АС3-класс написан на коленке (NP++) за 5 минут (в АС3 не использовал ибо), так что, возможно, придётся внести фикссы, чтобы компилировалось. Без оптимизации работает не самым быстрым способом. Помимо того, возможно накопление ошибок при сложении чисел с плавающей точкой. При таком раскладе первая зарегистрированная грань будет выпадать гипотетически чаще. Чтобы этого избежать, шансы граней должны быть одного или близких порядков. Грубо говоря, самый маленький шанс и самый большой не должны отличаться более чем на три-четыре порядка. Но в большинстве задач можно забить на эту ошибку, она реально ничтожна.

Код AS3:
package
{
	public class VirtualDice // виртуальная кость (ваш К.О.)
	{
		protected var _chances:Vector.<Number> = new Vector.<Number>; // стороны кости
		protected var _faces:Vector.<Number> = new Vector.<Number>; // абсолютные шансы для каждой стороны
		protected var _range:Number = 0; // кеш суммы всех шансов, используется при кидании кости
 
		public function getFaceChance(face:Number):Number // текущий вес для грани кости
		{
			var index:uint = _faces.lastIndexOf(face); // найти грань в наборе
			return (index == -1) ? 0 : _chances[index]; // вернуть шанс найденной грани, либо нуль, если не найдена
		}
 
		public function setFaceChance(face:Number, chance:Number = 1):void // установить вес грани
		{
			if(chance < 0) // отрицательные шансы невозможны
				chance = 0; // особо дотошные пишут throw new Error("Dice face chance negative value assigned");
 
			var index:uint = _faces.lastIndexOf(face); // найти грань в наборе
 
			if (index == -1) // а нету такой грани в наборе, придётся добавить
			{
				if(chance == 0) // её и так нет, нет смысла ставить нулевой шанс
					return;
 
				_faces.push(face);
				_chances.push(chance);
				index = _faces.lenght - 1;
			}
			else
			if(chance == 0) // грань с занулённым шансом удалим для экономии памяти
			{
				_faces.splice(index,1);
				_chances.splice(index,1);
			}
 
			_range = 0; // нужно обновить кеш
			for each (var intermediate:Number in _chances)
				result += intermediate;
		}
 
		public function roll():Number
		{
			if(!_faces.lenght) // опа, граней то нету!
				rhrow new Error("Rolling dice without faces"); // сферическая кость в ваккууме никогда бы не остановилась
 
			var fortune_charge:Number = _range * Math.random; // Holy Random is True God and only
			var lucker:Number = _faces.lenght - 1;
 
			while(lucker)
			{
				fortune_charge -= _chances[lucker];
 
				if(fortune_charge <= 0.0001)
					break;
 
				lucker--;
			}
 
			return _faces[lucker];
		}
	}
}
Если нужно работать только с целочисленными гранями, достаточно заменить только тип для _face и faces.
Так же легко работать и с целочисленными шансами, но я не думаю, что это удобно.


Последний раз редактировалось ShadowsInRain; 22.05.2011 в 01:24. Причина: UPD
Старый 22.05.2011, 00:51
mikhailk вне форума Посмотреть профиль Отправить личное сообщение для mikhailk Найти все сообщения от mikhailk
  № 9  
Ответить с цитированием
mikhailk
 
Аватар для mikhailk

Регистрация: Nov 2009
Адрес: СПб
Сообщений: 2,236
Цитата:
Я не понял, если честно? Поясните как? Пока вариант ИО элегантней :о))
Вариант с весами используется в общем виде достаточно часто.
Например, у нас есть три значения с весами 5, 3 и 2.
Получаем случайное число в промежутке 0-1, далее:
- если до 0.5 - выпало первое значение
- больше 0.5 и меньше 0.8 - второе
- больше 0.8 - третье

Старый 22.05.2011, 00:58
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 10  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
Собственно, решил сделать эксперимент интереса ради
Код AS3:
package tests 
{
	import flash.display.Sprite;
 
	/**
	 * ...
	 * @author wvxvw
	 */
	public class ProbablityTester extends Sprite
	{
		private const _variants:Vector.<uint> = 
			new <uint>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
 
		private const _weights:Vector.<uint> = 
			new <uint>[1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
 
		public function ProbablityTester() 
		{
			super();
			// position: 0 total: 99435
			// position: 1 total: 100361
			// position: 2 total: 99991
			// position: 3 total: 99921
			// position: 4 total: 99452
			// position: 5 total: 100059
			// position: 6 total: 100715
			// position: 7 total: 100259
			// position: 8 total: 99848
			// position: 9 total: 99959
			this.testDistribution();
			// exclude 5 from the pool completely
			this.setChance(5, 0);
			// position: 0 total: 111148
			// position: 1 total: 111645
			// position: 2 total: 111153
			// position: 3 total: 111161
			// position: 4 total: 111147
			// position: 5 total: 0
			// position: 6 total: 111019
			// position: 7 total: 110609
			// position: 8 total: 110869
			// position: 9 total: 111249
			this.testDistribution();
			// double the chances for 6
			this.setChance(6, 2);
			// position: 0 total: 100195
			// position: 1 total: 99949
			// position: 2 total: 99909
			// position: 3 total: 99673
			// position: 4 total: 100513
			// position: 5 total: 0
			// position: 6 total: 200260
			// position: 7 total: 99795
			// position: 8 total: 99600
			// position: 9 total: 100106
			this.testDistribution();
		}
 
		public function setChance(of:uint, to:uint):void
		{
			of = of % 10;
			this._weights[of] = to;
		}
 
		private function testDistribution():void
		{
			var results:Vector.<uint> = new Vector.<uint>(10);
			var i:int;
 
			for (i = 0; i < 1e6; i++)
			{
				results[this.selectRandom()]++;
			}
			for (i = 0; i < 10; i++)
			{
				trace("position:", i, "total:", results[i]);
			}
		}
 
		private function selectRandom():uint
		{
			var result:uint;
			var weight:uint;
			var random:uint = this.sum() * Math.random();
 
			for (var i:int; i < 10; i++)
			{
				weight = this._weights[i];
				if (random < weight)
				{
					result = i;
					break;
				}
				else random -= weight;
			}
			return result;
		}
 
		private function sum():uint
		{
			var result:uint;
			for each (var i:uint in this._weights) result += i;
			return result;
		}
	}
}
EDIT: перемудрил в первый раз
__________________
Hell is the possibility of sanity


Последний раз редактировалось wvxvw; 22.05.2011 в 01:09.
Создать новую тему Ответ Часовой пояс GMT +4, время: 02:53.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Теги
выпад , массив , Рандом , шанс

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 02:53.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.