Share This
Связаться со мной
Крути в низ
Categories
//Python AI в StarCraft II. Часть III: гейзеры и экспансия

Python AI в StarCraft II. Часть III: гейзеры и экспансия

12.05.2021Category : Python

python ai v starcraft ii chast iii gejzery i ekspansija 0d75983 - Python AI в StarCraft II. Часть III: гейзеры и экспансия

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

В третьей части серии статей про использование AI в игре Starcraft II мы займёмся добычей другого очень важного ресурса — газа. А также произведем экспансию в другие регионы.

В конце концов наша область истощится. Не забывайте, что нам нужно всего трое рабочих на один участок с полезными ископаемыми. В итоге нам нужно расширяться. Однако к расширению не следует относиться слишком легкомысленно. При расширении вы ослабляете свою защиту. Тем не менее, когда мы истощим нашу область, нам придется задуматься о расширении. К счастью, это для нас несложная задача, поскольку некоторая логика расширения уже для нас реализована. Давайте добавим add await self.expand() в наш метод on_step:

    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         await self.expand()  

Теперь наш метод expand имеет следующий вид:

    async def expand(self):         if self.units(NEXUS).amount < 2 and self.can_afford(NEXUS):             await self.expand_now()

В приведенном выше случае мы ограничиваем наши расширения только двумя локациями. Rод для метода expand_now можно найти в файле sc2 / bot_ai.py.

Наш полный код на данный момент выглядит следующим образом:

import sc2 from sc2 import run_game, maps, Race, Difficulty from sc2.player import Bot, Computer  from sc2.constants import NEXUS, PROBE, PYLON  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         await self.expand()       async def build_workers(self):         # nexus = command center         for nexus in self.units(NEXUS).ready.noqueue:             # we want at least 20 workers, otherwise let's allocate 70% of our supply to workers.             # later we should use some sort of regression algo maybe for this?              if self.can_afford(PROBE):                 await self.do(nexus.train(PROBE))      async def build_pylons(self):         if self.supply_left &lt; 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)      async def expand(self):         if self.units(NEXUS).amount &lt; 2 and self.can_afford(NEXUS):             await self.expand_now()   run_game(maps.get("AbyssalReefLE"), [     Bot(Race.Protoss, SentdeBot()),     Computer(Race.Terran, Difficulty.Easy) ], realtime=False)

Вот теперь-то мы развернемся! У нас есть 2 зоны командного центра и быстрорастущая коллекция ресурсов. Далее нужно сосредоточиться на том, что нам требуется для создания нашей армии (о ней речь пойдет в следующем уроке).

python ai v starcraft ii chast iii gejzery i ekspansija 18bb922 - Python AI в StarCraft II. Часть III: гейзеры и экспансия

Больше материалов по машинному обучению

Подписывайтесь на нас в Телеграм

Подписаться ×

Когда мы приблизимся к нашей цели собрать армию и атаковать нашего врага, мы обнаружим, что нам понадобится топливо (газ). Газ собирают из гейзеров Веспен, разбросанных по карте. Для расы протоссов здание, необходимое для сбора этого газа, называется ассимилятором (класс Assimilator). Нам нужно построить его прямо над гейзерами.

Чтобы произвести постройку, нам надо импортировать класс Assimilator. Поэтому давайте для начала добавим его в наш стандартный импорт:

from sc2.constants import NEXUS, PROBE, PYLON, ASSIMILATOR

Теперь давайте добавим await self.build_assimilator() в наш метод on_step, после чего он приобретет следующий вид:

class SentdeBot(sc2.BotAI):     async def on_step(self, iteration):         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         await self.expand()  # expand to a new resource area.         await self.build_assimilator()  # getting gas

А теперь нам нужно написать этот метод. Как вы, вероятно, догадываетесь, найти правильный гейзер и построить прямо на нем здание может оказаться серьезной проблемой для написания кода. К счастью для нас, большая часть этой работы была уже сделана.

Например, мы можем найти доступные гейзеры рядом с нашим Нексусом с помощью API. У нас есть по одному Нексусу на каждую ресурсную область — так мы и будем их находить.

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

Наконец, мы можем построить что-то, обратившись к рабочему юниту. Для этого нужно просто выполнить .build (THING, WHERE).

Приступим.

