RU 📌 Pinned

Как сделать?

Dark[Ol(U23)leneri] #34 18.04.2010 22:57 6408 comments 2424884 views

Злой Механик #2702 17.09.2023 07:18 (2 years ago)

Как сделать в QSP генератор псевдослучайных чисел?
“Нормально никак не сделать… Можно конечно, написать высокоуровневые преобразования в двоичное представление, а потом ещё всякие там XOR’ы, да shift’ы туда-сюда. Правда это может не потянуть вычислительный бюджет конкретной задачи…”
А, если еще сделать так, что RNG не последовательный (да ещё сохраняет ключ для следующей генерации), а например принимает еще 2 произволных аргумента, и мы можем сразу взять 100500-е значение?
“Ну, тогда можно написать высокоуровневые преобразования для двойной точности, к ним в догонку полиноминалы для тригонометрии, а потом как например в некоторых шейдерах - cosine (относительно скоростные) мумбо-юмбо, там ведь как раз-таки координаты пикселей используются. Но с вычислительным бюджетом проблем только прибавится…”
Ну раз так, тогда хочу всё то же самое, но без высокоуровневых костылей и изоленты.
“Иди-ка ты на *** с такими замашками!”

Цена вопроса:
- RNG, промежуточные ключи генерации нафиг не должны быть (их ведь ещё складывать куда-то надо).
- У нас есть только математика QSP +*[mod] (только хардкор, только так)
- Числа 32-битные, знаковые целые (однако, минимальное отрицательное, похоже прикрыто! уже что-то)
- Скорость максимальная (Вообще это отдельная тема, но сегодня пощадим нейроны).
- Значит, пермутатация будет нихрена не “косиновая” как в пиксельных шейдерах обычно делают…
- а ещё скажем твёрдое “нет” XOR-shift’ам и прочим “мурмурам”…
Теперь, если приглядеться: Умножение-то с переполнением! Как впрочим и сложение. Остаток от деления - тоже в наличии. А про простые числа даже в лесу слышали.

Так, есть ли в природе такой метод для QSP, или нет (без высокоуровневых преобразований)?
Есть как минимум один!
Только перед этим примем вынужденное условие: метод не подходит для научного, промышленного, военного применения.
Т.е. не будем исползовать в качестве решения в профессиональной криптографии, квантовой физике, разработке вооружений и всего такого прочего, однако нам с избытком хватит для компьютерных игр.
Плюсом является скорость - примерно 28 “обычных” QSP операций.

Используется как: number = func(”f_rng_2d”, seed, min, max, x, y)

if (args[3] = 0): args[3] = 13763
if (args[4] = 0): args[4] = 10613
args[0] += args[3] * args[3] * args[4]
args[0] *= args[4] * args[4] * args[3]
args[0] += args[4]
args[0] = (args[0] * 16807) mod 127773
args[0] += args[3]
if (args[0] < 0): args[0] += 2147483647
args[0] = ((args[0] mod 127773) * 16807) mod 127773
args[0] = (args[0] * 16807) mod 127773
result = args[1] + ((max(args[1], args[2]) - args[1] + 1) * (args[0] - 1) / 127772)

Ниже прикреплён файл с примером.
_test_rng_2d.rar

seed - произволная величина, условно “карта” генерации.
min, max - как и в rand() и с тем же умыслом.
x, y - дополнительные числовые аргументы.
При одном и том же сиде, для одних и тех же x и y, результат (очевидно, ведь в этом и весь смысл) гарантирован.
При изменении сида даже на единицу - avalanche effect гарантируется.

Для турбо-мудрых: Существут проблема “хорошего” сида, очень похожая на ту, что есть в XOR-shift алгоритмах. Однако в масштабах компьютерных игр, никто ничего не заметит (впрочем как и в случае с XOR-shift). Так же поскольку ВСЯ пермутация производится в 32-битных величинах (!), не стоит использовать экстремальные (в бинарном аспекте) значения x и y. Но всё работает достаточно хорошо, и границу (в десятеричном выражении) я бы обозначил на десятках миллонов. При больших значениях (миллиард), могут начать проявляться паттерны.

Из-за очень высокой скорости алгоритма, можно использовать полученную псевдо-случайную величину как сид для повторных генераций, иммитируя реально космически-гигантские объемы данных. Вообще я ничего не написал про применение, считая что все кому надо и так знают. Для тек кто не понял - пример: карта выдуманной случайно сгенерированной галактики (но по размеру приблеженной к реальной) в компьютерной игре может занимать… одно число (сид). Или как записать квадриллион случайно сгенерированных свойств… опять-таки одним числом (сидом), а потом еще и разом получить любое из них. Теперь вы видите, как “они это делают”.
Все дело в распределении результатов - оно ни на бит не случайное(!), но НАСТОЛЬКО приближенно к нему, что без статистичеких метов анализа, никто и никогда не поймет. Вот именно в этом и есть вся суть ВСЕХ подобных алгоритмов.

