diff --git a/CAPI/python/PyAPI/API.py b/CAPI/python/PyAPI/API.py index ece00692..12abadb2 100644 --- a/CAPI/python/PyAPI/API.py +++ b/CAPI/python/PyAPI/API.py @@ -9,113 +9,212 @@ def __init__(self,logic:ILogic)->None: self.__logic=logic self.__pool=ThreadPoolExecutor(20) - def Move(self,timeInMilliseconds:int,angle:float)->Future[bool]: - return self.__pool.submit(self.__logic.move, timeInMilliseconds, angle) - - def MoveRight(self,timeInMilliseconds:int)->Future[bool]: - return self.Move( timeInMilliseconds,pi*0.5) - - def MoveLeft(self,timeInMilliseconds:int)->Future[bool]: - return self.Move( timeInMilliseconds,pi*1.5) - - def MoveUp(self,timeInMilliseconds:int)->Future[bool]: - return self.Move( timeInMilliseconds,pi) - - def MoveDown(self,timeInMilliseconds:int)->Future[bool]: - return self.Move( timeInMilliseconds,0) - - def Attack(self,angle:float)->Future[bool]: - return self.__pool.submit(self.__logic.Attack, angle) - - def Recover(self)->Future[bool]: - return self.__pool.submit(self.__logic.Recover) - - def Produce(self)->Future[bool]: - return self.__pool.submit(self.__logic.Produce) - - def Rebuild(self,constructionType:THUAI7.ConstructionType)->Future[bool]: - return self.__pool.submit(self.__logic.Rebuild, constructionType) - - def Construct(self,constructionType:THUAI7.ConstructionType)->Future[bool]: - return self.__pool.submit(self.__logic.Construct, constructionType) - - def GetFrameCount(self)->int: - return self.__logic.GetFrameCount() - - def Wait(self)->bool: - if self.__logic.GetCounter()==-1: - return False - else: - return self.__logic.WaitThread() - - def EndAllAction(self)->Future[bool]: - return self.__pool.submit(self.__logic.EndAllAction) - - def SendMessage(self,toID:int,message:Union[str,bytes])->Future[bool]: - return self.__pool.submit(self.__logic.SendMessage, toID, message) - - def HaveMessage(self)->bool: - return self.__logic.HaveMessage() - - def GetMessage(self)->Tuple[int,Union[str,bytes]]: - return self.__logic.GetMessage() - - def GetShips(self)->List[THUAI7.Ship]: - return self.__logic.GetShips() - - def GetEnemyShips(self)->List[THUAI7.Ship]: - return self.__logic.GetEnemyShips() - - def GetBullets(self)->List[THUAI7.Bullet]: - return self.__logic.GetBullets() - - def GetFullMap(self)->List[List[THUAI7.PlaceType]]: - return self.__logic.GetFullMap() - - def GetPlaceType(self,cellX:int,cellY:int)->THUAI7.PlaceType: - return self.__logic.GetPlaceType(cellX, cellY) - - def GetConstructionHp(self,cellX:int,cellY:int)->int: - return self.__logic.GetConstructionHp(cellX, cellY) - - def GetWormHp(self,cellX:int,cellY:int)->int: - return self.__logic.GetWormHp(cellX, cellY) - - def GetResouceState(self,cellX:int,cellY:int)->int: - return self.__logic.GetResouceState(cellX, cellY) - - def GetHomeHp(self)->int: - return self.__logic.GetHomeHp() - - def GetGameInfo(self)->THUAI7.GameInfo: - return self.__logic.GetGameInfo() - - def GetPlayerGUIDs(self)->List[int]: - return self.__logic.GetPlayerGUIDs() - - def GetSelfInfo(self)->THUAI7.Ship: - return cast(THUAI7.Ships,self.__logic.GetSelfInfo()) - - def GetMoney(self)->int: - return self.__logic.GetMoney() - - def GetScore(self)->int: - return self.__logic.GetScore() - - def HaveView(self,gridX:int,gridY:int)->bool: - return self.__logic.HaveView(gridX, gridY,self.GetSelfInfo().x,self.GetSelfInfo().y,self.GetSelfInfo().viewRange) - - def Print(self,cont:str)->None: - pass + def Move(self,timeInMilliseconds:int,angle:float)->Future[bool]: + return self.__pool.submit(self.__logic.move, timeInMilliseconds, angle) + + def MoveRight(self,timeInMilliseconds:int)->Future[bool]: + return self.Move( timeInMilliseconds,pi*0.5) + + def MoveLeft(self,timeInMilliseconds:int)->Future[bool]: + return self.Move( timeInMilliseconds,pi*1.5) + + def MoveUp(self,timeInMilliseconds:int)->Future[bool]: + return self.Move( timeInMilliseconds,pi) + + def MoveDown(self,timeInMilliseconds:int)->Future[bool]: + return self.Move( timeInMilliseconds,0) + + def Attack(self,angle:float)->Future[bool]: + return self.__pool.submit(self.__logic.Attack, angle) + + def Recover(self)->Future[bool]: + return self.__pool.submit(self.__logic.Recover) + + def Produce(self)->Future[bool]: + return self.__pool.submit(self.__logic.Produce) + + def Rebuild(self,constructionType:THUAI7.ConstructionType)->Future[bool]: + return self.__pool.submit(self.__logic.Rebuild, constructionType) + + def Construct(self,constructionType:THUAI7.ConstructionType)->Future[bool]: + return self.__pool.submit(self.__logic.Construct, constructionType) + + def GetFrameCount(self)->int: + return self.__logic.GetFrameCount() + + def Wait(self)->bool: + if self.__logic.GetCounter()==-1: + return False + else: + return self.__logic.WaitThread() + + def EndAllAction(self)->Future[bool]: + return self.__pool.submit(self.__logic.EndAllAction) + + def SendMessage(self,toID:int,message:Union[str,bytes])->Future[bool]: + return self.__pool.submit(self.__logic.SendMessage, toID, message) + + def HaveMessage(self)->bool: + return self.__logic.HaveMessage() + + def GetMessage(self)->Tuple[int,Union[str,bytes]]: + return self.__logic.GetMessage() + + def GetShips(self)->List[THUAI7.Ship]: + return self.__logic.GetShips() + + def GetEnemyShips(self)->List[THUAI7.Ship]: + return self.__logic.GetEnemyShips() + + def GetBullets(self)->List[THUAI7.Bullet]: + return self.__logic.GetBullets() + + def GetFullMap(self)->List[List[THUAI7.PlaceType]]: + return self.__logic.GetFullMap() + + def GetPlaceType(self,cellX:int,cellY:int)->THUAI7.PlaceType: + return self.__logic.GetPlaceType(cellX, cellY) + + def GetConstructionHp(self,cellX:int,cellY:int)->int: + return self.__logic.GetConstructionHp(cellX, cellY) + + def GetWormHp(self,cellX:int,cellY:int)->int: + return self.__logic.GetWormHp(cellX, cellY) + + def GetResouceState(self,cellX:int,cellY:int)->int: + return self.__logic.GetResouceState(cellX, cellY) + + def GetHomeHp(self)->int: + return self.__logic.GetHomeHp() + + def GetGameInfo(self)->THUAI7.GameInfo: + return self.__logic.GetGameInfo() + + def GetPlayerGUIDs(self)->List[int]: + return self.__logic.GetPlayerGUIDs() + + def GetSelfInfo(self)->THUAI7.Ship: + return cast(THUAI7.Ships,self.__logic.GetSelfInfo()) + + def GetMoney(self)->int: + return self.__logic.GetMoney() + + def GetScore(self)->int: + return self.__logic.GetScore() + + def HaveView(self,gridX:int,gridY:int)->bool: + return self.__logic.HaveView(gridX, gridY,self.GetSelfInfo().x,self.GetSelfInfo().y,self.GetSelfInfo().viewRange) + + def Print(self,cont:str)->None: + pass - def PrintShip(self)->None: - pass + def PrintShip(self)->None: + pass - def PrintSelfInfo(self)->None: - pass + def PrintSelfInfo(self)->None: + pass + + def StartTimer(self)->None: + pass + + def EndTimer(self)->None: + pass + + def Play(self,ai:IAI)->None: + ai.ShipPlay(self) class TeamAPI(ITeamAPI,IGameTimer): def __init__(self,logic:ILogic)->None: self.__logic=logic - self.__pool=ThreadPoolExecutor(20) \ No newline at end of file + self.__pool=ThreadPoolExecutor(20) + + def StartTimer(self)->None: + pass + + def EndTimer(self)->None: + pass + + def Play(self,ai:IAI)->None: + ai.TeamPlay(self) + + def SendMessage(self,toID:int,message:Union[str,bytes])->Future[bool]: + return self.__pool.submit(self.__logic.SendMessage, toID, message) + + def HaveMessage(self)->bool: + return self.__logic.HaveMessage() + + def GetMessage(self)->Tuple[int,Union[str,bytes]]: + return self.__logic.GetMessage() + + def GetFrameCount(self)->int: + return self.__logic.GetFrameCount() + + def Wait(self)->bool: + if self.__logic.GetCounter()==-1: + return False + else: + return self.__logic.WaitThread() + + def EndAllAction(self)->Future[bool]: + return self.__pool.submit(self.__logic.EndAllAction) + + def GetBullets(self) -> List[THUAI7.Bullet]: + return self.__logic.GetBullets() + + def GetShips(self) -> List[THUAI7.Ship]: + return self.__logic.GetShips() + + def GetEnemyShips(self) -> List[THUAI7.Ship]: + return self.__logic.GetEnemyShips() + + def GetFullMap(self) -> List[List[THUAI7.PlaceType]]: + return self.__logic.GetFullMap() + + def GetPlaceType(self,cellX:int,cellY:int) -> THUAI7.PlaceType: + return self.__logic.GetPlaceType(cellX, cellY) + + def GetConstructionHp(self,cellX:int,cellY:int) -> int: + return self.__logic.GetConstructionHp(cellX, cellY) + + def GetWormHp(self,cellX:int,cellY:int) -> int: + return self.__logic.GetWormHp(cellX, cellY) + + def GetResouceState(self,cellX:int,cellY:int) -> int: + return self.__logic.GetResouceState(cellX, cellY) + + def GetHomeHp(self) -> int: + return self.__logic.GetHomeHp() + + def GetGameInfo(self) -> THUAI7.GameInfo: + return self.__logic.GetGameInfo() + + def GetPlayerGUIDs(self) -> List[int]: + return self.__logic.GetPlayerGUIDs() + + def GetSelfInfo(self) -> THUAI7.Home: + return cast(THUAI7.Home,self.__logic.GetSelfInfo()) + + def GetScore(self) -> int: + return self.__logic.GetScore() + + def GetMoney(self) -> int: + return self.__logic.GetMoney() + + def InstallModule(self,ID:int,type:THUAI7.ModuleType)->Future[bool]: + return self.__pool.submit(self.__logic.InstallModule,ID,type) + + def Recycle(self,ID:int)->Future[bool]: + return self.__pool.submit(self.__logic.Recycle,ID) + + def BuildShip(self, shipType: THUAI7.ShipType, cellX: int, cellY: int) -> Future[bool]: + return self.__pool.submit(self.__logic.BuildShip,shipType, cellX, cellY) + + def Print(self, string: str) -> None: + pass + + def PrintTeam(self) -> None: + pass + + def PrintSelfInfo(self) -> None: + pass \ No newline at end of file diff --git a/CAPI/python/PyAPI/Communication.py b/CAPI/python/PyAPI/Communication.py index e69de29b..948f63db 100644 --- a/CAPI/python/PyAPI/Communication.py +++ b/CAPI/python/PyAPI/Communication.py @@ -0,0 +1,91 @@ +import PyAPI.structures as THUAI7 +from PyAPI.AI import Setting +from PyAPI.utils import THUAI72Proto +from PyAPI.Interface import IErrorHandler +import proto.Services_pb2_grpc as Services +import proto.Message2Clients_pb2 as Message2Clients +import threading +import grpc + +from typing import Union + +class BoolErrorHandler(IErrorHandler): + @staticmethod + def result(): + return False + +class Communication: + def __init__(self, sIP: str, sPort: str): + aim = sIP + ":" + sPort + channel = grpc.insecure_channel(aim) + self.__THUAI7Stub = Services.AvailableServiceStub(channel) + self.__haveNewMessage = False + self.__cvMessage = threading.Condition() + self.__message2Client: Message2Clients.MessageToClient + self.__mtxLimit = threading.Lock() + self.__counter = 0 + self.__counterMove = 0 + self.__limit = 50 + self.__moveLimit = 10 + + def Move(self, time: int, angle: float, playerID: int) -> bool: + try: + with self.__mtxLimit: + if ( + self.__counter >= self.__limit + or self.__counterMove >= self.__moveLimit + ): + return False + self.__counter += 1 + self.__counterMove += 1 + moveResult = self.__THUAI7Stub.Move( + THUAI72Proto.THUAI72ProtobufMoveMsg(time, angle, playerID) + ) + except grpc.RpcError as e: + return False + else: + return moveResult.act_success + + def SendMessage(self,toID:int,message:Union[str,bytes],playerID:int,teamID:int)->bool: + try: + with self.__mtxLimit: + if self.__counter >= self.__limit: + return False + self.__counter += 1 + sendResult = self.__THUAI7Stub.SendMessage( + THUAI72Proto.THUAI72ProtobufSendMsg( playerID, toID,teamID,message,True if type(message) == bytes else False) + ) + except grpc.RpcError as e: + return False + else: + return sendResult.act_success + + def Attack(self, angle: float, playerID: int,teamID:int) -> bool: + try: + with self.__mtxLimit: + if self.__counter >= self.__limit: + return False + self.__counter += 1 + attackResult = self.__THUAI7Stub.Attack( + THUAI72Proto.THUAI72ProtobufAttackMsg(playerID,teamID,angle ) + ) + except grpc.RpcError as e: + return False + else: + return attackResult.act_success + + def Recover(self, playerID: int,teamID:int,recover:int) -> bool: + try: + with self.__mtxLimit: + if self.__counter >= self.__limit: + return False + self.__counter += 1 + recoverResult = self.__THUAI7Stub.Recover( + THUAI72Proto.THUAI72ProtobufRecoverMsg(playerID,recover,teamID) + ) + except grpc.RpcError as e: + return False + else: + return recoverResult.act_success + + \ No newline at end of file diff --git a/CAPI/python/PyAPI/utils.py b/CAPI/python/PyAPI/utils.py index 8c3027da..1bfdc22a 100644 --- a/CAPI/python/PyAPI/utils.py +++ b/CAPI/python/PyAPI/utils.py @@ -441,7 +441,7 @@ def THUAI72ProtobufConstructMsg( ) @staticmethod - def THUI72ProtobufAttackMsg( + def THUAI72ProtobufAttackMsg( playerID: int, teamID: int, angle: float ) -> Message2Server.AttackMsg: return Message2Server.AttackMsg(player_id=playerID, team_id=teamID, angle=angle) @@ -494,3 +494,7 @@ def THUAI72ProtobufPlayerMsg( x=x, y=y, ) + + @staticmethod + def THUAI72ProtobufRecoverMsg(playerID:int,recover:int,teamID:int)->Message2Server.RecoverMsg: + return Message2Server.RecoverMsg(player_id=playerID,team_id=teamID,recover=recover) diff --git a/CAPI/python/generate_proto.sh b/CAPI/python/generate_proto.sh new file mode 100644 index 00000000..25e4cb7e --- /dev/null +++ b/CAPI/python/generate_proto.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +python3 -m pip install -r requirements.txt + +mkdir -p proto + +python3 -m grpc_tools.protoc -I../../dependency/proto/ --python_out=./proto --pyi_out=./proto MessageType.proto +python3 -m grpc_tools.protoc -I../../dependency/proto/ --python_out=./proto --pyi_out=./proto Message2Clients.proto +python3 -m grpc_tools.protoc -I../../dependency/proto/ --python_out=./proto --pyi_out=./proto Message2Server.proto +python3 -m grpc_tools.protoc -I../../dependency/proto/ --python_out=./proto --pyi_out=./proto --grpc_python_out=./proto Services.proto diff --git a/CAPI/python/requirements.txt b/CAPI/python/requirements.txt new file mode 100644 index 00000000..61138d46 --- /dev/null +++ b/CAPI/python/requirements.txt @@ -0,0 +1,3 @@ +grpcio==1.54.2 +grpcio-tools==1.54.2 +numpy