close

Вход

Забыли?

вход по аккаунту

Ковалев Никита Сергеевич. Разработка автоматизированной системы проведения квеста «Дозор» на основе API Telegram

код для вставки
АННОТАЦИЯ
ВКР 62 с., 27 рис., 1 табл., 10 источников, 1 прил.
ГОРОДСКИЕ КВЕСТЫ, ДОЗОР, TELEGRAM API, СОЗДАНИЕ БОТОВ,
МЕССЕНДЖЕР, ПОДСЧЕТ РЕЙТИНГА, PYTHON, ФОРМАТ JSON.
Выпускная
квалификационная
работа
посвящена
разработке
автоматизированной системы проведения квеста «Дозор» на основе API Telegram.
В первой главе выпускной квалификационной работы приведено описание
городских квестов, история их появления и существующие форматы игр. Были
рассмотрены уже готовые проекты по организации городских квестов. В ходе
анализа аналогов были выделены ключевые параметры для разрабатываемой
системы, выявлены функциональные и нефункциональные требования к системе.
Во второй главе была разработана архитектура системы проведения квеста
«Дозор». Составлена функциональная и информационные модели, описана
структура базы данных.
В третьей главе приведена структура ПО. Разработаны модули диалога с
пользователями
и
модуль
администрирования,
описаны
механизмы
взаимодействия с пользователями системы. Спроектированы основные алгоритмы
и структуры данных для функционирования системы.
В четвертой главе представлена программная реализация основных
механизмов проведения квестов, а также показана реализация системы резервного
сохранения текущего процесса игры.
Графическая
часть
выпускной
квалификационной
работы
включает
иллюстрации, таблицы, которые объединены в презентацию PowerPoint.
Библиографическая часть выпускной квалификационной работы включает в
себя 10 источников.
4
СОДЕРЖАНИЕ
ВВЕДЕНИЕ
6
1 ИССЛЕДОВАНИЕ ПРОЦЕССОВ ПРЕДМЕТНОЙ ОБЛАСТИ
АВТОМАТИЗИРОВАННОЙ СИСТЕМЫ ПРОВЕДЕНИЯ КВЕСТОВ «ДОЗОР» 8
1.1 Описание предметной области
8
1.2 Обзор аналогов
10
1.3 Функциональные требования
17
1.4 Нефункциональные требования
18
2 ПРОЕКТИРОВАНИЕ АВТОМАТИЗИРОВАННОЙ СИСТЕМЫ
ПРОВЕДЕНИЯ КВЕСТОВ «ДОЗОР»
19
2.1 Архитектура системы
19
2.2 Функциональное моделирование
20
2.3 Диаграмма переходов состояний
22
2.4 Проектирование базы данных
23
3 ПРОЕКТИРОВАНИЕ АВТОМАТИЗИРОВАННОЙ СИСТЕМЫ
ПРОВЕДЕНИЯ КВЕСТОВ «ДОЗОР»
29
3.1 Структура ПО
29
3.1.1 Модуль диалога с пользователем
29
3.1.2 Модуль создания игр и администрирования
30
3.2 Проектирование алгоритмов
31
3.2.1 Алгоритм регистрации команды
31
3.2.2 Алгоритм цикла игры
32
3.2.3 Алгоритм старта игры
34
3.2.4 Алгоритм проверки пользовательских ответов
35
3.3 Проектирование пользовательского интерфейса
36
3.4 Проектирование структур данных
36
4. РЕАЛИЗАЦИЯ АВТОМАТИЗИРОВАННОЙ СИСТЕМЫ ПРОВЕДЕНИЯ
КВЕСТОВ «ДОЗОР».
38
4.1 Выбор инструментальных средств разработки
38
5
4.2 Реализация механизма регистрации
40
4.3 Реализация механизма старта игры
41
4.4 Реализация механизма проверки ответов пользователя
43
4.5 Реализация механизма сохранности данных
46
ЗАКЛЮЧЕНИЕ
48
СПИСОК ИСПОЛЬЗОВАННОЙ ЛИТЕРАТУРЫ
49
ПРИЛОЖЕНИЕ А ЛИСТИНГ ПРОГРАММНОГО КОДА
50
УДОСТОВЕРЯЮЩИЙ ЛИСТ К ВЫПУСКНОЙ КВАЛИФИКАЦИОННОЙ
РАБОТЕ
60
ИНФОРМАЦИОННО-ПОИСКОВАЯ ХАРАКТЕРИСТИКА ДОКУМЕНТА НА
ЭЛЕКТРОННОМ НОСИТЕЛЕ
61
6
ВВЕДЕНИЕ
В 21 веке все привычные сферы жизни стали изменяться с помощью
информатизации некоторых процессов. Спорт не остался в стороне. Например,
спортивное ориентирование. Появление гаджетов, онлайн-карт, навигаторов
привело к усовершенствованию этого вида спорта, а в купе с жаждой
экстремальных ощущений, привело к созданию к городским квестам.
Квест (англ. quest) – жанр игры, сочетающий в себе различные
интеллектуальные задачи, сопровождающиеся одним сюжетом. Задачи могут быть
абсолютно разными, начиная от ребусов, заканчивая абстрактной логикой. Данный
жанр получил огромное распространение в компьютерных играх.
Спортивное ориентирование — вид спорта, в котором участники при помощи
спортивной карты и компаса должны пройти неизвестную им трассу (дистанцию)
через
контрольные
пункты,
расположенные
на
местности.
Результаты
определяются по времени прохождения дистанции (в определённых случаях с
учётом штрафного времени) или по количеству набранных очков.
Городской квест – вид активной игровой деятельности, сочетающий в себе
как спортивное ориентирование, так и интеллектуальную составляющую квестов.
Такие игры развивают как физическую форму участников, так и мышление. В
процессе игры так же налаживаются взаимоотношения внутри команды, в
результате чего многие компании используют квесты как метод тимбилдинга.
В настоящее время набирают популярность различные виды городских
квестов, как постоянно действующих лиг, так и корпоративных. Однако,
большинство игр проводится либо с помощью неудобных для пользователей и
авторов игр платформ, за большую стоимость.
Актуальность разработки системы автоматизированного проведения квестов
обусловлена следующими факторами:

проведение игр на различных платформах, которые не имеют удобства
как в пользовании, так и создании;
7

большая стоимость игр для проведения корпоративных игр для
маленьких компаний;

платформы имеют сильную зависимость от хорошего интернета, хотя
не везде в городе есть устойчивая сеть.
Целью данной работы является повышение эффективности процесса
проведение квеста «Дозор» за счет уменьшение нагрузки на интернет-траффик во
время проведения квеста и уменьшение времени, необходимого на создание
сценариев игр. Для достижения данной цели необходимо решить ряд задач:

провести анализ предметной области проведения квестов «Дозор»;

осуществить анализ существующих видов и принципов проведения
городских квестов;

построить функциональную модель и определения;

определить функциональные и не функциональные требования к
разрабатываемой системе проведения городских квестов;

разработать модель базы данных;

спроектировать схему логики диалога с пользователем;

выбрать средства для разработки системы проведения городских
квестов;

