Оглавление "Программирование для игр"

При игре в настольное лото игроки по очереди должны доставать из мешка фишки/бочонки и произносить их номера. Выигрывает тот, кто быстрее других закроет все числа на карточке по какому-то условию. Фишки двусторонние, но у достающего фишку есть возможность увидеть номер раньше других и быстрее определить наступление у себя выигрышного условия. Устранить этот недостаток можно при помощи приложения, имитирующего ведущего лото, который будет сообщать числа. Но перед этим имеет смысл подумать над тем, что при этом настольная игра потеряет:

  • возможность брать фишки в руки, показывать их и сообщать номер
  • натуральный голос, звук сталкивающихся фишек и глубину взаимодействий между игроками
  • невозможность задания условия выигрыша по закрытию линий фишками, так как они физически не используются

Настольные игры, в которых совместно используются реальные и виртуальные объекты, принято называть гибридными. У них есть и преимущества, и недостатки, но главное - не перестараться с последними, чтобы настольная игра не превратилась в кино, как в некоторых видеоиграх, где 95% времени смотришь на экран, а 5% выполняешь то, что пишут на экране.

Задача. Создать приложение для имитации ведущего лото, который через определённые промежутки времени будет сообщать случайные номера из заданного диапазона. Начало игры происходит по нажатию на кнопку. При окончании игры ведущий воспроизводит заданную фразу.

Эта задача похожа на ту, в которой мы имитировали броски игрального кубика. Но есть и отличие – выпавшие числа не должны повторяться. Существует несколько вариантов для её решения.

Вариант 1. На этапе инициализации список чисел заполняется случайной последовательностью. Пока количество элементов в списке меньше максимально возможного, добавляем в него случайное число, если его ещё нет в списке. Игра прекращается либо при достижении индексом конца списка, либо при возникновении выигрышного условия.

Преимущество данного подхода в том, что выбор значения из списка в дальнейшем будет происходить по индексу: создаём цикл и последовательно выбираем числа по счетчику: 0, 1, 2 … Max.

Недостаток – наличие лишних операций. При каждом добавлении числа в список приходится делать проверку на его наличие. Если его в списке нет, то добавляем число в список. В противном случае прерываем выполнение текущей итерации и переходим к следующей.

Вариант 2. На этапе инициализации список последовательно заполняется числами от 1 до Max. Для выбора значения из списка необходимо случайным образом генерировать индекс, получить по нему значение элемента списка и удалить последний. Игра прекращается либо при уменьшении размера списка до 0, либо при возникновении выигрышного условия.

В этом варианте нет лишних операций. Выберем его для реализации.

В приложении потребуется кнопка Старт, при нажатии на которую начнётся игра. Не нужно добавлять в проект все компоненты, которые кажутся необходимыми для решения задачи. Отлаживать проще работу одного, а не 10 компонентов сразу. Как уже говорилось, далеко не все платформы визуальной разработки являются надёжными. Бывают случаи, когда работающая программа вызывает краш приложения только потому, что разработчик добавил в проект какой-то сбойный блок. Этот блок ни к чему не подключен, но он находится в приложении и даёт сбой, а разработчик тратит время на поиск несуществующей ошибки в своих алгоритмах.

Ещё одно правило при разработке – на этапе отладки выводите все данные на экран, чтобы видеть то, что с ними происходит. В противном случае будут уходить часы и дни на поиск ошибки, которая решается за 1 минуту. Глаза нам для этого и даны, чтобы видеть ошибку, а не пытаться понять, почему “на 100% правильное” приложение не работает.

Разобьём исходную задачу на элементарные подзадачи.

1) На этапе инициализации нужно заполнить список числами от 1 до 10. Почему до 10, если в лото 100 чисел? В лото 100, но для удобства отладки сначала заполним массив пятью. Предположим, на каждую выборку отводится 5 секунд. Тогда полный перебор  100 чисел займёт 500 секунд. Это просто бессмысленная потеря времени. Нам нужно всё делать гораздо проще и быстрее – 10 элементов с выборкой через 1 секунду. После отладки сделаем так, как требуется.

Здесь стоит сделать небольшое отступление. Человек может не быть программистом, но он может думать как программист. Думать как программист - это объёмное понятие, в которое также входит способность к самостоятельной постановке и решению задач, а не ожидания того, когда кто-то что-то решит за тебя. Как говорится, программисты не ждут - программистов ждут.

Вернёмся к нашему пункту и составим блоки. Создайте новый проект в Thunkable X и добавьте в него кнопку Button и область просмотра списка List Viewer для контроля заполнения списка чисел. После этого составляем блоки.

Если при нажатии на кнопку на экране отображается список из 10 элементов, то идём дальше.

2) Создадим функцию для получения значения из списка и его озвучивания. Для этого добавьте в проект синтезатор речи Text To Speech. Составим блоки.

Вначале функции стоит блок для смены языка воспроизведения речи на русский язык. Далее генерируем случайный индекс, получаем по нему значение элемента списка и удаляем данный элемент. После этого для контроля выводим на кнопке значение индекса, воспроизводим его и обновляем список на экране также для контроля. Если всё работает, то идём дальше. Идея проста: сначала нужно сделать правильно один шаг. Бессмысленно делать серию шагов, если нет уверенности в том, что один шаг работает как надо. 

3) Добавляем в проект таймер Timer, задаём цикличный режим работы Loops = True и интервал Interval = 1 seconds. После этого с учётом условий по завершению игры составляем блоки.

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

4) Нужно добавить окончание игры по голосовой команде от пользователя. Для этого добавим в проект компонент распознавания речи Speech Recognizer и выберем для него русский язык. В качестве команды выберем фразу "стоп". Расписывать блоки не буду, потому что из-за чудной работы компонентов распознавания речи пришлось упростить задачу и заменить голосовой ввод нажатием на полноэкранную прозрачную кнопку. Здесь всё, как и с игровыми приставками: одни помогают играть, а другие мешают из-за нехватки производительности.

Ссылка на шаблон проекта Виртуальный ведущий лото.

Мы создали простое приложение, но в нём используются блоки, работа которых может быть понятна не всем, особенно если есть сложности с английским языком. В таком случае имеет смысл создать вспомогательное приложение для тренировки и изучения работы блоков.

В заключение данного занятия дам ещё один совет: программирования основано на понимании, а не заучивании. А для понимания используйте понятные ассоциации из окружающего мира:

константа - то, что не должно меняться в программе (например, математические и физические постоянные)
переменная и её значение - кошелёк и его содержимое
массив и индексы - квартиры в доме с номерами на дверях
объект и свойства - дом из 24 этажей с балконами синего цвета
указатель - номер дома
циклы - работа двигателя или светофора
условия и выбор - поиграть в видеоигры или пойти поработать

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