Сначала мы хотим перебрать все наши нексусы, а затем все васпены (другое название для месторождений газа в Starcraft II), находящиеся в радиусе ~ 25 единиц от нексуса:

    async def build_assimilator(self):         for nexus in self.units(NEXUS).ready:             vaspenes = self.state.vespene_geyser.closer_than(25.0, nexus)

Отлично, мы нашли васпены. Теперь мы хотим строить. Как обычно, если у нас нет необходимых средств, строить мы не можем:

    async def build_assimilator(self):         for nexus in self.units(NEXUS).ready:             vaspenes = self.state.vespene_geyser.closer_than(25.0, nexus)             for vaspene in vaspenes:                 if not self.can_afford(ASSIMILATOR):                     break

В противном случае нам нужно выбрать доступного рабочего:

    async def build_assimilator(self):         for nexus in self.units(NEXUS).ready:             vaspenes = self.state.vespene_geyser.closer_than(25.0, nexus)             for vaspene in vaspenes:                 if not self.can_afford(ASSIMILATOR):                     break                 worker = self.select_build_worker(vaspene.position)                 if worker is None:                     break

Если у нас есть место, средства и рабочий, можно строить ассимилятор (если, конечно, поблизости уже нет построенного)!

                if not self.units(ASSIMILATOR).closer_than(1.0, vaspene).exists:                     await self.do(worker.build(ASSIMILATOR, vaspene))

Весь метод выглядит вот так:

    async def build_assimilator(self):         for nexus in self.units(NEXUS).ready:             vaspenes = self.state.vespene_geyser.closer_than(25.0, nexus)             for vaspene in vaspenes:                 if not self.can_afford(ASSIMILATOR):                     break                 worker = self.select_build_worker(vaspene.position)                 if worker is None:                     break                 if not self.units(ASSIMILATOR).closer_than(1.0, vaspene).exists:                     await self.do(worker.build(ASSIMILATOR, vaspene))

А полный код теперь имеет вот такой вид:

import sc2 from sc2 import run_game, maps, Race, Difficulty from sc2.player import Bot, Computer from sc2.constants import NEXUS, PROBE, PYLON, ASSIMILATOR   class SentdeBot(sc2.BotAI):     async def on_step(self, iteration):         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         await self.expand()  # expand to a new resource area.         await self.build_assimilator()  # getting gas      async def build_workers(self):         # nexus = command center         for nexus in self.units(NEXUS).ready.noqueue:             # we want at least 20 workers, otherwise let's allocate 70% of our supply to workers.             # later we should use some sort of regression algo maybe for this?              if self.can_afford(PROBE):                 await self.do(nexus.train(PROBE))      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)      async def expand(self):         if self.units(NEXUS).amount < 2 and self.can_afford(NEXUS):             await self.expand_now()      async def build_assimilator(self):         for nexus in self.units(NEXUS).ready:             vaspenes = self.state.vespene_geyser.closer_than(25.0, nexus)             for vaspene in vaspenes:                 if not self.can_afford(ASSIMILATOR):                     break                 worker = self.select_build_worker(vaspene.position)                 if worker is None:                     break                 if not self.units(ASSIMILATOR).closer_than(1.0, vaspene).exists:                     await self.do(worker.build(ASSIMILATOR, vaspene))   run_game(maps.get("AbyssalReefLE"), [     Bot(Race.Protoss, SentdeBot()),     Computer(Race.Terran, Difficulty.Easy) ], realtime=False)

Запустив его, мы можем убедиться, что идет строительство ассимиляторов:

python ai v starcraft ii chast iii gejzery i ekspansija 60b908e - Python AI в StarCraft II. Часть III: гейзеры и экспансия

Потрясающе! Теперь давайте займемся созданием армии! Но уже в следующей статье.

Следующая статья — Python AI в StarCraft II. Часть IV: создание AI армии.

python ai v starcraft ii chast iii gejzery i ekspansija 6b25b32 - Python AI в StarCraft II. Часть III: гейзеры и экспансия

Больше материалов по машинному обучению

Подписывайтесь на нас в Телеграм

Подписаться ×

  • 3 views
  • 0 Comment

Leave a Reply

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

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Свежие комментарии

    Рубрики

    About Author 01.

    blank
    Roman Spiridonov

    Моя специальность - Back-end Developer, Software Engineer Python. Мне 39 лет, я работаю в области информационных технологий более 5 лет. Опыт программирования на Python более 3 лет. На Django более 2 лет.

    Categories 05.

    © Speccy 2020 / All rights reserved

    Связаться со мной
    Close