реализовать систему автоматизации проведения городских квестов.
8
1 ИССЛЕДОВАНИЕ ПРОЦЕССОВ ПРЕДМЕТНОЙ ОБЛАСТИ
АВТОМАТИЗИРОВАННОЙ СИСТЕМЫ ПРОВЕДЕНИЯ КВЕСТОВ
«ДОЗОР»
1.1 Описание предметной области
Городские квесты – спортивно-интеллектуальные состязания, связанные с
ориентированием в городской среде, нахождением определенных скрытых точек и
решением различных загадок. Игроки в команде делятся по ролям, за которые они
ответственны. Обычно игроков разделяют на «полевиков» и «штабных». «Поле» в
данном случае означает локации, где нужно выполнить задания или что-то найти,
чем занимаются «полевые», а «штаб» в это время решает загадки и координирует
«полевых» в городе, указывая места локаций. Наличие «полевой» или «штабной»
части заданий не обязательно и зависит от типа игры и его сценария.
Квесты подразделяют:
По количественному признаку играющих на:

индивидуальные;

командные.
По способу передвижения:

пешие;

велосипедные;

автомобильные.
Командные автомобильные квесты бывают:

однобортовые (одна команда – один автомобиль и не более 5 человек
«в поле»);

многобортовые (одна команда – несколько автомобилей, как с
ограничением по количеству играющих, так и без).
По способу прохождения:

линейный
(есть
выдаются один за другим);
определенный
порядок
прохождения,
уровни
9

штурмовые (доступны сразу все уровни, команды сами решают
последовательность прохождения).
Так же существуют различные правила и сценарии игры. Ниже будут
описаны самые популярные типы квестов (названия взяты из проекта Encounter)

схватка;

точки;

мозговой штурм;

фотоохота;

кэшинг.
«Схватка» представляет собой многобортовую автомобильную игру с долгим
прохождением (более 5 часов) обычно с сильной нагрузкой как на полевых, так и
на штабных игроков.
«Точки» представляют собой упрощенную версию «Схватки» для одного
экипажа. Обычно в таких играх меньше продолжительность (менее 4 часов) и
практически нет нагрузки для штабных игроков.
В обоих вышеперечисленных типах игры на локациях особым образом
написаны коды, которые должны найти полевые игроки. При этом, существуют
различия как по способам написания кодов: размер кодов (от больших кодов,
написанных баллоном, до «пикселей», написанных миллиметровым маркером),
цвет, место нанесения и способ скрытия (видно на уровне глаз, нужно куда-то
залезть, нужно что-то покрутить или сделать), так и по логике самих кодов.
Например, ложные коды – их не нужно отсылать в движок, они нужны для
запутывания команды; штрафные коды – за посыл таких кодов команда получает
штраф по времени; нестандартные коды – перед посылом их нужно как-то
преобразовать, чтобы код был принят.
«Мозговой
штурм»
-
тип
игры,
в
которой
присутствует
только
интеллектуальная часть. В нее можно играть где угодно, где есть устройство с
выходом в сеть Интернет, так как нет необходимости передвигаться по локациям
10
игры. «Мозговой штурм», как и другие типы квестов, бывает командный и
индивидуальный.
«Фотоохота» - режим игры, в котором командам необходимо сделать
фотографии по определенным описаниям. Чем точнее фотография подходит под
описание, тем больше баллов получает команда. При этом некоторые пункты
описания заставляют команды творчески подойти к процессу создания
фотографий.
«Кэшинг» отличается от «Схватки» и «Точек» тем, что вместо кодов команды
должны будут найти определенное место, где спрятан или зарыт клад. Команда,
которая первой находит этот клад, не только побеждает, но и имеет право забрать
себе его содержимое.
1.2 Обзор аналогов
Чтобы выделить преимущества разрабатываемой системы необходимо
рассмотреть аналоги, в качестве которых выступают различные уже готовые
проекты проведения квестов.
DoZor – один из двух основных проектов по организации городских квестов
на территории СНГ. Первая игра была проведена 11 июня 2005 года в СанктПетербурге. С тех пор проект активно развивался и набирал большую аудиторию
пользователей. Основные типы игры, которые проводятся на этом проекте –
«Схватка» и «Точки». Раньше так же был популярен «Мозговой штурм», но сейчас
интерес к этому режиму игры сильно спал. Несмотря на ажиотаж, у данной
платформы есть ряд недостатков. Это, в первую очередь, далеко не самый
дружелюбный интерфейс. Как говорят некоторые игроки, найти поле на сайте для
ввода ответа иногда становится отдельным квестом. Не самый удобный интерфейс
для создания игр так же является одним из больших недостатков. Еще одним
минусом является низкая вариативность движка. Это означает, что игры типа
«Схватка» и «Мозговой штурм» не имеют никакой разницы в техническом плане,
что не позволяет создавать комплексные и интересные задания. Так же одним
11
существенным недостатком является слабая адаптированность сайта под
мобильные платформы. Интерфейс сайта можно увидеть на рисунках 1.1 – 1.3
Рисунок 1.1 – Основной интерфейс Dozor
12
Рисунок 1.2 – Пример логического задания в Dozor
Рисунок 1.3 – Анонс предстоящей игры в Dozor
13
Encounter – проект, ставший основным на текущий момент по организации
городских квестов в СНГ. Эта платформа стала настолько популярной, что даже в
Европе люди с удовольствием играют и создают игры на этом движке. В отличии
от
«Дозора»,
проект
обладает
более
дружелюбным
интерфейсом
и
многофункциональной системой организации, что позволяет создавать игры с
более сложными и интересными заданиями. Поэтому количество игр «Мозгового
штурма» соизмеримо со «Схваткой» и «Точками», так как платформа имеет разные
приложения для организации игр разных типов. Еще одним плюсом является
адаптивная верстка, позволяющая удобно играть с телефона. Однако, высокая
стоимость создания игры и комплексный интерфейс создания сценария, с которым
нужно долго разбираться из-за обилия функций, а также достаточно «тяжелый» для
интернет-траффика сайт, не позволяют использовать данный движок для малых
компаний и организаций квестов «для друзей». Интерфейс Encounter можно
увидеть на рисунках 1.4 – 1.6
Рисунок 1.4 – Пример задания в Encounter
14
Рисунок 1.5 – Анонс игры в Encounter
Рисунок 1.6 – Пример интерфейса Encounter
15
Lampagame – относительно новый проект, создаваемый группой энтузиастов
квестового движения. Основной целью проекта стало привлечение как можно
большего числа людей для участия в городских квестов. Для этого был создан
простой и понятный интерфейс пользователя и создателя игр. При этом
функционал редактора был изначально достаточно скуден. До недавнего времени
платформа была бесплатной, сейчас появились цены на создание игр типа
«Схватка», «Точки», «Мозговой
штурм».
Приятной особенностью стала
возможность создания простых игр для одной команды – «Тренировка» - что
позволяет использовать данную платформу для проведения корпоративных игр для
маленькой компании. Проект активно разрабатывается и с каждым месяцем
расширяется его функционал и возможности. При всех таких плюсах у проекта есть
огромный минус – он крайне нестабилен. Хотя географически проект обхватывает
всю Россию, количество игроков все равно не очень большое. Очень многие игроки
отзываются, что за время игр испытывали большие проблемы с доступом к сайту,
особенно с мобильных устройств, несмотря на хорошее Интернет-соединение. Так
же часто бывали случаи неправильной выдачи заданий или некорректной проверки
ответов. Общий интерфейс можно увидеть на рисунках 1.7 – 1.8
Рисунок 1.7 – Главная страница Lampagame
16
Рисунок 1.8 – Анонсы игр на Lampagame
Таким образом, на сегодняшний день существует множество разных
форматов и видов городских квестов. Некоторые из них обладают широкой
аудиторией и известностью, однако их минусы не позволяют использовать их при
каждой ситуации. Разница стоимость проведения игр на каждой платформе, на
некоторых – даже в зависимости от типа игры. Все платформы обладают
функционалом для создания собственных игр, но часто далеко не самым понятным
и простым. Некоторые проекты широко признаны и используются во всем мире,
тогда как другие – в определенных частях России. На основе приведенного
исследования существующих решений можно провести их сравнительный анализ,
чтобы выделить их достоинства и недостатки. Можно выделить следующий
перечень основных критериев:

