mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 20:21:32 -06:00
155
worlds/_sc2common/bot/observer_ai.py
Normal file
155
worlds/_sc2common/bot/observer_ai.py
Normal file
@@ -0,0 +1,155 @@
|
||||
"""
|
||||
This class is very experimental and probably not up to date and needs to be refurbished.
|
||||
If it works, you can watch replays with it.
|
||||
"""
|
||||
|
||||
# pylint: disable=W0201,W0212
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, List, Union
|
||||
|
||||
from .bot_ai_internal import BotAIInternal
|
||||
from .data import Alert, Result
|
||||
from .game_data import GameData
|
||||
from .position import Point2
|
||||
from .unit import Unit
|
||||
from .units import Units
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .client import Client
|
||||
from .game_info import GameInfo
|
||||
|
||||
|
||||
class ObserverAI(BotAIInternal):
|
||||
"""Base class for bots."""
|
||||
|
||||
@property
|
||||
def time(self) -> float:
|
||||
""" Returns time in seconds, assumes the game is played on 'faster' """
|
||||
return self.state.game_loop / 22.4 # / (1/1.4) * (1/16)
|
||||
|
||||
@property
|
||||
def time_formatted(self) -> str:
|
||||
""" Returns time as string in min:sec format """
|
||||
t = self.time
|
||||
return f"{int(t // 60):02}:{int(t % 60):02}"
|
||||
|
||||
@property
|
||||
def game_info(self) -> GameInfo:
|
||||
""" See game_info.py """
|
||||
return self._game_info
|
||||
|
||||
@property
|
||||
def game_data(self) -> GameData:
|
||||
""" See game_data.py """
|
||||
return self._game_data
|
||||
|
||||
@property
|
||||
def client(self) -> Client:
|
||||
""" See client.py """
|
||||
return self._client
|
||||
|
||||
def alert(self, alert_code: Alert) -> bool:
|
||||
"""
|
||||
Check if alert is triggered in the current step.
|
||||
Possible alerts are listed here https://github.com/Blizzard/s2client-proto/blob/e38efed74c03bec90f74b330ea1adda9215e655f/s2clientprotocol/sc2api.proto#L679-L702
|
||||
|
||||
Example use:
|
||||
|
||||
from sc2.data import Alert
|
||||
if self.alert(Alert.AddOnComplete):
|
||||
print("Addon Complete")
|
||||
|
||||
Alert codes::
|
||||
|
||||
AlertError
|
||||
AddOnComplete
|
||||
BuildingComplete
|
||||
BuildingUnderAttack
|
||||
LarvaHatched
|
||||
MergeComplete
|
||||
MineralsExhausted
|
||||
MorphComplete
|
||||
MothershipComplete
|
||||
MULEExpired
|
||||
NuclearLaunchDetected
|
||||
NukeComplete
|
||||
NydusWormDetected
|
||||
ResearchComplete
|
||||
TrainError
|
||||
TrainUnitComplete
|
||||
TrainWorkerComplete
|
||||
TransformationComplete
|
||||
UnitUnderAttack
|
||||
UpgradeComplete
|
||||
VespeneExhausted
|
||||
WarpInComplete
|
||||
|
||||
:param alert_code:
|
||||
"""
|
||||
assert isinstance(alert_code, Alert), f"alert_code {alert_code} is no Alert"
|
||||
return alert_code.value in self.state.alerts
|
||||
|
||||
@property
|
||||
def start_location(self) -> Point2:
|
||||
"""
|
||||
Returns the spawn location of the bot, using the position of the first created townhall.
|
||||
This will be None if the bot is run on an arcade or custom map that does not feature townhalls at game start.
|
||||
"""
|
||||
return self.game_info.player_start_location
|
||||
|
||||
@property
|
||||
def enemy_start_locations(self) -> List[Point2]:
|
||||
"""Possible start locations for enemies."""
|
||||
return self.game_info.start_locations
|
||||
|
||||
async def on_unit_destroyed(self, unit_tag: int):
|
||||
"""
|
||||
Override this in your bot class.
|
||||
This will event will be called when a unit (or structure, friendly or enemy) dies.
|
||||
For enemy units, this only works if the enemy unit was in vision on death.
|
||||
|
||||
:param unit_tag:
|
||||
"""
|
||||
|
||||
async def on_unit_created(self, unit: Unit):
|
||||
"""Override this in your bot class. This function is called when a unit is created.
|
||||
|
||||
:param unit:"""
|
||||
|
||||
async def on_building_construction_started(self, unit: Unit):
|
||||
"""
|
||||
Override this in your bot class.
|
||||
This function is called when a building construction has started.
|
||||
|
||||
:param unit:
|
||||
"""
|
||||
|
||||
async def on_building_construction_complete(self, unit: Unit):
|
||||
"""
|
||||
Override this in your bot class. This function is called when a building
|
||||
construction is completed.
|
||||
|
||||
:param unit:
|
||||
"""
|
||||
|
||||
async def on_start(self):
|
||||
"""
|
||||
Override this in your bot class. This function is called after "on_start".
|
||||
At this point, game_data, game_info and the first iteration of game_state (self.state) are available.
|
||||
"""
|
||||
|
||||
async def on_step(self, iteration: int):
|
||||
"""
|
||||
You need to implement this function!
|
||||
Override this in your bot class.
|
||||
This function is called on every game step (looped in realtime mode).
|
||||
|
||||
:param iteration:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
async def on_end(self, game_result: Result):
|
||||
"""Override this in your bot class. This function is called at the end of a game.
|
||||
|
||||
:param game_result:"""
|
||||
Reference in New Issue
Block a user