Python AI в StarCraft II. Часть II: рабочие и пилоны

Предыдущая статья — Python AI в StarCraft II. Часть I: введение и добыча минералов.

Добро пожаловать во вторую часть серии статей про использование искусственного интеллекта в игре Starcraft II. В предыдущей части мы написали простого бота, который только собирает ресурсы при помощи доступных рабочих. А теперь мы хотим иметь больше рабочих, чтобы быстрее добывать минералы!

Начальный код из предыдущей статьи имеет следующий вид:

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)

Написать его было несложно, так как метод distribute_workers уже существовал. Но такая роскошь будет не всегда. Например, нам нужно больше рабочих. Добавим в наш класс вызов метода build_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
        await self.build_workers()

Однако такого метода (build_workers) не существует. Нам нужно его написать. Чтобы создать рабочих, нам нужно получить доступ к нашему объекту NEXUS в игре. Напомним, NEXUS — это командный центр для расы протоссов. Мы собираемся создать рабочих, которые называются Probes для класса Protoss, поэтому нам также необходимо взаимодействовать с объектом PROBE. Импортируем эти объекты:

from sc2.constants import NEXUS, PROBE, PYLON

Чтобы создать рабочих, нам нужно использовать нексус или одно из наших зданий нексуса. А затем давайте сделаем еще одного зонда (рабочего), если сможем себе это позволить.

[machinelearning_ad_block]

Еще одна небольшая деталь: строения, которые производят такие юниты, могут делать их за один раз в небольшом количестве, например не более пяти. Когда игроком является человек, может быть удобно просто поставить в очередь все 5 заданий одновременно и заниматься другими делами. Но когда играет AI, в очередях смысла нет. В отличие от человека, он может управлять всеми юнитами и/или зданиями одновременно. Люди так слабы и медлительны!

Итак, вот метод build_workers для создания наших рабочих:

    async def build_workers(self):
        # nexus = command center
        for nexus in self.units(NEXUS).ready.noqueue:
            if self.can_afford(PROBE):
                await self.do(nexus.train(PROBE))

Мы уже могли бы запустить этот код, но у нас возникнет проблема с запасами (Supply). В целом, «запас» определяет количество юнитов, которые нам разрешено производить. Юниты — это рабочие, истребители, корабли и так далее. Чтобы увеличить наш «запас» (supply), нам нужно построить больше пилонов. Давайте сделаем это.

Добавим await self.build_pylons() в наш метод  on_step:

class SentdeBot(sc2.BotAI):
    async def on_step(self, iteration):
        # what to do every step
        await self.distribute_workers()  # in sc2/bot_ai.py
        await self.build_workers()  # workers bc obviously
        await self.build_pylons()  # pylons are protoss supply buildings

Далее давайте напишем метод build_pylons. В нем будет следующее условие: если наши запасы меньше или равны n, то мы производим пилона. Мы хотим строить пилоны вокруг наших зданий Нексуса (нашей основной базы). Класс Protoss требует, чтобы вы строили свои здания внутри зоны псионной матрицы (Psionic Matrix). Пилоны расширяют эту матрицу и увеличивают ваши запасы.

    async def build_pylons(self):
        if self.supply_left < 5 and not self.already_pending(PYLON):
            nexuses = self.units(NEXUS).ready
            if nexuses.exists:
                if self.can_afford(PYLON):
                    await self.build(PYLON, near=nexuses.first)

Обратите внимание: чтобы не тратить ресурсы впустую, мы также проверяем, нет ли у нас уже строящегося пилона.

Запустив этот код, мы произведем дополнительных пилонов и рабочих, если это нужно и возможно:

pylons and workers ai

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

Следующая статья — Python AI в StarCraft II. Часть III: гейзеры и экспансия.