кроссплатформенность;

функционал редактора игр;

стоимость;

охват аудитории;

понятный для игроков интерфейс.
По этим критериям был произведен анализ игр, результаты которого
представлены в таблице 1.1
17
Таблица 1.1 – Анализ аналогов
Система
Кроссплат Редактор игр
форменност
ь
Стоимо
сть
Аудито
рия
1
Dozor
2
-
3
Сложный,
мало
функциональн
ый
5
+
Encounter
+
Сложный,
многофункци
ональный
+
+
LampaGa
me
-
Простой,
малофункцио
налаьный
-
+
Разработа
нная
система
+
Простой,
многофункци
ональный
4
Зависит
от
количес
тва
команд
Зависит
от типа
игры,
дорогая
Зависит
от типа
игры,
дешева
я
Бесплат
ная
Понятн
ый
интерф
ейс
6
-
+
+
1.3 Функциональные требования
Разрабатываемая система должна обеспечивать пользователю простой и
понятный способ отправки и прием сообщений. Формат специальных команд для
регистрации, авторизации и управления игрой должен быть детерминированным, а
сам текст команды – интуитивно понятным.
Для
разрабатываемой
системы
были
сформулированы
следующие
функциональные требования:

возможность регистрации команд и пользователей;

возможность создания собственных сценариев игр;

возможность управлять ходом игры администратором;

в системе должно быть разграничение прав пользователей;

вывод сообщений о текущих уровнях, заданиях и локациях игры;

способность сохранять текущий прогресс игры.
18
1.4 Нефункциональные требования
Для разрабатываемой системы проведения городских квестов можно
выделить следующие нефункциональные требования:

использование архитектуры «клиент-сервер»;

простота и функциональность редактора сценариев;

обеспечение максимальной производительности и быстрого отклика
системы;

поддержка целостности и безопасности данных, обусловленные
нарушениями в работе серверов и баз данных;

обеспечение
кроссплатформенности
(поддержка
мобильных
операционных систем iOS, Android, поддержка настольных операционных систем
Windows, Linux, macOS);

ориентированность на конечных пользователей;

пользователи не должны изменять данные, к которым не имеют
доступа.
19
2 ПРОЕКТИРОВАНИЕ АВТОМАТИЗИРОВАННОЙ СИСТЕМЫ
ПРОВЕДЕНИЯ КВЕСТОВ «ДОЗОР»
2.1 Архитектура системы
Архитектура системы проведения квестов представляет один из видов клиент
- серверной архитектуры. Основными компонентами архитектуры являются:

клиент, пользуется интерфейсом пользователя, взаимодействие с
сервером, отправка запросов и получение ответов;

сервер, управляющий базами данных, выполняющий запросы клиенты,
отсылающий ему ответы и делегирующий права доступа к нему;

сеть, осуществляющая взаимодействие между сервером и клиентом.
Для
реализации
системы
проведения
квестов
такая
архитектура
предпочтительна. Данная система минимизирует требование к системным
мощностям со стороны клиента, так как осную вычислительную работу берет на
себя сервер. За счет этого снижается сетевой трафик при обработке запросов. Так
же эта система легко масштабируема, быстро приспосабливается к увеличению
объема баз данных и количества пользователей, обеспечивает защищенность
данных.
Для корректной и рациональной работы системы требуется спроектировать
два режима работы системы: режим администратора и режим игрока.
В режиме игрока пользователь имеет возможность создавать команду и
присоединяться к уже существующим, а, также, получать задания игры и
отправлять свои ответы
В режиме администратора пользователь имеет возможность выбрать
сценарий следующей игры, запланировать игру, воздействовать на текущую игру
и команды, которые на нее зарегистрированы.
20
2.2 Функциональное моделирование
Для описания модели функционирования системы построим диаграмму
IDEF0. Эта методология предписывает построение иерархической системы
диаграмм – описаний фрагментов системы.
Сначала нужно описать систему в целом и показать ее взаимодействие с
внешней средой в чем нам поможет контекстная диаграмма, а затем необходимо
осуществить функциональную декомпозицию – систему разбить на подсистемы,
каждую из которых описать отдельно, в этом случае мы воспользуемся диаграммой
декомпозиции. Основным моделируемым процессом является сам процесс игры,
опишем его, используя контекстную диаграмму, которая представлена на рисунке
2.1.
Рисунок 2.1 – Контекстная диаграмма
Вводными
данными
для
начала
работы
являются
выбранный
администратором сценарий игры – вопросы, ответы на них, адреса локаций команды, зарегистрированные на игру и их ответы на вопросы. Управляющими
являются набор команд администратора, с помощью которых он воздействует на
21
текущую игру и систему в целом. Механизмами будут являться администратор и
игроки.
Декомпозиция блока А0 включает процессы:

создание сценария игры;

регистрация команд;

управление сценарием;

процесс игры;

получение итоговых результатов;
Администратор создает новую игру и вносит в файл сценария всю
информацию об игре: адреса локаций, уровни, их порядок, задания, правильные
ответы, дату старта и анонс. Этот уровень является входным для процесса «Игра».
В блоке «Регистрация» пользователи регистрируют свои команды на
ближайшую игру. Список зарегистрированных команд является входным
элементом в блок «Управление сценарием игр»
Блок «Управление сценарием игр» является входным для блока «Игра». На
данном этапе администратор выбирает сценарий будущей игры среди доступных в
базе данных и заносит в планировщик старт игры. Так же администратор имеет
возможность вносить различные корректировки для разных команд, например,
установить различные маршруты прохождения для каждой команды благодаря
изменению порядка выдачи уровней.
В
результате
получается
сценарий
игры
и
список
команд,
зарегистрированных на игру. Переход в процесс «Игра», в процессе которого
пользователи присылают свои ответы и координаты локаций в систему, и система
регистрирует их в базу данных.
По окончанию игры, система подводит итоги, проводя подсчет времени
прохождения локаций и количество правильно отвеченных заданий, после чего
система формирует итоговую таблицу, за что отвечает процесс «Формирование
статистики», и начисляет команде победителю призовой рейтинг.
22
В итоге, после формирования и вывода итоговой таблицы на экран, и
начисления баллов команде за победу в игре, пользователи могут ознакомится с
этими результатами, после чего следует завершение работы.
Все выше сказанное можно увидеть на рисунке 2.2
Рисунок 2.2 – Декомпозиция блока А0
2.3 Диаграмма переходов состояний
Для корректного описания работы программы необходимо обозначить
действия программы в конкретные промежутки времени и возможности действий
построив диаграмму переходов состояний.
Переходы между состояниями осуществляются при выполнении в системе
определенных действий. Рассмотрим основные состояния, которые касаются
пользователя системы – игрока.

начально состояние;

авторизация;

ожидание действий пользователя;
23

создание команды;

процесс игры;

подведение итогов игры;

окончание игры.
Все вышеизложенное представлено ниже на рисунках 2.3
Рисунок 2.3 – Диаграмма состояний пользователя
2.4 Проектирование базы данных
При проектировании базы данных, которая будет использоваться в системе,
было принято решение выбрать реляционную модель хранения данных. Этот
24
выбор был основан исходя из того, что эта система наглядна, проста в
использовании и обеспечивает удобное преобразование сущностей и связей в
схему базы данных.
Для проектирования реляционной базы данных необходимо описать
сущности, которые отражают предметную область. Для базы данных можно
выделить следующие основные сущности:

пользователь;

команда;

игра;

уровень;

локация;

координаты;

задание;

ответ.
Каждая таблица содержит ключевое поле – первичный ключ, который будет
обеспечивать уникальность записей. Так же таблицы содержат внешние ключи –
необходимые для обеспечения связей между таблицами.
Перейдем к описанию самих сущностей. Сущность «Пользователь» будет
включать в себя следующие данные:

идентификатор(первичный ключ);

номер в Телеграмм;

имя;

фамилия;

команда(внешний ключ).
Рисунок 2.4 – Атрибуты сущности «Пользователь»
25
Сущность «Команда» будет включать в себя следующие данные:

идентификатор(первичный ключ);

название команды;

счет.
Рисунок 2.5 – Атрибуты сущности «Команда»
Сущность «Игра» будет включать в себя следующие данные:

идентификатор(первичный ключ);

название игры;

дата начала игры;

время начала игры;

аннотация;

игровой счет.
Рисунок 2.6 – Атрибуты сущности «Игра»
Сущность «Уровень» будет включать в себя следующие данные:
26

идентификатор (первичный ключ);

название;

время;

задание;

локация (внешний ключ);

игра (внешний ключ).
Рисунок 2.7 – Атрибуты сущности «Команда»
Сущность «Локация» будет включать в себя следующие данные:

идентификатор (первичный ключ);

координаты.
Рисунок 2.8 – Атрибуты сущности «Локация»
Сущность «Координаты» будет включать в себя следующие данные:

идентификатор (первичный ключ);

широта;
27

долгота.
Рисунок 2.9 – Атрибуты сущности «Координаты»
Сущность «Задание» будет включать в себя следующие данные:

идентификатор (первичный ключ);

текст;

название задания.
Рисунок 2.10 – Атрибуты сущности «Задание»
Сущность «Ответ» будет включать в себя следующие данные:

идентификатор (первичный ключ);

ответ;

задание (внешний ключ).
Рисунок 2.11 – Атрибуты сущности «Ответ»
28
Теперь рассмотрим связи между описанными сущностями. В одной команде
может содержаться множество пользователей, следовательно, между сущностями
«Команда» и «Пользователь» будет проходить связь «один ко многим». В
зарегистрированной игре может участвовать множество команд, поэтому
целесообразно создать промежуточную таблицу, которая соответствует связи
«один ко многим». В каждой игре есть уровни, причем для каждой игры их может
быть неограниченное количество. У каждого уровня должно быть задание или
локация, в зависимости от продвижения игрового процесса, и типа уровня. На
каждом уровне есть только одно задание или одна локация. Для каждого задания
неограниченное число ответов, соответствующих этому заданию, исходя из этого
создается промежуточная таблица, которая соответствует связи «один ко многом».
Так как на каждую локацию указывает только одни координаты, то между этими
таблицами установлена связь «один к одному».
Описав атрибуты сущностей и их типы данных, построим полную
логическую модель базы данных и визуализируем ее как диаграмму.
Конечная схема базы данных со всеми сущностями, атрибутами и связями
представлена на рисунке 2.12.
Рисунок 2.12 – Схема базы данных
29
3 ПРОЕКТИРОВАНИЕ АВТОМАТИЗИРОВАННОЙ СИСТЕМЫ
ПРОВЕДЕНИЯ КВЕСТОВ «ДОЗОР»
3.1 Структура ПО
Для создания системы проведения квестов было решено использовать
модульную структуру.
Модульная структура – способ организация проекта, которое позволяет
удобно разделить работу программы между отдельными модулями, а также
проводить всю ресурсоемкую работу через интерфейсы, чтобы скрыть
внутреннюю логику от пользователя.
Целостность работы модулей обусловлено общей базой данных, которая
гарантирует сохранность и безопасность данных. Также есть ядро – модуль, цель
которого наладить взаимодействие между всеми модулями программы, не
вмешиваясь во внутреннюю работу каждого из них (принцип черного ящика)
Систему было принято разделить на два модуля:

Модуль взаимодействия с пользователем

Основной модуль квеста (движок)
3.1.1 Модуль диалога с пользователем
Диалог с пользователем – это взаимодействие программного средства с
пользователем.
Диалог
осуществляет
двустороннее
взаимодействие
с
пользователем, принимая от пользователя различные запросы и возвращающее ему
результат этих запросов и состояние системы. В рамках данного модуля диалог с
пользователем заключается в регистрации, оповещении, принятия сообщений от
пользователя и отправки ему ответов.
Среди методов данного модуля можно выделить:

Инициализация диалогового бота. Модуль выполняется при каждом
запуске модуля и останавливается только при его отключении.

Регистрация пользователя в системе. Пользователь при помощи
специальных команд отправляет на сервер информацию о команде и её членах.
30

Отправка вопросов пользователям. Перед началом квеста система
подгружает из базы данных сценарий игры и, по мере прохождения командой
уровней, присылает команде задания и локации. При этом на каждый уровень
отведено определенное время, по истечению которого игра перейдет на следующий
уровень (автопереход).

Получение ответов от пользователей. Система ожидает ответ или
координаты от пользователей ровно то время, отведенное на уровень, после чего
обновляет уровень и информацию, в зависимости от его типа.
3.1.2 Модуль создания игр и администрирования
Администрирование
–
комплекс
мер
по
запуску
и
поддержанию
работоспособности системы. Регулярное администрирование и наполнение
системы информацией позволяет привлекать новых и поддерживать старых
пользователей.
Вследствие работы данного модуля осуществляется добавление новых игр и
управление текущими. Можно выделить следующие методы:

Авторизация пользователя. Метод инициирует проверку авторизации
пользователя, чтобы проверить права доступа к управлению системой.

Планирование игры. Модуль с помощью формирования запросов
получает необходимую информацию из базы и оповещает команды о предстоящей
игре.

Блокировка команд. Блокировка команды необходима для пресечения
нарушений правил и нечестной игры – система штрафов.

Пауза, полная остановка и перезапуск игры. Модуль сохраняет
текущий процесс игры после каждого действия команд в отдельный файл, что
позволяет в случае нештатных ситуаций приостановить игру и продолжить ее с
того же места
31

Создание новых игр. Происходит формирование новых заданий,
ответов, локаций и уровней в базу, откуда в дальнейшем будет импортироваться
большая часть игровой информации.
3.2 Проектирование алгоритмов
В соответствии с функциональными требованиями разрабатываемая система
проведения интеллектуальных игр представлена совокупностью следующих
алгоритмов:

регистрация команды;

создание и поддержание цикла игры;

старта игры;

проверка пользовательских ответов.
3.2.1 Алгоритм регистрации команды
Работа алгоритма начинается при вводе соответствующей команды
пользователем. Сначала алгоритм проверяет, не находится в ли пользователь в
черном списке – списке пользователей, которым был запрещен доступ к системе.
Если пользователь в черном списке, то алгоритм заканчивает работу. Если нет, то
дальше идет проверка на то, является ли пользователь уже зарегистрированным в
системе. Если да, то выводится сообщение о том, что пользователь уже
зарегистрирован и алгоритм заканчивает свою работу. Если нет, то идет проверка
на то, что квест уже запущен. Если нет текущей игры, то выводится сообщение об
успешной авторизации в системе и в память программы сохраняется информация
о новой команде, после чего новое состояние системы сохраняется в отдельный
файл. Если в этот момент уже идет какая-либо игра, то выводится сообщение о
невозможности регистрации. На этом алгоритм заканчивает свою работу.
На рисунке 3.1 представлена блок - схема алгоритма регистрации
пользователей.
32
Рисунок 3.1 – Алгоритм регистрации команд
3.2.2 Алгоритм цикла игры
Алгоритм начинает свою работу при наступлении времени старта игры,
загруженной в оперативную память системы.
После начала времени старта квеста всем командам присылается их первый
уровень. Порядок прохождения уровней для каждой команды определятся автором
игры при создании сценария. Затем команды начинают отправлять ответы на
задания – будь то коды на локациях или ответы на логические задачи – и система
переходит в режим ожидания ответов команд. Как только команда отправляет все
ответы текущего уровня, проводится переход на следующий уровень. Если
33
команда прошла все уровни, то сохраняется время, за которое команда прошла игру
и увеличивается счетчик завершивших команд. После прохождения игры всеми
командами игра останавливается и команде с наименьшим временем прохождения
присуждается победа и в рейтинг начисляется количество баллов, равное
стоимости игры. Всем командам высылается сообщение с их итоговым местом.
Затем, результаты игры сохраняются в базу данных из оперативной памяти.
На рисунке 3.2 представлена схема алгоритма цикла игры.
Рисунок 3.2 – Алгоритм цикла игры
34
3.2.3 Алгоритм старта игры
Алгоритм старта игры – один из алгоритмов диалога пользователя с
системой. Он позволяет администратору выбрать, какой именно сценарий
запустить на следующую игру.
На первом шаге алгоритм проверяет, зарегистрировался ли пользователь как
администратор. Если нет, то алгоритм заканчивает работу. Дальше алгоритм делает
запрос к базе данных и смотрит сценарии, которые доступны и отправляет
сообщение организатору со списком. После этого система ждет ответа
администратора, в котором содержится информация о выбранном сценарии. Как
только такой ответ поступает, система загружает выбранную игру в оперативную
память и ждет времени начала игры для запуска цикла игры. После этого алгоритм
останавливается.
Рисунок 3.3 – Алгоритм старта игры
35
3.2.4 Алгоритм проверки пользовательских ответов
Алгоритм проверки пользовательских ответов достаточно прост, так как
основан на простых сравнениях. Алгоритм начинает свою работу при отправке
игроками их ответов.
На первом шаге производится проверка пользователя. Если он не
зарегистрирован в системе, то алгоритм прекращает свою работу. Дальше идет
проверка, зарегистрирована ли его команда на игру. Если нет – выход из алгоритма.
На третьем шаге алгоритм проверяет, является ли ответ игрока правильным
ответом для задания, на уровне которого находится его команда. Если нет, то
пользователю возвращается ответ, что ответ не правильный. Если ответ верен, то
пользователю возвращается сообщение, что ответ принят и увеличивается счетчик
правильных ответов на уровне. Если приняты все ответы с данного уровня, то
алгоритм сигнализирует системе о необходимости перевода команды на
следующий уровень и заканчивает свою работу.
На рисунке 3.4 представлена схема алгоритма проверки пользовательских
ответов.
Рисунок 3.4 – Алгоритм проверки пользовательских ответов
36
3.3 Проектирование пользовательского интерфейса
Интерфейс
пользователям.
пользователя
При
–
часть
проектировании
программы,
интерфейса
которая
необходимо
доступна
учитывать
специфику тех пользователей, которые будут работать с разрабатываемой
системой. Так как потенциальные пользователи могут иметь разный опыт работы
с подобными приложениями и системами, интерфейс должен быть максимально
понятен и интуитивен. Интерфейс для администратора и пользователя будет
различным и представлять следующее:

Форма создании игры и редактирования сценария. Данный интерфейс
представляет собой вебсайт, который в простой форме позволяет автору написать
задания, ответы к ним, отметить локации, собрать из них уровни и сценарий игры.

Форма администратора. Позволяет напрямую вносить в базу данных
новую информацию, редактировать уже существующую информацию и удалять
устаревшую.

Диалог регистрации пользователя.

Диалог регистрации команды.

Диалог старта игры.

Диалог проверки ответов в ходе игры.
3.4 Проектирование структур данных
На основе анализа модели отображения данных было принято решение
использовать для редактора сценариев такого формата данных, как JSON
(JavaScript Object Notation).
JSON текстовый формат обмена данными, основанный на JavaScript. Как и
многие другие текстовые форматы, JSON легко читается людьми. Формат JSON
был разработан Дугласом Крокфордом. Формат считается независимым от языка и
может использоваться практически с любым языком программирования.
37
Использование такого формата обусловлено удобством чтения и записи
данных, так как для многих языков существует готовый код для сериализации и
десериализации данных в формате JSON
Формат такого файла можно рассмотреть на примере одного из уровней
игры, содержащий задание и несколько ответов.
{
“Название”: «Уровень1»,
«Текст»: «Здесь текст задания»,
«Ответы»:
[«Ответ1», «Ответ2», «Ответ3»],
«Время на уровень»: 3600
}
Для полного сценария игры формат будет выглядеть следующим образом:
{
“Название”:”Название игры”,
“Анонс”:”Информация о предстоящей игре”,
“Время старта”:”14:00”,
“Дата старта”:”27.08.2018”,
“Список уровней”:[
Далее идет перечисление уровней в формате, указанном выше
]
}
Как можно заметить, такой формат файла позволяет легко записывать и
читать
данные
даже
без
использования
сторонних
программ,
четко
структурирован, что обеспечивает надежность и правильность интерпретации
данных. Также, такой формат данных позволяет в будущем создавать другие
программы по редактированию сценариев игры. Это увеличит вовлеченность
аудитории, так как позволит другим участникам проекта присоединиться к
процессу разработки и предложить свои решения в этой области
38
4. РЕАЛИЗАЦИЯ АВТОМАТИЗИРОВАННОЙ СИСТЕМЫ
ПРОВЕДЕНИЯ КВЕСТОВ «ДОЗОР».
4.1 Выбор инструментальных средств разработки
Для реализации разрабатываемой системы предполагается использование
языков программирования Python c фреймворком Telepot для работы с Telegram
Bot API, СУБД SQLite3.
Python - высокоуровневый язык программирования общего назначения,
ориентированный на повышение производительности разработчика и читаемости
кода. Синтаксис ядра Python минималистичен. В то же время стандартная
библиотека включает большой объём полезных функций.
Python поддерживает несколько парадигм программирования, в том числе
структурное, объектно-ориентированное, функциональное, императивное и
аспектно-ориентированное. Код в Python организовывается в функции и классы,
которые могут объединяться в модули (они в свою очередь могут быть объединены
в пакеты).
К числу основных преимуществ Python можно отнести:

