![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
random збесился. что делать? [Delphi, Windows]
Tsaiper © (2004-05-03 20:51:00)Делаю игрульку. Пошаговая стратегия. Почему-то при битве юнитов генератор стал выдавать несколько одинаковых случайных значений подряд, хотя процедура randomize запускается при каждом вызове функции ближнего боя. Юнит или пробивает броню при каждом ударе, или ни один удар не доходит до цели. Почему - не понятно :(
Помогите!
Proger (2004-05-06 16:34:00) [1]2 Tsaiper ©.Дай ты этому random'у успокоительное :)
TButton (2004-05-06 10:06:00) [2]re 19
это типа как в максе, с одинаковым RandomSeed два эффекта будут выглядеть абсолютно одинаково сколько их не рендери.
Twinge (2004-05-06 01:41:00) [3]Дополнение Kobik
В первый раз random(x) всегда выдает 0 если не используется randomize. random(0) - вот те и глюк... а лучше напиши
random(random(100) +1);
Ермак (2004-05-05 20:30:00) [4]Нельзя вызвать Рандомайз повторно. Алгоритм генерации случайных чисел на самом деле псевдослучаен, каждое последующее число ОДНОЗНАЧНО выводится из предыдущего. Используется хитрый (но не особо-то сложный) алгоритм деления по модулю на подобранные простые числа. Это дает ооо-чень длинную (но заранее предопределенную) последовательность чисел. Ее период (то есть длина, на протяжении которой числа не повторяются), если не ошибаюсь, равен 2 в степени разрядности используемых чисел (т.е. 2 в 32). Рандомайз же только выбирает, С КАКОГО МЕСТА этой длинющей последовательности Рандом начнет выдавать числа. Естественно, если Рандомайз вызвать несколько раз рядом, то и выданы будут числа с одного куска.
Если иметь мозги на плечах и книжку под рукой, можно за пять минут сваять свой генератор псевдослучайных чисел.
А вообще, дискретная математика - рулез!
TButton (2004-05-05 00:17:00) [5]>Потому что нельзя сделать random(0);
>А random(100) принимает значения от 0 до 99
резонно... я как-то не задумывался о том =)
Kobik (2004-05-04 18:50:00) [6]>>кстати, никто не знает почему
>>random(random(100));
>>или
>>
>>n:=random(100);
>>z:=random(n);
>>вызывают переполнение стека???
Потому что нельзя сделать random(0);
А random(100) принимает значения от 0 до 99
Tsaiper (2004-05-04 15:06:00) [7]ОК, спасибо всем!
буду пробовать
NailMan (2004-05-04 14:04:00) [8]Sirgfine
есть такая функция - RandG. В модуле Math объявлена. Разберись с ней и у тебя никогда не будет проблем с генерацией случайных чисел. Ещё можешь использовать now (например последних две цифры дробной части) тоже совпадений не может быть.
RandG выдает вещественные числа, а конвертить каждый раз real->dword навено будет лень.
Тем более RandG работает на том же самом Random.
Tsaiper ©
Советую использовать не стандартный Randomize(который действительно надо запускать один раз), а несколько другой:
Procedure MyRandomize;
begin
asm
push eax
push edx
RDTSC
mov dword ptr randseed[0],eax
pop edx
pop eax
end;
end;
В качестве Randseed берет не системное время, а младшую половину 64-битного счетчика тактов процессора. Уж оно-то будет у всех всегда разное :-)
Его можно впихивать хоть перед каждым вызовом Random, т.о. получишь хорошую последовательность.
Я этим генератором Randseed получаю довольно правдоподобное звездное небо в демке.
Единственное но использования вышеприведенной процедуры: процессор должен поддерживать команду RDTSC, т.е. от пентиума и выше.
Tano (2004-05-04 13:24:00) [9]Random - псевдослучайная функция и опирается на системное время (до миллисекунд). Если вызывать слишком быстро друг за другом, то чем быстрее комп, тем менее случайная последовательность получиться. Randomize вызывай один раз на старте проги.
или
Используй из Math.
miek (2004-05-04 10:37:00) [10]Неплохо бы знать механизм генерации случайных чисел.
Randomize это то же самое, что RandSeed:= GetTickCount;
MeF88 (2004-05-04 08:56:00) [11]
> procedure random(amout:Word);
Ой извиняюсь первую строчку читать как:
function random(amout:Word):Word;
TButton (2004-05-04 02:20:00) [12]Когда и где такое было у тебя? Я попробовал код, всё работает без проблем.
было. в одном из старых проектов ушедших в небытье после того как Rовцы похерили мне винт. насчет второго не уверен, но первый вызывал ошибку стопудово. а использовалось оно для создания случайного числа в пределах от одного до 100, с таким условием, что чем больше число тем реже оно должно встречаться. далее на базе этого числа создавалась шмотка. это, если кто знает, был у меня проект RealHero. вот в нем это все происходило.
MeF88 (2004-05-04 00:56:00) [13]
> Когда и где такое было у тебя? Я попробовал код, всё работает
> без проблем.
Свободно работает. ;) Если ты конечно не создавал что-то вроде
procedure random(amout:Word);
begin
result:=random(random(100));
end;
;)
> Randomize не нужно каждый раз вызывать. Нужно вызывать один
> раз где-нибудь в OnCreate формы или даже в файле проекта
> при инициализации.
МОжет быть в этом и причина, что randomize вызываешь каждый раз...
Sirgfine (2004-05-04 00:20:00) [14]есть такая функция - RandG. В модуле Math объявлена. Разберись с ней и у тебя никогда не будет проблем с генерацией случайных чисел. Ещё можешь использовать now (например последних две цифры дробной части) тоже совпадений не может быть.
Короче думай, как избежать препятствий, а не ломай голову над их тараном.
Mihey (2004-05-03 23:17:00) [15]> TButton © (03.05.04 22:19) [6]
Когда и где такое было у тебя? Я попробовал код, всё работает без проблем.
TButton (2004-05-03 22:37:00) [16]кстати, рандомайз по умолчанию делается по текущему времени. так что подожди, мож само пройдет =)
TButton (2004-05-03 22:19:00) [17]кстати, никто не знает почему
random(random(100));
или
n:=random(100);
z:=random(n);
вызывают переполнение стека???
Mihey (2004-05-03 21:46:00) [18]Randomize не нужно каждый раз вызывать. Нужно вызывать один раз где-нибудь в OnCreate формы или даже в файле проекта при инициализации.
Tsaiper (2004-05-03 21:42:00) [19]Вершиной моих усилий по избавлению от глюка стала ф-ция следующего вида:
function random22(x: byte): byte;
var
a: byte;
begin
a:=random(x);
repeat
Randomize;
result:=random(x);
until result<>a;
end;
я пробовал давать ей сгенерить 6 значений подряд от 1 до 6, и она выдавала мне строчки наподобие 666661 или 555544. Кашмар!
От глюка удалось избавиться, удалив вызовы Randomize из ключевых (т.е. почти из всех) мест. Вот. Не знаю, кто глючит - я, компутер или делфи, но вот оно как...
чушь какая-то!
TButton (2004-05-03 21:33:00) [20]и Randomize не забывай