java

Ещё кофе? (разработка бота для BlackJack на Java)

Некоторое время назад начал изучать Java. Кто не знает — язык программирования от Sun, ныне им владеет Oracle. С первых дней инструмент порадовал своей мощью. В первую очередь продвинутыми средствами объектно-ориентированного программирования. Всё строго, точно и функционально.

Позанимавшись немного с самоучителем, я решил сделать небольшой проект. В образовательных целях. Задачу поставил себе так: написать самообучающийся бот для игры в BlackJack. «Мозгами» боту служит искусственная нейронная сеть, привязанная к каждому из виртуальных картёжников. На вход сети подаём сигналы об имеющихся на руках у игрока картах. Выход ещё более простой — решение взять новую карту или остановиться. Ну и несколько скрытых полносвязных слоёв, где и происходит вся «магия». Обучать агентов будем, используя генетические алгоритмы, заставляя многократно играть с себе подобными.

А теперь обо всём по порядку.

Black Jack

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

  • GameBlackJack — экземпляр одной игры. Хранит данные об игроках и запускает поединок между ними. Реализует внутри-игровую логику, согласно принятым в правилам.
  • Hand — стопка карт, условно называемая «рукой». Помимо «руки» игрока это также общая колода и выложеннные карты на столе. Можно перемешивать колоду, перемещать карты и подсчитывать суммарное количество очков на «руках».
  • Card — одна игральная карта. Устроена очень просто — у неё есть Масть и Значение. Её можно перемещать из «руки» в «руку«.

BlackJack

Нейронная сеть

Отвечает за те решения, которые принимает игрок. Как уже было сказано выше — на вход принимает имеющиеся у игрока карты (54 нейрона). На выходе — решение: добрать ещё карт или остановиться. В качестве архитектуры была выбрана полносвязная сеть с несколькими скрытыми слоями.

  • NeuroNet — экземпляр нейронной сети, принадлежащий некоторому игроку. Хранит данные о внутренних слоях, получает исходные данные и вычисляет итоговое решение.
  • Layer — слой нейронной сети. Может быть как входным, так входным или скрытым. Состоит из нейронов.
  • Neuron — один нейрон, принадлежащий какому-то слою. Имеет величину сигнала, которую он получил от предыдущего слоя и который будет передан следующему слою. К нейрону привязаны аксоны, позволяющие ему сообщаться с предыдущими слоями (входной слой не имеет собственных аксонов).
  • Axon — аксон. Связывает два нейрона. Имеет вес связи. Чем более значительный вес — тем более сильный сигнал будет передан.

NeuroNet

Генетические алгоритмы

После того, как каждый из агентов сыграл несколько партий с другими агентами, программа оценивает их результативность и выбирает лучших (осуществляет т.н. «селекцию»). На их основе будут получены новый набор (его называют «поколение») агенты с небольшими изменениями, называемые «мутациями». Таким образом, от поколения к поколению, игроки всё больше адаптируются к игре и становятся всё больше результативными. Такой подход называется «генетическими алгоритмами», поскольку схож по механизму с эволюцией в живой природе.

  • Selection — осуществляет селекцию поколений. Из заданного поколения выбирает лучших агентов и порождает на их основе новое поколение, изменяя и адаптируя их нейронные сети.
  • Generation — одно поколение агентов. Содержит в себе несколько игроков.
  • Player — один игрок, принадлежащий какому-либо поколению. Содержит нейронную сеть, которая принимает решения в ходе игры, а также руку, в которой содержатся карты для одной игры.
  • ScoreGen — вспомогательный класс, подсчитывающий результативность игр внутри одного поколения.

В результате

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

https://github.com/gigabyte-artur/blackjack_ai

Дальнейшее развитие

Что хотелось бы ещё доработать, чего пока не хватает…

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

BlackJackAi_UML

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *