Добро пожаловать в новую серию статей, где мы будем создавать ботов для игры StarCraft II при помощи алгоритмов искусственного интеллекта на языке Python. Примерно в середине 2017 года DeepMind и Blizzard (создатели StarCraft II) объявили о партнерстве и анонсировали API для взаимодействия со стратегической игрой.
До этого мы никогда не играли в StarCraft II, но зато играли во многие похожие игры, такие как Command and Conquer и Age of Empires. Смысл таких игр в том, чтобы соревноваться с другими игроками или компьютером.
Вы начинаете с некой «базы», в которой вы можете строить базовые юниты, собирающие ресурсы. Далее можно строить из этого новые здания, что в свою очередь открывает для вас новые юниты, например боевые. А затем вы можете совершать разные покупки юнитов и всевозможным образом их модернизировать. Ваша конечная цель — собрать армию, чтобы победить вашего противника (одного или нескольких).
В StarCraft II есть три «расы»: терраны, протоссы и зерги. Игру мы начнем за расу протоссов, так как она нам кажется наиболее технологичной. А это важно, поскольку мы планируем создать искусственный интеллект!
На следующей диаграмме показаны все здания и юниты, которые вы можете создать, играя за протоссов:
Данное изображение нами взято отсюда. Это довольно полезный ресурс для тех, кто, как и мы, понятия не имеет, что делать в реальной игре.
Как вы можете заметить, эта диаграмма имеет древовидную структуру. Таким образом, чтобы создать Верховного храмовника (High Templar), у вас для начала должен быть Нексус (Nexus). С него вы начинаете, это своего рода «командный центр» для вас. Отсюда вы строите Врата (Gateaway), затем Кибернетическое Ядро (Cybernetics Core) , затем Сумеречный Совет (Twilight Council), и только ЗАТЕМ Архивы тамплиеров (Templar Archives).
Здания, рабочие и бойцы — все это требует от вас ресурсов и, возможно, самого важного элемента: времени. Довольно сложно даже просто разобраться во всех этих строениях, юнитах и их апгрейдах. А ведь мы еще и участвуем в различных сражениях на большом количестве карт с различной топологией. Одни карты относительно открыты, а в других есть довольно мало путей, по которым можно пройти. И вам нужно решить, в какие области можно безопасно расширить свою базу, а также многое другое.
И наконец, важную роль играют ваши противники. Они идут за вами по пятам? Или оставили вас на время в покое и собирают армию? Какой они расы? Они производят обновления? Насколько сильно они расширились? И многое, многое другое. Это очень сложная и конкурентная игра, несмотря на то, что на первый взгляд кажется довольно простой .
Мы, конечно, не эксперты, и поэтому не будем тратить много времени на объяснение самой игры. Чтобы ее освоить, мы просто создали базовых ботов и запускали их в режиме реального времени, внося изменения и наблюдая, что работает лучше и дольше. Затем переписывали ботов и запускали опять.
Итак, для начала нам нужен Starcraft II. Сейчас игра бесплатна, и все, что вам нужно, это создать аккаунт, скачать игру отсюда и установить ее.
Далее, мы будем использовать библиотеку python-sc2
. Еще есть библиотека pysc2
, которая является оболочкой для Python Deepmind. На данный момент мы остановились на библиотеке python-sc2
, так как она нам кажется более простой для понимания. Однако заметим, что скорей всего pysc2
все же больше подходит для ботов с глубоким обучением, так как там есть много удобных вещей. В любом случае не забудьте установить python-sc2
: pip install sc2
.
С релизом Python 3.7 многие вещи были изменены, особенно веб-сокеты. Если у вас возникнут проблемы, откатитесь до Python 3.6.
Теперь нам понадобятся карты!
Перейдите в раздел Map Packs библиотеки Blizzard s2client
и загрузите несколько карт. Мы скачали их все, но вам это делать необязательно. Когда вы загрузите эти архивы, распакуйте карты в каталог Maps, который находится в каталоге Starcraft II. Примерная файловая структура имеет следующий вид:
StarCraft II -Maps --Ladder2017Season1 ---AbyssalReefLE.SC2Map
Если вы уже установили Starcraft II в определенную директорию, зайдите в каталог Python для сторонних разработчиков, найдите там директорию sc2
, а в ней — файл paths.py
. Далее поменяйте в нем значение переменной basedir
на соответствующее вашей директории Starcraft II.
Теперь у нас есть карты, а значит, мы готовы к путешествиям! Начнем с простого примера.
Для начала произведем импорт необходимых модулей:
import sc2 from sc2 import run_game, maps, Race, Difficulty from sc2.player import Bot, Computer
Чтобы упростить нашу жизнь, здесь все из пакета python-sc2
, включая такие вещи, как запуск игр, выбор гонок и настройка нашего противника.
Далее нам нужно создать класс нашего бота. Своего бота мы назовем SentdeBot, но вы можете выбрать любое название, которое вам по душе. Наш бот будет наследником класса sc2.BotAI
. Вы можете познакомиться с этим классом, заглянув в sc2/bot_ai.py
. Как вы можете увидеть, в нем много методов. Такие вещи, как known_enemy_units
, выглядят довольно полезными! Класс нашего бота будет начинаться так:
class SentdeBot(sc2.BotAI):
Итак, в игре мы, очевидно, хотим собрать армию и уничтожить наших врагов. Но чтобы это сделать, для начала нам потребуются определенные ресурсы. В Starcraft это минералы и газ. Что касается минералов (полезных ископаемых), нам просто нужно их добывать при помощи рабочих.
[machinelearning_ad_block]Мы начинаем с 12-ти рабочих. В расе протоссов, к которой мы принадлежим, рабочие называются зондами (probes). Нашей первоочередной задачей должно быть равномерное распределение этих сотрудников по рабочим местам. Например, вам нужно не более 3 рабочих на участок минералов, так как наличие большего количества не ускорит добычу. К счастью для нас, в родительском классе sc2.BotAI
есть метод distribute_workers
, который делает это за нас!
Итак, обеспечиваем хорошее распределение рабочих на каждом этапе:
class SentdeBot(sc2.BotAI): async def on_step(self, iteration): # what to do every step await self.distribute_workers() # in sc2/bot_ai.py
Ключевое слово async
используется для создания данных асинхронных методов, поэтому нам не нужно ждать завершения каждого из них, чтобы исполнять другой код.
Давайте предположим, что все, чего мы хотим, это распределять рабочих в играх. В таком случае у нас все готово! Для запуска игры мы будем использовать метод run_game
. Сперва эта функция принимает карту, которую вы хотите запустить, а затем — список игроков. После этого вы можете указать, хотите ли вы играть в режиме реального времени (по сути — обычная скорость или супербыстро).
run_game(maps.get("AbyssalReefLE"), [ Bot(Race.Protoss, SentdeBot()), Computer(Race.Terran, Difficulty.Easy) ], realtime=True)
Итак, мы будем играть по карте AbyssalReefLE
. Играть будет бот, принадлежащий к расе протоссов, а класс бота будет называться SentdeBot
. Вторым игроком будет компьютер, выступающий за расу терранов. Его уровень сложности будет невысоким. Больше игроков не будет.
Запускайте код: игра начнется и ваш бот будет работать!
Наш код на данный момент имеет следующий вид:
import sc2 from sc2 import run_game, maps, Race, Difficulty from sc2.player import Bot, Computer class SentdeBot(sc2.BotAI): async def on_step(self, iteration): # what to do every step await self.distribute_workers() # in sc2/bot_ai.py run_game(maps.get("AbyssalReefLE"), [ Bot(Race.Protoss, SentdeBot()), Computer(Race.Terran, Difficulty.Easy) ], realtime=True)
Не хотелось бы вас огорчать, но таким образом никакой игры не выиграть. Тем не менее, у нас уже есть бот! В следующей статье мы будем работать над добавлением в него дополнительных функций, которые позволят начать выигрывать в каких-нибудь играх.
Следующая статья — Python AI в StarCraft II. Часть II: рабочие и пилоны.