mirror of
				https://github.com/MarioSpore/Grinch-AP.git
				synced 2025-10-21 20:21:32 -06:00 
			
		
		
		
	
		
			
	
	
		
			156 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			156 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
|   | """
 | ||
|  | 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:"""
 |