(Злой Механик)

Дамир Белялов #654 17.09.2023 17:01 (2 years ago)

Сделал по старинке через раздел, убрал loop. Скажите, получается я еще и массив неправильно прописал? Мне нужен капитальный массив с координатами и типом объекта, а плеер мне пишет про ошибку синтаксиса.

! Общая генерация границ мира
max_X[1]=24 & !допустим это максимальные границы карты №1
max_Y[1]=24
x_a=1
y_a=1
!Случайное наполнение
y_a=1
:loopY 
x_a=1
:loopX 
type_sym=rand(1,5)
if type_sym=1: $x[x_a,y_a,map,'символ']='<font color="gray">.</font>' & $x[x_a,y_a,map,'описание']='камушки' & $x[x_a,y_a,map,'тип']='поверхность'
if type_sym=2: $x[x_a,y_a,map,'символ']='<font color=rgb(80,50,50)>.</font>' & $x[x_a,y_a,map,'описание']='пол' & $x[x_a,y_a,map,'тип']='поверхность'
if type_sym=3: $x[x_a,y_a,map,'символ']='<font color="green">ш</font>' & $x[x_a,y_a,map,'описание']='куст' & $x[x_a,y_a,map,'тип']='поверхность'
if type_sym=4: $x[x_a,y_a,map,'символ']='Т' & $x[x_a,y_a,map,'описание']='дерево' & $x[x_a,y_a,map,'тип']='стена'
if type_sym=5: $x[x_a,y_a,map,'символ']='.' & $x[x_a,y_a,map,'описание']='пол' & $x[x_a,y_a,map,'тип']='поверхность'
if x_a<=max_X[1]: x_a+=1 and jump'loopX'
if y_a<=max_Y[1]: y_a+=1 and jump'loopY'

ByltrcДамир Белялов,
Индекс исправь - [x_a,y_a,map,’символ’] -> [’<<x_a>>,<<y_a>>,<<map>>, символ’]

Дамир Белялов #654 18.09.2023 09:30 (2 years ago)

Привет! Спасибо массив перестал вылетать. К сожалению, карта из символов не прорисовывается. То ли массив не записывается, то ли я неграмотно его записал, опечатался, но я снова облажался, увы. Может у вас взор незамыленный, сможете найти, почему не прогружается рандомное наполнение мира. У меня из-за этой поганой сетки стоит проект весь((
Основные локации связанные с проблемой это boot ($scr_map_draw), gen_world, travel - на ней по идее должна была нарисоваться карта для игрока.
project.zip

Дамир Белялов,
x y у тебя где задается? У тебя они равны 0, а для значений меньше единицы массив не заполнен.

Дамир Белялов #654 18.09.2023 11:52 (2 years ago)

задается в локации gen_world в цикле, в начале процесса x_a=1 потом в цикле при x_a<maxX[1] переменная x_a+=1 и снова цикл выполняется

Дамир Белялов,
Ты для отрисовки карты используешь переменную x, а не x_a.

Дамир Белялов #654 18.09.2023 11:59 (2 years ago)

Придётся все-таки заменять? Я думал воспользуюсь временно при генерации переменной x_a, а персонаж когда будет перемещаться то буду использовать x.

Дамир Белялов,
Нет, это разные переменные для разных целей.
Можешь в дискорд зайти? а то мы весь форум зафлудим.
У тебя x_a для генерации, а x - для отрисовки от центра карты, как я понял. Но центр у тебя сейчас не указан и является нолем. У тебя не существует значений масиива для значения 0 и меньше. А ты просишь рисовать 0, -1, -2.

Дамир Белялов #654 18.09.2023 12:13 (2 years ago)

центр в отрисовке показан символом @, но на самом деле координата должна быть сгенерирована, у меня вся карта по идее 24 на 24 сгенерирована.

Дамир Белялов,
$x[’<<x-2>>,<<y-2>>,<<map>>, символ’]
Вот твоя переменная для отрисовки тайла. У тебя x=0, y=0
$x[’<<-2>>,<<-2>>,<<map>>, символ’]
Вот что получает плеер.
Где у тебя значение тайла для этого элемента массива?

Дамир Белялов #654 18.09.2023 12:26 (2 years ago)

локация ‘Office’ действие “Выйти” при выполнении действия x=12 y=12

Дамир Белялов,
Отбой тревоги), это я напрямик в локу защел. У тебя в генераторе map не задан, т.е. 0, а в параметрах ты просишь 1, либо в генератор добавь map=1 либо при переходе на карту map=0.

Дамир Белялов #654 18.09.2023 12:32 (2 years ago)

Ооооо, хвала богам, косо криво но мы справились, спасибо тебе. Ты часом не знаешь как ровненько символы выстроить, ну кроме таблицы?

Дамир Белялов,
Никак. Либо таблица, либо выбор одноразмерных символов, либо вместо символов - картинки одинакового размера.

Log in or Register to post comments.