Python编写AI机器人玩爆星际争霸系列(4)

timg

经过前几节的努力,我们已经实现了训练工人、基地扩张和建造气矿,接下来当我们工人、基地和资源积累到一定程度,我们就可以开始建造第一只军队:Stalker(追猎者)。

追猎者是神族的基本作战兵种,操作性强,攻击力高,可研发闪现,可使追猎者瞬间传送到范围内的目标可见地点,但有冷却时间,可用于脱离战斗、追击敌人或是闪现进入敌方基地点杀重要建筑和工作单位,在敌人的部队被调回防守时利用闪现逃走。(在星际争霸的史诗中是这样介绍追猎者的:星灵的一个分支:黑暗圣堂武士拒绝融入神族共同的幽能联结——卡拉。因此很久以前,他们被驱逐出了自己的家园艾尔行星,最终在遥远的萨古拉斯星球找到了栖身之所。通过汇聚体内的幽能之力和抽取虚空中的能量,受古老龙骑士(星际争霸1中的兵种)行走方式的启发,他们创造了追猎者,一种由黑暗圣堂武士战斗精髓控制的战斗机器。追猎者装备的粒子碎裂炮,在扩增得当的情况下,可以瞬间实现地区间的传送。这让追猎者能从无法预料的位置发起攻击,也可以捕获逃跑的敌人,或是从被动的局面中脱离。)

stalker-300

要建造追猎者,我们需要依次建造 Gateway(星门,也是神族的基础兵营) > Cybernetics Core(机械核心,升级攻防的科技建筑,可以解锁Stalker生产科技) > Stalker(追猎者)。

其中星门是这个金黄色的建筑:

th

 

机械核心建筑是这样的:

th (1)

 

好的,那接下来我们在前一节的代码基础上依次实现建造这两个建筑!

首先我们现在on_step方法下增加建造追猎者所需要的兵营及科技建筑方法:

class MrBot(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() # 建造所需兵营及科技建筑

其中offensive_force_buildings如下:

  async def offensive_force_buildings(self):
        if self.units(PYLON).ready.exists:
            pylon = self.units(PYLON).ready.random # 选择一个Pylon附近建造
            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)

接下来,我们就开始建造Stalker(追猎者):

class MrBot(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() # 建造Stalker方法

其中build_offensive_force方法如下:

async def build_offensive_force(self): 
        for gw in self.units(GATEWAY).ready.noqueue: # gw是gateway缩写
            if self.can_afford(STALKER) and self.supply_left > 0: 
                await self.do(gw.train(STALKER))

 

完整代码如下:

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 MrBot(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 < 2 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("(2)CatalystLE"), [
    Bot(Race.Protoss, MrBot()),
    Computer(Race.Terran, Difficulty.Easy)
    ], realtime=False)

实际运行游戏界面:

微信图片_20180709213114

 

 

未经允许不得转载:Mr.开发者 » Python编写AI机器人玩爆星际争霸系列(4)

赞 (0)
分享到:更多 ()