Go поддерживает функции первого класса, функции высшего порядка, пользовательские
типы функций, функциональные литералы, замыкания и множественные возвращаемые значения.
Этот богатый набор возможностей поддерживает функциональный стиль программирования в строго
типизированном языке.
В этом кодевёрке мы рассмотрим простую программу, которая имитирует игру в кости под названием Pig и оценивает
базовые стратегии.
doc/codewalk/pig.go
Обзор игры
Pig — это игра для двух игроков, в которой используется шестигранный кубик. Каждый ход вы можете
бросить кубик или остановиться.
Если вы бросаете единицу, вы теряете все очки за этот ход и очередь переходит к противнику.
Любое другое значение добавляется к вашему счету за ход.
Если вы останавливаетесь, очки за ход добавляются к вашему общему счету, и очередь
переходит к противнику.
Первый игрок, достигший 100 очков, побеждает.
Тип score хранит счет текущего и противостоящего игроков, а также очки, накопленные за
текущий ход.
doc/codewalk/pig.go:17,21
Пользовательские типы функций
В Go функции можно передавать точно так же, как и любые другие значения. Сигнатура типа функции
описывает типы её аргументов и возвращаемых значений.
Тип action представляет собой функцию, которая принимает score и
возвращает обновлённый score и информацию о том, завершена ли текущая очередь.
Если очередь завершена, поля player и opponent в возвращаемом
score должны быть поменяны местами, поскольку теперь очередь другого игрока.
doc/codewalk/pig.go:23,24
Множественные возвращаемые значения
Функции в Go могут возвращать несколько значений.
Функции roll и stay возвращают пару значений. Они также соответствуют
сигнатуре типа action. Эти функции action определяют правила игры Pig.
doc/codewalk/pig.go:26,41
Функции высшего порядка
Функция может использовать другие функции как аргументы и возвращаемые значения.
strategy — это функция, которая принимает score как входное значение и
возвращает action, который нужно выполнить.
(Помните, что action сам по себе является функцией.)
doc/codewalk/pig.go:43,44
Анонимные функции и замыкания
В Go можно объявлять анонимные функции, как в данном примере. Литералы функций являются замыканиями:
они наследуют область видимости функции, в которой они объявлены.
Одна из базовых стратегий в Pig — продолжать бросать кости до тех пор, пока не наберётся хотя бы k
очков в одной очереди, а затем остановиться. Аргумент k захвачен в данном литерале
функции, который соответствует сигнатуре типа strategy.
doc/codewalk/pig.go:48,53
Симуляция игр
Мы симулируем игру в Pig, вызывая
action для обновления
score до тех пор, пока один из игроков не достигнет 100 очков. Каждое
action выбирается путем вызова функции strategy, связанной с текущим
игроком.
doc/codewalk/pig.go:56,70
Моделирование турнира
Функция roundRobin моделирует турнир и подсчитывает победы.
Каждая стратегия играет с каждой другой стратегией gamesPerSeries раз.
doc/codewalk/pig.go:72,89
Объявление функций с переменным числом аргументов
Функции с переменным числом аргументов, такие как ratioString, принимают переменное
количество
аргументов. Эти аргументы доступны внутри функции в виде среза.
doc/codewalk/pig.go:91,94
Результаты моделирования
Функция main определяет 100 базовых стратегий, моделирует турнир в круговом формате,
а затем выводит таблицу побед/поражений для каждой стратегии.
Этот богатый набор возможностей поддерживает функциональный стиль программирования в строго типизированном языке.
В этом кодевёрке мы рассмотрим простую программу, которая имитирует игру в кости под названием Pig и оценивает базовые стратегии.
- Если вы бросаете единицу, вы теряете все очки за этот ход и очередь переходит к противнику.
Любое другое значение добавляется к вашему счету за ход.
- Если вы останавливаетесь, очки за ход добавляются к вашему общему счету, и очередь
переходит к противнику.
Первый игрок, достигший 100 очков, побеждает.Тип
scoreхранит счет текущего и противостоящего игроков, а также очки, накопленные за текущий ход.Тип
actionпредставляет собой функцию, которая принимаетscoreи возвращает обновлённыйscoreи информацию о том, завершена ли текущая очередь.Если очередь завершена, поля
playerиopponentв возвращаемомscoreдолжны быть поменяны местами, поскольку теперь очередь другого игрока.Функции
rollиstayвозвращают пару значений. Они также соответствуют сигнатуре типаaction. Эти функцииactionопределяют правила игры Pig.strategy— это функция, которая принимаетscoreкак входное значение и возвращаетaction, который нужно выполнить.(Помните, что
actionсам по себе является функцией.)Одна из базовых стратегий в Pig — продолжать бросать кости до тех пор, пока не наберётся хотя бы k очков в одной очереди, а затем остановиться. Аргумент
kзахвачен в данном литерале функции, который соответствует сигнатуре типаstrategy.actionдля обновленияscoreдо тех пор, пока один из игроков не достигнет 100 очков. Каждоеactionвыбирается путем вызова функцииstrategy, связанной с текущим игроком.roundRobinмоделирует турнир и подсчитывает победы. Каждая стратегия играет с каждой другой стратегиейgamesPerSeriesраз.ratioString, принимают переменное количество аргументов. Эти аргументы доступны внутри функции в виде среза.mainопределяет 100 базовых стратегий, моделирует турнир в круговом формате, а затем выводит таблицу побед/поражений для каждой стратегии.Среди этих стратегий, остановка на 25 очках является лучшей, но оптимальная стратегия для игры Pig намного сложнее.