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

Python AI в StarCraft II. Часть V: командование армией

15.05.2021Category : Python

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

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

Сейчас наш код имеет следующий вид:

import sc2 from sc2 import run_game, maps, Race, Difficulty from sc2.player import Bot, Computer from sc2.constants import NEXUS, PROBE, PYLON, ASSIMILATOR, GATEWAY,   CYBERNETICSCORE, STALKER   class SentdeBot(sc2.BotAI):     async def on_step(self, iteration):         await self.distribute_workers()         await self.build_workers()         await self.build_pylons()         await self.build_assimilators()         await self.expand()         await self.offensive_force_buildings()         await self.build_offensive_force()      async def build_workers(self):         for nexus in self.units(NEXUS).ready.noqueue:             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 build_assimilators(self):         for nexus in self.units(NEXUS).ready:             vaspenes = self.state.vespene_geyser.closer_than(15.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 expand(self):         if self.units(NEXUS).amount < 3 and self.can_afford(NEXUS):             await self.expand_now()      async def offensive_force_buildings(self):         if self.units(PYLON).ready.exists:             pylon = self.units(PYLON).ready.random             if self.units(GATEWAY).ready.exists:                 if not self.units(CYBERNETICSCORE):                     if self.can_afford(CYBERNETICSCORE) and not self.already_pending(CYBERNETICSCORE):                         await self.build(CYBERNETICSCORE, near=pylon)             else:                 if self.can_afford(GATEWAY) and not self.already_pending(GATEWAY):                     await self.build(GATEWAY, near=pylon)      async def build_offensive_force(self):         for gw in self.units(GATEWAY).ready.noqueue:             if self.can_afford(STALKER) and self.supply_left > 0:                 await self.do(gw.train(STALKER))   run_game(maps.get("AbyssalReefLE"), [     Bot(Race.Protoss, SentdeBot()),     Computer(Race.Terran, Difficulty.Easy)     ], realtime=False)

Теперь нам надо добавить к нашему методу on_step метод наступления:

class SentdeBot(sc2.BotAI):     async def on_step(self, iteration):         await self.distribute_workers()         await self.build_workers()         await self.build_pylons()         await self.build_assimilators()         await self.expand()         await self.offensive_force_buildings()         await self.build_offensive_force()         await self.attack()

Базовый метод attack может выглядеть примерно так:

async def attack(self):         if self.units(STALKER).amount > 3:             if len(self.known_enemy_units) > 0:                 for s in self.units(STALKER).idle:                     await self.do(s.attack(random.choice(self.known_enemy_units)))

Итак, если у нас есть более трех Сталкеров, мы знаем, где находятся вражеские отряды, и наши Сталкеры ничем больше не заняты, давайте атакуем один из вражеских отрядов.

python ai v starcraft ii chast v komandovanie armiej b5fd76e - Python AI в StarCraft II. Часть V: командование армией

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

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

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

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

async def attack(self):         if self.units(STALKER).amount > 15:             for s in self.units(STALKER).idle:                 await self.do(s.attack(self.find_target(self.state)))          elif self.units(STALKER).amount > 3:             if len(self.known_enemy_units) > 0:                 for s in self.units(STALKER).idle:                     await self.do(s.attack(random.choice(self.known_enemy_units)))

Имея больше 15 юнитов, мы найдем любую цель. В противном случае, если у нас больше трех юнитов и мы знаем, где находятся вражеские юниты, мы пойдем за ними. Чтобы знать, где находятся враги, мы должны их видеть. При этом мы также знаем, где находится начальное расположение противника, так что, имея достаточно большую армию, мы будем знать, куда идти, чтобы начать бой. Однако у нас еще нет метода find_target. Давайте его напишем.

    def find_target(self, state):         if len(self.known_enemy_units) > 0:             return random.choice(self.known_enemy_units)         elif len(self.known_enemy_structures) > 0:             return random.choice(self.known_enemy_structures)         else:             return self.enemy_start_locations[0]

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

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

Полный код на данный момент имеет вот такой вид:

import sc2 from sc2 import run_game, maps, Race, Difficulty from sc2.player import Bot, Computer from sc2.constants import NEXUS, PROBE, PYLON, ASSIMILATOR, GATEWAY,   CYBERNETICSCORE, STALKER import random   class SentdeBot(sc2.BotAI):     async def on_step(self, iteration):         await self.distribute_workers()         await self.build_workers()         await self.build_pylons()         await self.build_assimilators()         await self.expand()         await self.offensive_force_buildings()         await self.build_offensive_force()         await self.attack()      async def build_workers(self):         for nexus in self.units(NEXUS).ready.noqueue:             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 build_assimilators(self):         for nexus in self.units(NEXUS).ready:             vaspenes = self.state.vespene_geyser.closer_than(15.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 expand(self):         if self.units(NEXUS).amount < 3 and self.can_afford(NEXUS):             await self.expand_now()      async def offensive_force_buildings(self):         if self.units(PYLON).ready.exists:             pylon = self.units(PYLON).ready.random              if self.units(GATEWAY).ready.exists and not self.units(CYBERNETICSCORE):                 if self.can_afford(CYBERNETICSCORE) and not self.already_pending(CYBERNETICSCORE):                     await self.build(CYBERNETICSCORE, near=pylon)              elif len(self.units(GATEWAY)) < 3:                 if self.can_afford(GATEWAY) and not self.already_pending(GATEWAY):                     await self.build(GATEWAY, near=pylon)      async def build_offensive_force(self):         for gw in self.units(GATEWAY).ready.noqueue:             if self.can_afford(STALKER) and self.supply_left > 0:                 await self.do(gw.train(STALKER))      def find_target(self, state):         if len(self.known_enemy_units) > 0:             return random.choice(self.known_enemy_units)         elif len(self.known_enemy_structures) > 0:             return random.choice(self.known_enemy_structures)         else:             return self.enemy_start_locations[0]      async def attack(self):         if self.units(STALKER).amount > 15:             for s in self.units(STALKER).idle:                 await self.do(s.attack(self.find_target(self.state)))          elif self.units(STALKER).amount > 3:             if len(self.known_enemy_units) > 0:                 for s in self.units(STALKER).idle:                     await self.do(s.attack(random.choice(self.known_enemy_units)))   run_game(maps.get("AbyssalReefLE"), [     Bot(Race.Protoss, SentdeBot()),     Computer(Race.Terran, Difficulty.Easy)     ], realtime=False)

Данный бот вполне хорош, чтобы побеждать AI слабого и среднего уровня:

python ai v starcraft ii chast v komandovanie armiej 2650ccf - Python AI в StarCraft II. Часть V: командование армией

Но от сильного AI мы потерпели поражение! Насколько мы можем судить, сильный AI гораздо лучше умеет собирать армию, которая намного превосходит по силе нашу. Итак, теперь мы сосредоточимся над тем, как лучше подготовить нашу армию для победы над сильным AI.

Следующая статья — Python AI в StarCraft II. Часть VI: побеждаем сильный AI.

python ai v starcraft ii chast v komandovanie armiej 453d029 - Python AI в StarCraft II. Часть V: командование армией

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

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

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

  • 1 views
  • 0 Comment

Leave a Reply

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

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

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

    Рубрики

    About Author 01.

    Roman Spiridonov
    Roman Spiridonov

    Привет ! Мне 38 лет, я работаю в области информационных технологий более 4 лет. Тут собрано самое интересное.

    Our Instagram 04.

    Categories 05.

    © Speccy 2020 / All rights reserved

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