Динамическая типизация. В Python не нужно заранее объявлять типы
переменных.

Поддержка модульности. Ввиду того, что около этого языка
образовалось большое сообщество программистов, которые постоянно пишут на
этом языке различные решения, то иногда для выполнения различных задач нужно
просто найти подходящий модуль

Интеграция
с
другими
языками.
Если
возможностей
Python
недостаточно, то возможно интегрировать код С/С++ (CPython), C# (IronPython),
Java (Jython)

Автоматический сборщик мусора.

Лаконичный и понятный синтаксис. Удобная система функций
позволяет создавать код, в котором просто разобраться другому программисту в
39
случае необходимости. Так же это облегчает чтение и использование сторонних
модулей.

Кроссплатформенность.
В качестве платформы для приема и отправки сообщений был выбран
Telegram. Это кроссплатформенный мессенджер, количество ежемесячных
активных пользователей которого по состоянию на конец марта 2018 года
составляет более 200 млн человек. Это означает доступность нашей системы для
огромного количества людей. Он является очень безопасным, ведь для
функционирования мессенджера был создан протокол MTProto, предполагающий
использование нескольких
протоколов шифрования. При
авторизации и
аутентификации используются алгоритмы RSA-2048, DH-2048 для шифрования,
при передаче сообщений протокола в сеть они шифруются AES с ключом,
известным клиенту и серверу. Также применяются криптографические хешалгоритмы SHA-1 и MD5. Также, Telegram крайне мало нагружает интернеттраффик во время обмена сообщениями, что позволит пользователям нашей
системы продолжать играть в городские квесты даже при плохой телефонной
связи.
Telegram выбран так же из-за наличия Telegram API и Bot API, что позволяет
разработчикам писать собственных «ботов» - интеллектуальных систем – для
взаимодействия с пользователями. Для упрощения работы с Bot API был выбран
фреймворк Telepot – популярный фреймворк для языка Python.
В качестве основного средства разработки базы данных была выбрана СУБД
SQLite3.Это компактная встраиваемая СУБД. Слово «встраиваемый» (embedded)
означает, что SQLite не использует парадигму клиент-сервер, то есть движок
SQLite не является отдельно работающим процессом, с которым взаимодействует
программа, а представляет собой библиотеку, с которой программа компонуется, и
движок становится составной частью программы. Таким образом, в качестве
протокола обмена используются вызовы функций (API) библиотеки SQLite. Такой
подход уменьшает накладные расходы, время отклика и упрощает программу.
SQLite хранит всю базу данных (включая определения, таблицы, индексы и
40
данные) в единственном стандартном файле на том компьютере, на котором
исполняется программа. Простота реализации достигается за счёт того, что перед
началом исполнения транзакции записи весь файл, хранящий базу данных,
блокируется; ACID-функции достигаются в том числе за счёт создания файла
журнала.
Несколько процессов или потоков могут одновременно без каких-либо
проблем читать данные из одной базы. Запись в базу можно осуществить только в
том случае, если никаких других запросов в данный момент не обслуживается; в
противном случае попытка записи оканчивается неудачей, и в программу
возвращается код ошибки. Другим вариантом развития событий является
автоматическое повторение попыток записи в течение заданного интервала
времени.
4.2 Реализация механизма регистрации
Для регистрации пользователя в системе существует несколько методов,
описанных ранее. В программном коде, представленном ниже происходит
считывание данных пользователя. Метод срабатывает при получении команды
«/register». После этого срабатывает после этого обработчик сообщений и вызывает
метод регистрации команды. Он проверяет, существует ли уде команда с таким
названием. Если да, то возвращается сообщение об ошибке. Если нет - сообщение
об успешной регистрации. Ниже представлен скрипт регистрации команды:
def __register(self, user_id, text):
msg = ''
if not (user_id in self.black_list):
if len(text) >= 2:
if not self.is_registered(user_id):
if not self.isGoing:
self.register_team(user_id, '_'.join(text[1:]))
msg = 'Вы успешно зарегестрированы!'
else:
41
msg = 'Квест уже идет!'
else:
msg = 'Вы уже зарегестрированы на квест!'
else:
msg = 'Пожалуйста, введите /register и название команды'
bot.sendMessage(user_id, msg)
def register_team(self, owner_id, name):
new_team = Team({"owner_id": owner_id, "name": name})
self.teams.append(new_team)
rewrite_json(self.teams_file, self.teams)
def is_registered(self, user_id):
for t in self.teams:
if t.owner_id == user_id:
return True
return False
Рисунок 4.1 – Регистрация команды в системе
4.3 Реализация механизма старта игры
Чтобы организовать цикл игры, администратору необходимо написать
команду /start_game. После этого статус игры game.isGoing устанавливается в True.
Это нужно для того, чтобы невозможно было зарегистрироваться на игру, которая
уже идет и не было возможности изменить данные сценария. В это же время
42
начинает работать таймер, отсчитывающий время игры. Как только таймер
запущен, система автоматически рассылает текст загадки первого уровня каждой
команде, которая зарегистрирована на игру. После этого система ждет ответов от
игроков на эти загадки.
В случае возникновения внештатных ситуаций у администратора есть
возможность остановить игру и перезапустить ее заново с помощью команд
/stop_game и /restart_game. Ниже представлен код запуска, остановки, перезапуска
игры и посылки текста загадки командам.
def start_quest(self, is_silent):
if not self.isGoing:
self.isGoing = True
self.time_start = now()
for t in self.teams:
t.penalty = [0 for r in range(len(self.riddles) - 1)]
t.time_start = now()
if not is_silent:
bot.sendMessage(t.owner_id, Msg.start)
t.send_riddle(self.riddles[str(t.loc_cur)])
def stop_quest(self):
try:
self.isGoing = False
self.time_start = now() - self.time_start
for t in self.teams:
t.time_stop = now()
t.has_ended = True
bot.sendMessage(t.owner_id, Msg.stop)
except Exception as e:
print(e) False
43
def restart_game(self):
self.time_start = now()
self.isGoing = False
self.riddles = self.raw['riddles']
for t in self.teams:
t.cnt_solved = 0
t.cnt_bonus = 0
t.loc_cur = t.loc_start
t.has_ended = False
t.penalty = [0 for r in range(len(self.riddles) - 1)]
t.time_start = now()
t.time_stop = now()
bot.sendMessage(t.owner_id, Msg.restart)
rewrite_json(self.teams_file, self.teams)
def send_riddle(self, r):
bot.sendMessage(self.owner_id, r['sp_riddle'])
return
Рисунок 4.2 – Процесс старта игры
4.4 Реализация механизма проверки ответов пользователя
После того как игра запущена, система переходит в режим ожидания ответов
от пользователей. Механизм проверки кода разбит на два метода внутри двух
классов – Game и Team. В классе Game содержится метод проверки кода, который
44
проверяет, закончилась ли игра для этой команды. Если нет, то проверяет,
соответствует ли ответ команды правильным ответам на данный уровень. Если нет,
то система отправляет сообщение о неудачной проверке кода. Если да, то
отправляется сообщение о правильном ответе и вызывается метод solved класса
Team, который увеличивает количество решенных загадок. В случае, если это было
дополнительное задание, а не основное, то просто начисляется дополнительный
балл. Ниже представлен код двух методов, рассматриваемых выше:
Класс Game:
def check_code(self, team, code):
code = code.upper()
riddle = self.riddles[str(team.loc_cur)]
try:
if not team.has_ended:
if code == riddle['sp_ans'].upper():
team.solved(code, is_spoiler=True, coord=riddle['loc_coord'])
elif code == riddle['code'].upper():
team.solved(code)
elif code in self.riddles['bonus']:
self.riddles['bonus'].remove(code)
team.solved(code, is_bonus=True)
else:
bot.sendMessage(team.owner_id, Msg.bad.format(code))
else:
bot.sendMessage(team.owner_id, Msg.has_ended)
rewrite_json(self.teams_file, self.teams)
except Exception as e:
print(e)
return
Класс Team:
45
def solved(self, code, is_bonus=False, is_spoiler=False, coord=''):
if is_bonus:
self.cnt_bonus += 1
bot.sendMessage(self.owner_id, Msg.bonus.format(code))
return
elif is_spoiler:
bot.sendMessage(self.owner_id, Msg.spolier.format(code, coord))
else:
self.cnt_solved += 1
if self.cnt_solved == len(quest.riddles):
self.has_ended = True
self.time_stop = now()
bot.sendMessage(self.owner_id, Msg.congrat)
else:
bot.sendMessage(self.owner_id, Msg.good.format(code))
self.loc_cur = (self.loc_cur + 1) % len(quest.riddles)
self.send_riddle(quest.riddles[str(self.loc_cur)])
return
Рисунок 4.3 – Результат правильно введенного кода
Рисунок 4.4 – Результат неправильно введенного кода
46
4.5 Реализация механизма сохранности данных
После каждого действия, которое вносит изменение в оперативную память
программы, срабатывает механизм сохранения данных. Все данные об игре
хранятся в формате JSON. Это позволяет сохранять игру на любом этапе и
возобновить ее в случае возникновения нештатных ситуаций. Ниже представлен
код сохранения и загрузки данных из JSON:
def rewrite_json(file_name, data):
try:
ft = open(file_name, 'r+')
ft.truncate(0)
ft.write(json.dumps(data, default=jdefault, ensure_ascii=False, sort_keys=True,
indent=4, separators=(',', ': ')))
ft.flush()
ft.close()
except Exception as e:
print(e)
def jdefault(o):
return o.__dict__
def json_load(file_name):
with open(file_name, "rb+") as f:
data = f.read()
data = json.loads(data.decode('utf8'))
return data
47
def log(msg, file_name):
try:
data = msg['from']
data['text'] = msg['text']
pprint(data)
with open(file_name, 'a') as f:
f.write(json.dumps(data, indent=4, separators=(',', ': ')) + '\n')
except Exception as e:
print(e)
return
48
ЗАКЛЮЧЕНИЕ
Задача создания системы автоматизированного создания и проведения
городских квестов с каждым днем увеличивает свою актуальность. Все больше и
больше людей начинают интересоваться этой темой, использовать игры в качестве
тимбилдинга, хобби или просто хорошего времяпровождения. В рамках данной
выпускной квалификационной работы система осуществляет подготовку и
проведения таких квестов. Основной целью этой системы было создать простую и
понятную для каждого платформу для использования при каждом удобном случае.
В ходе выполнения данной работы были выполнены все задачи. Был
проведен полноценный разбор и анализ предметной области, описана суть
городских квестов, их правил и типов сценариев. Проведен сравнительный анализ
уже существующих аналогов, рассмотрены их достоинства и недостатки.
На основе анализы были описаны спецификации городских игр, были
выявлены основные функциональные и нефункциональные требования к системе
подготовке и проведения квестов.
Затем была спроектирована база данных по хранению информации о квестах,
построена ее схема, описаны сущности и связи.
В дальнейшем, во время проектирования была создана архитектура системы,
ее отдельные модули, разработаны основные алгоритмы работы нашей системы.
Далее был спроектирован интерфейс пользователя и администратора системы,
рассмотрены структуры данных, которые используются для работы проекта
На последнем этапе были выбраны программные средства реализации
автоматизированной системы создания и проведения городских квестов,
реализованы основные алгоритмы функционирования системы.
В следствие всего выше сказанного можно с уверенностью сказать, что цель
данной выпускной квалификационной работы достигнута.
49
СПИСОК ИСПОЛЬЗОВАННОЙ ЛИТЕРАТУРЫ
1.
Правила вида спорта «Спортивное ориентирование». Утверждено
приказом Минспортуризма России от «02» апреля 2010 г. № 278
2.
Adams, Ernest. Fundamentals of Game Design. — 2nd edition. — Berkeley,
CA: New Riders, 2010. — С. 547. — 700 p. — ISBN 978-0321643377.
3.
Милющенко, Вадим Квесты: эволюция жанра (рус.). №4 (41). Лучшие
компьютерные игры (апрель 2005). Проверено 2 октября 2014.
4.
Марк Лутц. Изучаем Python, 4-е издание. — Перевод с английского. —
СПб.: Символ-Плюс, 2010. — 1280 с — ISBN 978-5-93286-159-2
5.
Дэвид М. Бизли. Python. Подробный справочник, 4-е издание. —
Перевод с английского. — СПб.: Символ-Плюс, 2010. — 864 с — ISBN 978-593286-157-8
6.
Марк Саммерфилд. Программирование на Python 3. Подробное
руководство. — Перевод с английского. — СПб.: Символ-Плюс, 2009. — 608 с —
ISBN 978-5-93286-161-5
7.
D. Crockford The application/json Media Type for JavaScript Object
Notation (JSON) — Internet Engineering Task Force, 2006. — 10 p. —
doi:10.17487/RFC4627
8.
Кнут Д. Искусство программирования, том 1. Основные алгоритмы =
The Art of Computer Programming, vol.1. Fundamental Algorithms — 3-е
изд. — М.: «Вильямс», 2006. — С. 720. — ISBN 0-201-89683-4
9.
Telegram
Bot
API
[Электронный
ресурс]
Режим
доступа:
https://core.telegram.org/bots/api (Дата обращения 12.04.2018)
10.
Леоненков, А.В. Самоучитель UML 2 [Текст] / А.В. Леоненков. – СПб.:
БХВ-Петербург, 2007. – 576 с.
50
ПРИЛОЖЕНИЕ А
(обязательное)
ЛИСТИНГ ПРОГРАММНОГО КОДА
# -*- coding: utf-8 -*import telepot, datetime, time, sys, os, json, collections
from pprint import pprint
BOT_TOKEN = "************************************"
ADMIN_ID = 9999999
SECRET_CODES = [u'TE', u'ST', u'WO', u'RD']
SECRET_COUNT = len(SECRET_CODES)
BAD_MSG = u": код не принят"
GOOD_MSG = u": код принят! Ждите следующую загадку"
START_MSG = u"Внимание, команды! Квест начался! Время пошло!"
STOP_MSG = u"Внимание, команды! Время квеста закончилось! Всем
участниками прийти в актовый зал!"
class Team:
def __init__(self, name, user_id, offset = 0):#, solved = 0, riddles =
SECRET_CODES, is_word = False, has_ended = False, timer = 0, offset = 0):
self.name = name
self.owner_id = user_id
self.solved = 0
self.solved_bonus = 0
self.is_word = False
self.has_ended = False
self.time_start = 0
self.time_stop = 0
51
self.start_position = offset
self.cur_position = offset
def now(self):
tt = time.gmtime()
__time = tt.tm_hour * 60 + tt.tm_min
return __time
class Game:
def __init__(self, game_name, riddles, teams = []):
self.game_name = game_name
self.isGoing = False
self.teams = teams
self.time_start = 0
self.riddles = riddles
self.black_list = []
def start_quest(self):
if not self.isGoing:
self.isGoing = True
self.time_start = time.time()
for t in self.teams:
bot.sendMessage(t.owner_id, START_MSG)
def stop_quest(self):
try:
self.isGoing = False
self.time_start = time.time() - self.time_start
for t in self.teams:
52
# t.timer = t.now() - t.timer
t.has_ended = True
bot.sendMessage(t.owner_id, STOP_MSG)
except Exception as e:
print e
def call_help(self, team):
bot.sendMessage(ADMIN_ID, 'help {0}, location {1}'.format(team.name,
team.cur_position + 1))
def find_team(self, user_id):
for t in self.teams:
if user_id == t.owner_id:
return t
return False
def check_code(self, team, code):
user_id = team.owner_id
response = code
code = code.upper()
lRid = self.riddles['riddles']
# pprint(lRid)
try:
if not team.has_ended:
if not team.is_word:
if lRid[unicode(team.cur_position)]['code'].upper() == code.upper():
response += GOOD_MSG
bot.sendMessage(user_id, response)
team.solved += 1
cur_rid = lRid[unicode(team.cur_position)]['riddle']
53
team.cur_position = (team.cur_position + 1) % len(lRid)
if team.solved == len(lRid):
team.is_word = True
bot.sendMessage(user_id, 'Последняя локация - актовый зал.
Вас ждет последнее испытание')
# team.
else:
bot.sendMessage(user_id, cur_rid)
elif code.upper() in self.riddles['bonus']:
bot.sendMessage(user_id, 'Бонусный код принят')
team.solved_bonus += 1
self.riddles['bonus'].remove(code.upper())
pprint(self.riddles['bonus'])
else:
response += BAD_MSG
bot.sendMessage(user_id, response)
else:
if code.upper() != self.riddles['secret'].upper():
response += BAD_MSG
bot.sendMessage(user_id, response)
else:
team.time_stop = team.now()
team.has_ended = True
bot.sendMessage(user_id, "Поздравляем, вы прошли квест!
Ожидайте окончания квеста остальными участниками")
bot.sendMessage(ADMIN_ID,
'Team
{0}
finished!'.format(team.name))
self.json_sync()
else:
bot.sendMessage(team.owner_id, 'Вы уже прошли квест!')
has
54
except Exception as e:
print e
def __register(self, user_id, text):
if not (user_id in self.black_list):
if len(text) >= 2:
if not self.is_registered(user_id):
if not self.isGoing:
self.register_team(user_id, '_'.join(text[1:]))
bot.sendMessage(user_id, 'Вы успешно зарегестрированы!')
else:
bot.sendMessage(user_id, 'Квест уже идет!')
else:
bot.sendMessage(user_id, 'Вы уже зарегестрированы на квест!')
else:
bot.sendMessage(user_id, 'Пожалуйста, введите /register и название
команды')
def register_team(self, user_id, team_name):
new_team = Team(team_name, user_id, offset=len(self.teams))
self.teams.append(new_team)
self.json_sync()
def json_sync(self):
try:
fT = open('RegisteredTeams.json', 'r+')
fT.truncate(0)
fT.write(json.dumps(self.teams, default=jdefault))
fT.flush()
fT.close()
55
except Exception as e:
print e
def is_registered(self, user_id):
for t in self.teams:
if t.owner_id == user_id:
return True
return False
def del_team(self, name):
for t in self.teams:
if t.name == name:
bot.sendMessage(t.owner_id, 'Ваша команда была исключена!
Обратитесь к организаторам!')
self.black_list.append(t.owner_id)
self.teams.remove(t)
self.json_sync()
return True
return False
# TODO
# def ban_team(self, name, __time):
#
#
#
for t in self.team:
if t.name == name:
bot.sendMessage(t.owner_id, 'Banned for {0} seconds'.format(__time))
def restart_game(self):
self.time_start = 0
self.isGoing = False
self.riddles = json_load('Riddles.json')
56
for t in self.teams:
# t.timer = time.gmtime()
t.solved = 0
t.cur_position = t.start_position
t.is_word = False
t.has_ended = False
bot.sendMessage(t.owner_id, 'Игра была перезапущена. Ждите старта!')
self.json_sync()
def print_status(self, user_id):
message = {t.name : [t.solved, t.cur_position, t.solved_bonus, t.now() t.time_start] for t in self.teams}
bot.sendMessage(user_id, message)
def send_message(self, to_name, text):
for t in self.teams:
if t.name.upper() == to_name.upper():
bot.sendMessage(t.owner_id, text)
return True
return False
def handle_message(self, msg):
try:
user = msg['from']
text = msg['text'].split()
pprint(msg)
team = self.find_team(user['id'])
if text == '/start':
pass
57
elif msg.has_key('entities'):
pprint(msg['entities'][0]['type'])
if text[0] == '/register':
self.__register(user['id'], text)
elif text[0] == '/help':
self.call_help(self.find_team(user['id']))
elif user['id'] == ADMIN_ID:
if text[0] == '/del':
self.del_team(text[1])
elif text[0] == '/status':
self.print_status(user['id'])
elif text[0] == '/send':
self.send_message(text[1], ' '.join(text[2:]))
elif text[0] == '/start_quest':
self.start_quest()
elif text[0] == '/stop_quest':
self.stop_quest()
elif text[0] == '/restart':
self.restart_game()
else:
bot.sendMessage(user['id'], 'Введена неправильная команда!')
else:
bot.sendMessage(user['id'], 'У вас нет прав для выполнения этой
команды!')
else:
if self.isGoing:
self.check_code(team, text[0])
else:
bot.sendMessage(user['id'], 'Квест еще не начался!')
except Exception as e:
58
print e
def dictToTeam(d):
team = Team(d['name'], d['owner_id'])
team.solved = d['solved']
team.is_word = d['is_word']
team.has_ended = d['has_ended']
team.time_start = d['time_start']
team.time_stop = d['time_stop']
team.start_position = d['start_position']
team.cur_position = d['cur_position']
return team
def jdefault(o):
return o.__dict__
def json_load(fName):
with open(fName, "r+") as f:
data = f.read().replace('\n', '')
data = json.loads(data)
return data
#====================MAIN=============================#
if __name__ == '__main__':
riddles = json_load('Riddles.json')
lTeams = json_load('RegisteredTeams.json')
teams = [dictToTeam(t) for t in lTeams]
quest = Game('Hogwarts quest', riddles=riddles, teams = teams)
59
bot = telepot.Bot(BOT_TOKEN)
bot.message_loop(quest.handle_message)
print 'Listening...'
while 1:
time.sleep(1)
Powered by TCPDF (www.tcpdf.org)
1/--страниц
Пожаловаться на содержимое документа