Концепция случайного довольно интересна, когда вы думаете об этом с точки зрения компьютера, потому что без некоторого внешнего ввода случайное невозможно.
Компьютеры (аппаратные и программные) являются детерминированными. Это значит, что вы даете какой-то ввод и получаете вывод, и если вы повторите его, вы получите тот же результат. Случайные числа с философской точки зрения являются недетерминированными.
Таким образом, случайные функции в программном обеспечении, такие как Math.random ()
начинаются со значения seed и, грубо говоря, результат вызова случайной функции используется в качестве следующего seed, а дальше и тд. Это означает, что компьютеры могут генерировать случайную последовательность значений, но для ее запуска требуется начальное число. Хорошим кандидатом на начальное значение является, например, текущее время в миллисекундах.
В «большинстве» случаев эти псевдослучайные значения хороши, хотя, если вы хотите провести подробное чтение о генерации случайных чисел в V8, есть отличная статья на Medium под названием TIFU с использованием Math. random () (архивная копия).
Случайный для игр
В последнее время я играл со своим собственным клоном тетриса и добавил (недокументированный) вариант для двух игроков. Когда игра идет, тетромино выбираются «наугад». Однако в игре с двумя игроками оба игрока должны получить одинаковую «случайную» последовательность блоков.
Использование Math.random ()
не будет выполняться, потому что я не могу контролировать начальное значение. В этом случае я должен написать свою собственную (или копию испытанную и проверенную) случайную функцию. Таким образом, я должен установить начальное значение, когда оба игрока присоединятся.
В дополнение к этому я создал игру, в которой создается случайная раскладка доски, и если игрок решает опубликовать свой счет, программное обеспечение может взять начальное начальное значение, а последовательность ходов для проверки своего счета является законной.
Давайте напишем нашу собственную случайную функцию
Бит поиска в сети вызовет ряд различных алгоритмов для случайного число. Моя проблема в том, что я не совсем уверен, что я а) понимаю данный код и б) доверяю коду, который на самом деле делает то, что говорит.
Например, вот три функции, которые я нашел:
let seed = Дата . В настоящее время ( ) ] ;
функция randomA ( ) {
seed = ( 5 * seed + 3 ) ) ] % 16 ;
вернуть семя / 16 ; ;
}
функция randomB ( ) {
seed = ( seed * 7919 + 1 ) ] & 0xffff ;
вернуть seed / 0xffff ; ;
}
let ctr = 0 ;
функция randomC ( n = 7 ] ] {
СУУ ++
let value = ( ( ( ( seed >>] 9 ) & 1 ) ^ ( ] ( семя >> 1 ) & 1 ] ) ) << 15 ) | ( seed >> > 1 ) ;
семя = значение ;
значение >> = 8 ;
значение + = ctr ;
значение % = n ;
возвращать значение / n ;
}
Как правило, я склоняюсь к более сложной функции поиска, но она полностью основана на внешности. Читая эти функции, я не могу даже вообразить, что они делают, и запуск их в браузере на самом деле не подтвердит, являются ли их числа случайными (достаточными), даже если я запускал функции снова и снова.
Честно говоря, эти функции выглядят так, будто они объединяют числа так, как вы можете смешивать опаловые фрукты и в итоге получить какой-то цвет, который ничем не напоминает.
Здесь полезна визуализация распределения шума, создаваемого функциями. Вы могли видеть это раньше:
На этих изображениях я ищу любые визуальные шаблоны, а шаблоны плохие. Это пример «плохого» генератора случайных чисел — поскольку существует шаблон, последовательность может быть предсказана:
Первоначально я обнаружил некоторый код на Python, который генерирует изображения такого типа, но я подумал, что с HTML5-подобной технологией должно быть целесообразно запускать в браузере и даже генерировать случайный код функции на лету, чтобы получить хорошее впечатление, если мой алгоритм работает для моих целей.
Итак, набросал некоторый код и придумал этот мини-инструмент: https://random.isthe.link
Таким образом, я могу сразу увидеть эффекты трех функций:
Я уверен, что есть лучшие функции, но randomC
«достаточно хорош» для моих конкретных потребностей. Хотя интересно, что это хорошо работает для 7 значений, которые мне нужны, но когда диапазон значений увеличивается, до 7777 или даже 77777 вы начинаете видеть градиенты (которые, я полагаю, достигают верхних границ сдвига битов… но на самом деле, я я не уверен!).
Я надеюсь, что это полезный или полезный инструмент, если вы думаете о добавлении собственной случайной функции. Да, и если кто-то захочет попытаться объяснить приведенный выше код, не стесняйтесь в комментариях ниже 😉