Создаем игру в Golang

В данном уроке мы попробуем описать процесс создания симулятора сокращения численности населения, перенаселения и рождаемости. Он также известен под названием Игра «Жизнь», или Conway’s Game of Life. Симуляция разыгрывается на двухмерной сетке клеток. Процесс создания будет фокусироваться на срезах.

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

Форум Гоферов

Мы работаем над форумом для программистов на Golang. Очень нужны модераторы которые хотят помочь с ответами для новичков и помочь в развитии Go-сообщества.

Go на Форум

Уроки, статьи и Видео

Мы публикуем в паблике ВК и Telegram качественные обучающие материалы для быстрого изучения Go. Подпишитесь на нас в ВК и в Telegram. Поддержите сообщество Go программистов.

Go в ВК Go в Telegram

Создание новой вселенной в игре Жизнь

Для первой реализации Игры в «Жизнь» поставим лимит, ограничив размер вселенной. Примем решение касательно размеров сетки и определим некоторые константы:

Затем определим тип Universe, что будет содержать двухмерное поле клеток. С булевым типом каждая клетка будет либо живой (true), либо мертвой (false):

Вместо массивов лучше использовать срезы. Таким образом, universe можно будет поделить или изменить через функции и методы.

В следующих уроках мы в подробностях разберем указатели, что является альтернативным способом напрямую делиться массивами через функции и методы.

Напишите функцию NewUniverse, что использует make для определения и возвращения Universe c высотой строк height и шириной столбцов width на каждый ряд:

Новые определенные срезы по умолчанию будут с нулевыми значениями, а это false. По этой причине изначально вселенная пуста.

Запуск пустой вселенной в игре Жизнь

Напишите метод для вывода на экран вселенной. Для этого нужно использовать пакет fmt. Живые клетки представьте через звездочку, а мертвые через пробел. Не забудьте о переходе на новую строку после вывода каждой строки:

Затем напишите функцию main для создания NewUniverse и Show. Перед продолжением убедитесь, что на данном этапе вы можете запустить программу, несмотря на то, что вселенная пока пуста.

Размещение живых клеток в игре Жизнь

Напишите метод Seed, что случайным образом размещает примерно 25% живых клеток (true):

Помните, что для использования функции Intn нужен импорт пакета math/rand. По завершении обновите функцию main для заполнения вселенной с Seed и отображения работы с Show.

Реализация правил игры Жизнь в программе

Правила Игры в «Жизнь» следующие:

  • Живая клетка, у которой менее двух живых соседей, умирает;
  • Живая клетка, у которой два или три живых соседа, живет до следующего поколения;
  • Живая клетка, у которой более трех живых соседей, умирает;
  • Мертвая клетка, у которой есть ровно три живых соседа, оживает.

Для имплементации правил игры разобьем их на три этапа, каждый из которых может быть методом:

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

Жизнь или смерть?

Определить, живая клетка или мертвая, должно быть не так уж сложно. Просто осмотрите клетку в срезе Universe. Если булево значение true, тогда клетка жива.

Напишите метод Alive для типа Universe со следующей сигнатурой:

Сложности возникают, когда клетка находится за пределами вселенной. Клетка (-1,-1) живая или мертвая? На сетке 80 x 15 клетка (80,15) живая или мертвая?

Сделаем так, чтобы вселенная при выходе за пределы значений возвращалась к началу. Сосед над (0,0) будет (0,14) вместо (0,-1), что можно посчитать через добавление height к y. Если y превышает высоту height сетки, можете обратиться к оператору модуля (%), что мы ранее использовали, чтобы выяснить, является ли год високосным. Используйте % для деления y на height и сохраните остаток. То же сделайте для x и width.

Подсчет соседей в игре Жизнь

Напишите метод для подсчета живых соседей указанной клетки, от 0 до 8. Вместо получения доступа к данным вселенной напрямую используйте метод Alive, чтобы вселенная возвращалась к началу:

Убедитесь, что подсчитываются примыкающие соседи, а не клетка вопроса.

Логика игры Жизнь

Теперь вы можете определить, есть ли у клетки два, три или более соседей. Также можно реализовать правила, описанные ранее. Напишите метод Next, что делает следующее:

Не редактируйте вселенную напрямую. Вместо этого выясните, должна ли клетка быть живой или мертвой в следующем поколении.

Параллельная вселенная игры Жизнь

Для завершения симуляции вам нужно пройтись по каждой клетке вселенной и определить, каким должно быть состояние Next.

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

Простым решением проблемы станет создание двух вселенных одинакового размера. Чтение через вселенную А происходит во время размещения клеток по вселенной В. Напишите функцию Step для осуществления данной операции:

Как только вселенная В будет содержать следующее поколение, можете поменять вселенные и повторить процесс:

Для очищения экрана перед отображением нового поколения выводится "\x0c", что является специальной последовательностью ANSI для выхода. Затем отображается вселенная и используется функция Sleep из пакета time для замедления анимации.

На заметку: Кроме Go Playground вам может потребоваться другой механизм для очищения экрана. Это может быть "\033[H" на macOS.

Теперь у вас есть все необходимое для создания симулятора игры Жизнь на Golang. Напишите свою программу и запустите ее на Go Playground.

Внизу дается полный текст программы симуляторы игры Жизнь.