- PVSM.RU - https://www.pvsm.ru -
Идея для Clojure Cup [1] этого года родилась примерно вот здесь:
(город Вырица, Ленобласть)
Ожидая обратную электричку мы убивали время, как могли, и грустили, что под рукой нет чего-то вроде Alias'а или Шляпы — всё же салонные игры это интеллигентнее, чем косплей гопоты в заброшке. TL;DR:
Играть: http://playthehat.com [2] (ещё с багами и не работает не на хроме, мы не можем править до окончания голосования судей)
Голосовать: https://clojurecup.com/#/apps/thehat [3]
Более длинная версия поста — ниже.
В прошлом году мы выиграли Clojure Cup в немалой части из-за того, что начали готовиться примерно за месяц. Что понимать под «готовиться»? Собрать команду; придумать идею; собрать предполагаемые библиотеки и попробовать слепить из них что-то полезное (в прошлом году это был clony [4]); порисовать дизайн и экраны на бумаге; желательно, приготовить блог и всякое такое. В этом году я слишком расслабленно подошёл к подготовке и в итоге многие вещи пришлось делать по ходу — например, выбрали идею приложения из десятка вариантов мы примерно за сутки до начала соревнований. Также команда в этом году выглядела немного по-другому (я, Саша Пантюхов [5], Саша Сорокоумов [6], Саша Шер [7]; Саша Дину [8] не смог играть с нами в этот раз), поэтому победоносное название DEFDERP [9] мы сменили на WocPocPoc [3]. Так как команда снова была распределённой (Петербург, Москва и Мюнхен), основными методами коммуникации и синхронизации усилий стали Trello, Flowdock (он крайне удобен, особенно при интеграции с GitHub'ом, Trello и деплойментом) и Google Hangouts.
Наконец, после горячей дискуссии в Hangouts к началу соревнований у нас были рисунки интерфейса на бумаге и отдалённое представление о том, что и как мы будем писать.
Мы специально взяли достаточно простую идею, планируя вместо реализации сложных алгоритмов добиться идеальной работоспособности и отполированного интерфейса. План частично оправдал себя — степень работоспособности The Hat в этом году многократно выше, чем CodeNotes в прошлом.
В первый день я занимался в основном разным инфраструктурным, пока Саша Пантюхов рисовал экраны (кстати, классный вид что CodeNotes [10], что The Hat [2] — его рук дело, зависть-зависть), а два других Саши занимались реализацией логики игры. В ходе написания выяснилось, что figwheel [11] абсолютно, сказочно божественен и очень облегчает вёрстку, особенно под несколько девайсов сразу: http://instagram.com/p/tce_F3FVe6/ [12]
Ближе к вечеру я обратил внимание, что большая часть команд уже сделала хоть какой-то landing, а мы нет, и решил быстро сделать стильную страницу и нам. Я давно хотел написать Poisson disc sampling [13], но (как это часто бывает) отладка затянулась и я потратил на это примерно в четыре раза больше времени, чем планировал. Тем не менее, после примерно 8 часов страдания получилось вот что (к чистому семплингу здесь добавлена маска из невидимого canvas'а): http://voting.playthehat.com/landing/ [14] Конечно, это overkill, но команда отлично справлялась и без меня :)
К вечеру первого дня у нас было уже рабочий, но немного глючный webapp и мы занялись деталями, составлением словарей (важная часть хорошего геймплея для игр такого рода) и тестированием.
Деталями, например, такого рода:
В какой-то момент мы поняли, что на игровом экране не очень понятно, кто сейчас ходит, а полоски с нулевым счётом смотрятся очень плохо; обе проблемы частично решились добавлением неактивной области слева, стрелка в которой обозначает текущую команду. Fun fact: мы не смогли придумать, как сделать понятный и красивый экран выбора количества команд и оставили только две.
Словарями же занялся Саша Сорокоумов. После небольшой дискуссии мы решили, что составлять их целиком руками бессмысленно, поэтому, например, для Computer Science мы взяли тексты SICP и AIMA и прошлись по ним POS-tagger'ом из Stanford CoreNLP [15], оставляя только существительные, посчитали TF-IDF, взяли не самые редкие слова и проконтролировали результат на адекватность и сложность вручную.
Во второй день Саши продолжили полировать приложение, а я занялся звуком. По правилам, которые мы адаптировали для этой игры, после окончания времени хода последнее слово могут угадывать обе команды; но тогда нужно сделать слежение за оставшимся временем более простым для второй команды. Использовать готовые WAV-файлы недостаточно стильно, поэтому нотификация синтезируется через Web Audio API [16] (плюс Vibration API [17], если он поддерживается устройством).
В процессе тестирования выяснился забавный момент: на iPhone'ах Web Audio при заходе на страницу отключен и получает возможность воспроизводить что-либо только в том случае, если это происходит в ответ на действие пользователя (например, в onClick). К счастью, после воспроизведения чего-либо в handler'е Web Audio по-прежнему остаётся активен, поэтому проблема решилась одноразовым воспроизведением очень короткого и тихого звука на touchStart.
Наверное, самым грустным моментом из всего Clojure Cup этого года для меня стало то, что в итоге в продакшн мы залили вариант с неработающим звуком. В какой-то момент мы сломали его, не заметили этого вовремя и я не успел поправить это за час до конца соревнований.
Отдельной и важной для нас целью было сделать так, чтобы приложение работало максимально хорошо даже при сомнительном качестве мобильного коннекта. Отсюда вытекает решение заинлайнить в итоговый .js словари, тщательная минимизация количества загружаемых файлов (один .js, один .css и шрифт), выставленный в максимум expires в nginx'е (мы добавляем часть хеша статики в url'ы в процессе деплоймента для cache busting) и компрессия. Удивительно, но в Интернете очень мало (по сравнению со сжатием «на лету») упоминается модуль gzip_static, отдающий .gz-версии статических файлов, если они есть; вся наша статика сжата с gzip -9 при деплойменте.
За несколько часов до конца я открыл для себя HTML5 AppCache [18] и ВНЕЗАПНО прикрутил его, попутно подперев наш деплоймент дополнительным костылём вида
echo "# `date`" >> cache.manifest
чтобы заставить клиентские браузеры всё-таки вытягивать обновлённую версию приложения. Благодаря этому The Hat отлично работает даже в Airplane Mode: http://instagram.com/p/tgl4tCFVdZ/ [19]
Наконец, незадолго до конца мы сделали то, что хотели сделать ещё в прошлом году — записали демо-видео:
Возможно, чуть позже мы выложим нарезку из неудавшихся дублей, которых было около десяти :)
Планы на будущее (когда голосование судей закончится):
В целом я очень доволен Clojure Cup этого года, несмотря на то, что и в пользовательском голосовании [20], и в голосовании жюри The Hat прямо сейчас не очень популярен (здесь должна быть картинка с грустной пандой). Я узнал много нового, написал много хорошего кода в замечательной компании (спасибо, Саши, вы очень крутые!) и принял участие в написании приложения, которое сам же и буду использовать. Кроме того, сам Clojure Cup отлично организован что в этом году, что в прошлом — очень рекомендую принять участие в следующем году!
И да, последнее, но тоже важное: проголосуйте за нас на https://clojurecup.com/#/apps/thehat [3], залогинившись через твиттер :)
Автор: si14
Источник [21]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/70866
Ссылки в тексте:
[1] Clojure Cup: http://clojurecup.com
[2] http://playthehat.com: http://playthehat.com
[3] https://clojurecup.com/#/apps/thehat: https://clojurecup.com/#/apps/thehat
[4] clony: https://github.com/si14/clony/
[5] Саша Пантюхов: https://twitter.com/alwxtwi
[6] Саша Сорокоумов: https://twitter.com/ASorokoumov
[7] Саша Шер: https://github.com/sherpc
[8] Саша Дину: https://twitter.com/aluuu
[9] DEFDERP: http://2013.clojurecup.com/
[10] CodeNotes: https://codenotes.me
[11] figwheel: https://github.com/bhauman/lein-figwheel
[12] http://instagram.com/p/tce_F3FVe6/: http://instagram.com/p/tce_F3FVe6/
[13] Poisson disc sampling: http://www.jasondavies.com/poisson-disc/
[14] http://voting.playthehat.com/landing/: http://voting.playthehat.com/landing/
[15] Stanford CoreNLP: http://nlp.stanford.edu/software/corenlp.shtml
[16] Web Audio API: https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API
[17] Vibration API: https://developer.mozilla.org/en-US/docs/Web/Guide/API/Vibration
[18] HTML5 AppCache: https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache
[19] http://instagram.com/p/tgl4tCFVdZ/: http://instagram.com/p/tgl4tCFVdZ/
[20] пользовательском голосовании: http://voting.playthehat.com/
[21] Источник: http://habrahabr.ru/post/239191/
Нажмите здесь для печати.