Skip to content

Advanced Build Order Tricks

DrInfy edited this page Jul 23, 2021 · 5 revisions

Enabling / Disabling Builds in settings

You can store your allowed builds in settings.ini by adding a [builds] section.

[builds]
mybot_vs_zerg = macro cheese
mybot_vs_protoss = cheese
mybot_vs_terran = macro
mybot_vs_random = macro cheese

You can read them in your code with

if self.knowledge.enemy_race == Race.Zerg:
    key = "builds.mybot_vs_zerg "
elif self.knowledge.enemy_race == Race.Terran:
    key = "builds.mybot_vs_terran "
elif self.knowledge.enemy_race == Race.Protoss:
    key = "builds.mybot_vs_protoss"
else:
    key = "builds.mybot_vs_random "

build_keys = self.knowledge.get_str_setting(key).split(" ")

Selecting builds on the fly

Sharpy requires you to define the BuildOrder at the create_plan at the start of the game.

Let's assume we have some builds for a bot.

builds: Dict[str, Callable[[], BuildOrder]] = {
    "lings": lambda: LingBuild(),
    "roaches": lambda: RoachBuild(),
    "hydras": lambda: HydraBuild()
}


class BuildSelector(ManagerBase):
    def __init__(self, build_name: str):
        self.dynamic = build_name == "default"
        if self.dynamic: # self.dynamic is not part of Sharpy's API, it is a Boolean parameter that we created for this solution
            assert build_name in builds.keys()
            self.response = build_name
        else:
            self.response = "lings"
        
        super().__init__()

    async def update(self):
        if not self.dynamic:
            # Do not change build, because we are in testing mode
            return
            
        if self.response == "lings" and self.cache.own(UnitTypeId.ZERGLING).amount > 20:
            # There's enough zerglings, let's start making roaches.
            self.response = "roaches"
        elif (self.response != "hydras" 
                and self.knowledge.game_analyzer.enemy_power.air_presence > 10):
            # Simple condition for when enemy has air based army
            self.response = "hydras"

    async def post_update(self):            
        pass

            
class MyBot(KnowledgeBot):
    def __init__(self, build_name: str = "default"):
        """ 
        bringing build_name as optional parameter allows the bot to be initialized with 
        'mybot.lings' for testing 
        """
        super().__init__("MyBot")
        self.build_name = build_name  # do not use "build" as name in bot.
        self.build_selector = BuildSelector("lings")
    
    def configure_managers(self) -> Optional[List[ManagerBase]]:
        return [self.build_selector]
        
    async def create_plan(self) -> BuildOrder:
        builds = []
        for key, build_order_call in early_builds.items():
            builds.append(
                Step(None, build_order_call(), 
                    skip_until=lambda k, key=key: self.build_selector.response == key
                )
            )
        
        return BuildOrder(builds, 
            [
                # Add tactics here
            ]
                                     
Clone this wiki locally