Безумие вероятностей или Пишу бота для Дурака

6 April
Безумие вероятностей или Пишу бота для Дурака

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

Писать бота буду для игры в карты в Дурака на платформе E-Champ. Ее плюсами являются открытый исходный код (JavaScript), бесплатное окружение (Node.js), простота настройки и подключения новых модулей.

E-Champ Дурак поддерживает до шести игроков одновременно (компьютерных и/или удаленных соперников), а также множество опций самой игры:

  • переводной дурак
  • подкидной дурак
  • колода 36 или 52 карты
  • игра без козыря
  • и другие.

Начало

Итак, создаю новый репозиторий на основе e-champ-app и клонирую его к себе на локальную машину в папку /app. В конфигурации приложения уже присутствует игра в Дурака.

Для подключения нового бота добавляю данные в конфигурацию игры. Назову бота - Шляпник, потому что стиль его игры будет непредсказуем и безумен.

Конфигурация бота
Конфигурация бота
Конфигурация бота

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

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

Атака

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

Метод разрешения атаки
Метод разрешения атаки
Метод разрешения атаки

В начале ставим условия при которых бот не будет атаковать. Из обязательных условий - это наличие карт на столе и наличие карт в банке.
Первое определяется правилами, а второе оградит от пропуска атаки ближе к концу игры, иначе могут возникать совсем уж позорные ситуации даже для Шляпника.

Последняя проверка - это попадание случайного значения в вероятность паса. Значение вероятности должно находиться между 0 и 1.
Чем ближе к 0, тем меньше шанс, что игрок пасует.

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

Если выпал шанс атаковать, то просто выбираем случайную карту из возможных.

Защита

При защите в Дураке есть два варианта - либо отбиться, либо забрать карты.

В переводном Дураке есть и третий вариант - перевести атаку на соперника, но оставлю это в стандартном исполнении.

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

Метод разрешения защиты
Метод разрешения защиты
Метод разрешения защиты

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

Вот все и готово!

Запуск

Для запуска приложения необходимо либо установить окружение Node.js и сервер базы данных Mongo, либо собрать и запустить приложение через Docker.

Для Windows

cd c:/app
npm install
set NODE_ENV=development
node console/install
node console/start

Для Linux

cd /app
npm install
NODE_ENV=development node console/install
NODE_ENV=development node console/start

Через Docker

cd /app
docker-compose up -d mongo
docker-compose up --build installer
docker-compose up -d server

Переходим по адресу http://localhost:3000 и наслаждаемся карточным безумием Шляпника!

Атака ботов в Дураке
Атака ботов в Дураке
Атака ботов в Дураке

Живая демонстрация доступна на сайте nervebit.com.

P. S. Кстати, при игре один на один и пустом банке Дурак становится игрой с полной информаций и в принципе поддается анализу тем же минимаксом...