Нет лототрона, как быть? JavaScript генератор случайных чисел

Как провести розыгрыш призов если у тебя нет лототрона?! Сделай на javascript'е случайную сортировку массыва

Йо-йо! 18.05 я побывал на мастер-классе Максима Батырева «Менджре и команда». О своих впечатлениях я рассказал у себя в дзен-блоге. Компания в которой я работаю являлась официальным партнёром мероприятия и мы разыгрывали год хостинга бесплатно.

Инициатива розыгрыша призов исходила от организаторов мероприятия. Мы напечатали билеты (о том как печатал билеты), нарезали их и…. и оказалось, что у них нет лототрона. Мы долго искали аренду этой штуки, но так и не нашли (за приемлемую плату).

Что делать если у тебя нет лототрона, а ты из it-компании?!) Правильно! — писать рандомную сортировку!

Процесс

Самое важное в такой штуке как розыгрыш призов — это действительный рандом. Тут не должно быть факторов, которые могли бы вызвать подозрения.

Истинный рандом

Я уже раньше использовал генератор случайных чисел для случайной сортировки элементов (пример). Но там была самая простая версия рандома. Позже я нашёл статью на habr, в которой нашёл «супер-функцию», для получения истинно случайного числа. После этого я создал более продвинутую версию.

Собственно как выглядит в итоге функция для случайной сортировки элементов:

function putToCache(elem, cache){
    if(cache.indexOf(elem) != -1){
        return;
    }
    var i = Math.floor(Math.random()*(cache.length + 1));
    cache.splice(i, 0, elem);
}
function madness(){
    var cache = [];
    return function(a, b){
        putToCache(a, cache);
        putToCache(b, cache);
        return cache.indexOf(b) - cache.indexOf(a);
    }
}
// Собственно сама функция сортировки
function shuffle(arr){
    var compare = madness();
    return arr.sort(compare);
}

Когда у меня была готовая сортировка элементов, я перешёл к более лёгким вещам.

Сортировка и объявление билетов

Так как у меня было 350 билетов и я просто их создал в цикле.

childs = [];
for(var i = 1; i < 351; i++){
	childs.push(i);
}

Если у вас есть конкретные имена номера билетов, то вы можете их объявить в массиве.

Разметка и обработка нажатия

Я создал небольшую разметку. Её было достаточно

<div id="result">
			0
</div>
<div id="btnBlock">
    <button id="btn">Выбрать победителя</button>
</div>

И написал немного стилей для наглядности

div#result {
  font-size: 60vh;
  text-align: center;
}
#btnBlock {
  text-align: center;	
}

Далее в js нашёл элементы и на кнопку повесил обработчик нажатия

const btn = document.getElementById('btn')
const result = document.getElementById('result');
btn.addEventListener('click', ()=>{
 // Действия по нажатию
});

Эпичность прокрутки номеров

Для того чтобы создать эмоциональную напряжённость, нужно было создать прокрутку номеров.

Схематически она работает так: При нажатии я показываю случайные номера с некоторым интервалом, спустя некоторое время я отключаю прокрутку номеров и показываю победителя.

Как это выразить в коде

// Объявляю интервал и записываю его в переменную
const interval = setInterval(()=>{
	childs = shuffle(childs);
        // Записываю случайный номер в блок с результатом
	result.textContent = childs[0];	
}, 50);
setTimeout(()=>{
	// Удаляю интервал
	clearInterval(interval);
	// Получаю опять заново отсортированный массив
	childs = shuffle(childs);
	// Записываю его в результа
	result.textContent = childs[0];
}, 2000); // 2 секунды, можно больше

Вуаля! Всё готово!

Результат

See the Pen Розыгрыш призов по билетам by xakplant (@xakplant) on CodePen.

P.S.

Смекалка рулит! Не унывайте в непредвиденных ситуациях, вы же it-шники. Кстати, скоро релиз SJ v0.5.0. Там я добавил адаптивность!