Как устроен розыгрыш
Не просто «верьте нам, это случайно». Вот наш метод.
Победитель определяется до начала вращения колеса
При каждом вращении победитель выбирается до начала анимации, после чего колесо визуально докручивается до нужной точки. Именно благодаря такому порядку сила вашего движения пальцем или курсором никак не может повлиять на результат, а включение режима уменьшения движения выдает тот же результат без анимации, не используя отдельную ветку логики. Это также означает, что наблюдаемое вами вращение — лишь воспроизведение уже принятого решения, что является единственным способом выполнить оба наших обещания честности.
Откуда берется случайность
Источником служит криптографический генератор вашего браузера, crypto.getRandomValues, а не Math.random. Math.random может быть предсказуемым, и в некоторых движках так и есть, что недопустимо для честного розыгрыша.
Почему мы отбрасываем некоторые числа
Преобразование 32-битного случайного числа в «число от 0 до 11» через взятие остатка от деления порождает незаметную несправедливость. 2³² не делится нацело на 12, поэтому первые несколько вариантов получают один дополнительный шанс. На колесе из двенадцати секторов это смещение крошечное, но оно реально, всегда благоприятствует одним и тем же секторам и никогда не сглаживается со временем. Поэтому вместо взятия остатка мы отбрасываем любое выпавшее число из неравномерного хвоста и запрашиваем новое. Это требует редкого дополнительного вызова генератора, но гарантирует абсолютно равномерный результат.
const limit = Math.floor(2 ** 32 / max) * max;
let draw = crypto.getRandomValues(new Uint32Array(1))[0];
while (draw >= limit) {
draw = crypto.getRandomValues(new Uint32Array(1))[0];
}
return draw % max;Веса и почему размеры секторов им соответствуют
Взвешенный розыгрыш суммирует веса, выбирает равномерно распределенное число меньше этой суммы тем же методом отклонения и определяет, в какой вариант это число попадает. Затем колесо отрисовывает каждый сектор строго пропорционально его доле в круге. Колесо с одинаковыми на вид секторами при разных шансах было бы обманчивым приемом, против которого мы выступаем, поэтому площадь сектора и его шансы архитектурно равны между собой.
Ваш список никогда не покидает ваш браузер
Здесь нет учетных записей и серверного хранилища. Ваш список живет в этом браузере, а ссылки «Поделиться» содержат данные колеса прямо внутри URL. Никакие данные о розыгрыше не записываются там, где мы могли бы их увидеть.
Проверьте сами
Логика розыгрыша занимает несколько десятков строк, и каждое приведенное выше утверждение покрыто тестом, который бы упал в случае нарушения — включая тест, подающий на вход числа, специально провоцирующие смещение по модулю, и проверяющий сохранение равномерности.
Колесо вмещает до 1000 вариантов, и описанный метод работает одинаково как для одного варианта, так и для всех 1000.