| @@ -13,7 +13,7 @@ | |||
| namespace AssistFunction | |||
| { | |||
| constexpr int numOfGridPerCell = 100; | |||
| constexpr int numOfGridPerCell = 1000; | |||
| [[nodiscard]] constexpr inline int GridToCell(int grid) noexcept | |||
| { | |||
| @@ -17,31 +17,7 @@ extern const THUAI6::StudentType studentType = THUAI6::StudentType::Athlete; | |||
| void AI::play(IStudentAPI& api) | |||
| { | |||
| int placei = 0, placej = 0; | |||
| auto self = api.GetSelfInfo(); | |||
| auto map = api.GetFullMap(); | |||
| for (int i = 0; i < map.size(); i++) | |||
| for (int j = 0; j < map[i].size(); j++) | |||
| if (map[i][j] == THUAI6::PlaceType::ClassRoom) | |||
| { | |||
| placei = i; | |||
| placej = j; | |||
| break; | |||
| } | |||
| if (placei < api.GridToCell(self->x)) | |||
| api.MoveLeft(100); | |||
| else if (placei > api.GridToCell(self->x)) | |||
| api.MoveRight(100); | |||
| else if (placej < api.GridToCell(self->y)) | |||
| api.MoveUp(100); | |||
| else if (placej > api.GridToCell(self->y)) | |||
| api.MoveDown(100); | |||
| else | |||
| api.Move(100, 1); | |||
| api.PrintSelfInfo(); | |||
| api.PrintTricker(); | |||
| api.PrintStudent(); | |||
| api.StartOpenChest(); | |||
| } | |||
| void AI::play(ITrickerAPI& api) | |||
| @@ -18,6 +18,10 @@ Logic::Logic(THUAI6::PlayerType type, int64_t ID, THUAI6::TrickerType tricker, T | |||
| { | |||
| currentState = &state[0]; | |||
| bufferState = &state[1]; | |||
| currentState->gameInfo = std::make_shared<THUAI6::GameInfo>(); | |||
| currentState->mapInfo = std::make_shared<THUAI6::GameMap>(); | |||
| bufferState->gameInfo = std::make_shared<THUAI6::GameInfo>(); | |||
| bufferState->mapInfo = std::make_shared<THUAI6::GameMap>(); | |||
| } | |||
| std::vector<std::shared_ptr<const THUAI6::Tricker>> Logic::GetTrickers() const | |||
| @@ -318,6 +322,8 @@ void Logic::ProcessMessage() | |||
| std::vector<THUAI6::PlaceType> row; | |||
| for (int j = 0; j < mapResult.row(i).col_size(); j++) | |||
| { | |||
| if (Proto2THUAI6::placeTypeDict.count(mapResult.row(i).col(j)) == 0) | |||
| logger->error("Unknown place type!"); | |||
| row.push_back(Proto2THUAI6::placeTypeDict[mapResult.row(i).col(j)]); | |||
| } | |||
| map.push_back(std::move(row)); | |||
| @@ -1,6 +1,6 @@ | |||
| import PyAPI.structures as THUAI6 | |||
| from PyAPI.Interface import IStudentAPI, ITrickerAPI, IAI | |||
| from typing import Union, Final | |||
| from typing import Union, Final, cast | |||
| class Setting: | |||
| @@ -17,11 +17,11 @@ class Setting: | |||
| # 选手需要将两个都定义,本份代码中不选择的阵营任意定义即可 | |||
| @staticmethod | |||
| def studentType() -> THUAI6.StudentType: | |||
| return THUAI6.StudentType.StudentType1 | |||
| return THUAI6.StudentType.Athlete | |||
| @staticmethod | |||
| def trickerType() -> THUAI6.TrickerType: | |||
| return THUAI6.TrickerType.TrickerType1 | |||
| return THUAI6.TrickerType.Assassin | |||
| # 辅助函数 | |||
| @@ -40,6 +40,23 @@ class AssistFunction: | |||
| class AI(IAI): | |||
| def play(self, api: Union[IStudentAPI, ITrickerAPI]) -> None: | |||
| # 选手在这里实现自己的逻辑,要求和上面选择的阵营保持一致,否则会发生错误 | |||
| # 选手在这里实现自己的逻辑,要求和上面选择的阵营保持一致 | |||
| def StudentPlay(self, api: IStudentAPI) -> None: | |||
| # studentSelf = api.GetSelfInfo() | |||
| # api.PrintSelfInfo() | |||
| # if AssistFunction.GridToCell(studentSelf.y) < 8: | |||
| # api.MoveRight(50) | |||
| # return | |||
| # if studentSelf.x < 3600: | |||
| # api.MoveDown(50) | |||
| # return | |||
| # if studentSelf.playerState == THUAI6.PlayerState.Idle: | |||
| # if api.GetClassroomProgress(5, 8) < 114514: | |||
| # api.StartLearning() | |||
| # return | |||
| api.PrintTricker() | |||
| return | |||
| def TrickerPlay(self, api: ITrickerAPI) -> None: | |||
| return | |||
| @@ -2,7 +2,7 @@ import PyAPI.structures as THUAI6 | |||
| from PyAPI.Interface import ILogic, IStudentAPI, ITrickerAPI, IGameTimer, IAI | |||
| from math import pi | |||
| from concurrent.futures import ThreadPoolExecutor, Future | |||
| from typing import List, Union | |||
| from typing import List, cast | |||
| class StudentAPI(IStudentAPI, IGameTimer): | |||
| @@ -25,21 +25,43 @@ class StudentAPI(IStudentAPI, IGameTimer): | |||
| return self.Move(timeInMilliseconds, pi * 1.5) | |||
| def MoveUp(self, timeInMilliseconds: int) -> Future[bool]: | |||
| return self.Move(timeInMilliseconds, 0) | |||
| return self.Move(timeInMilliseconds, pi) | |||
| def MoveDown(self, timeInMilliseconds: int) -> Future[bool]: | |||
| return self.Move(timeInMilliseconds, pi) | |||
| return self.Move(timeInMilliseconds, 0) | |||
| def Attack(self, angle: float) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.Attack, angle) | |||
| # 道具和技能相关 | |||
| def PickProp(self, propType: THUAI6.PropType) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.PickProp, propType) | |||
| def UseProp(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.UseProp) | |||
| def UseProp(self, propType: THUAI6.PropType) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.UseProp, propType) | |||
| def UseSkill(self, skillID: int) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.UseSkill, skillID) | |||
| # 与地图交互相关 | |||
| def OpenDoor(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.OpenDoor) | |||
| def CloseDoor(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.CloseDoor) | |||
| def SkipWindow(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.SkipWindow) | |||
| def StartOpenGate(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.StartOpenGate) | |||
| def StartOpenChest(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.StartOpenChest) | |||
| def UseSkill(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.UseSkill) | |||
| def EndAllAction(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.EndAllAction) | |||
| # 消息相关,接收消息时无消息则返回(-1, '') | |||
| @@ -77,15 +99,33 @@ class StudentAPI(IStudentAPI, IGameTimer): | |||
| def GetProps(self) -> List[THUAI6.Prop]: | |||
| return self.__logic.GetProps() | |||
| def GetSelfInfo(self) -> Union[THUAI6.Student, THUAI6.Tricker]: | |||
| return self.__logic.GetSelfInfo() | |||
| def GetFullMap(self) -> List[List[THUAI6.PlaceType]]: | |||
| return self.__logic.GetFullMap() | |||
| def GetPlaceType(self, cellX: int, cellY: int) -> THUAI6.PlaceType: | |||
| return self.__logic.GetPlaceType(cellX, cellY) | |||
| def IsDoorOpen(self, cellX: int, cellY: int) -> bool: | |||
| return self.__logic.IsDoorOpen(cellX, cellY) | |||
| def GetChestProgress(self, cellX: int, cellY: int) -> int: | |||
| return self.__logic.GetChestProgress(cellX, cellY) | |||
| def GetGateProgress(self, cellX: int, cellY: int) -> int: | |||
| return self.__logic.GetGateProgress(cellX, cellY) | |||
| def GetClassroomProgress(self, cellX: int, cellY: int) -> int: | |||
| return self.__logic.GetClassroomProgress(cellX, cellY) | |||
| def GetDoorProgress(self, cellX: int, cellY: int) -> int: | |||
| return self.__logic.GetDoorProgress(cellX, cellY) | |||
| def GetHiddenGateState(self, cellX: int, cellY: int) -> THUAI6.HiddenGateState: | |||
| return self.__logic.GetHiddenGateState(cellX, cellY) | |||
| def GetGameInfo(self) -> THUAI6.GameInfo: | |||
| return self.__logic.GetGameInfo() | |||
| # 用于DEBUG的输出函数,仅在DEBUG模式下有效 | |||
| def PrintStudent(self) -> None: | |||
| @@ -108,14 +148,14 @@ class StudentAPI(IStudentAPI, IGameTimer): | |||
| def StartLearning(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.StartLearning) | |||
| def EndLearning(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.EndLearning) | |||
| def StartTreatMate(self, mateID: int) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.StartTreatMate, mateID) | |||
| def StartHelpMate(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.StartHelpMate) | |||
| def StartRescueMate(self, mateID: int) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.StartRescueMate, mateID) | |||
| def EndHelpMate(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.EndHelpMate) | |||
| def GetSelfInfo(self) -> THUAI6.Student: | |||
| return cast(THUAI6.Student, self.__logic.GetSelfInfo()) | |||
| # Timer用 | |||
| @@ -126,7 +166,7 @@ class StudentAPI(IStudentAPI, IGameTimer): | |||
| pass | |||
| def Play(self, ai: IAI) -> None: | |||
| pass | |||
| ai.StudentPlay(self) | |||
| class TrickerAPI(ITrickerAPI, IGameTimer): | |||
| @@ -149,21 +189,43 @@ class TrickerAPI(ITrickerAPI, IGameTimer): | |||
| return self.Move(timeInMilliseconds, pi * 1.5) | |||
| def MoveUp(self, timeInMilliseconds: int) -> Future[bool]: | |||
| return self.Move(timeInMilliseconds, 0) | |||
| return self.Move(timeInMilliseconds, pi) | |||
| def MoveDown(self, timeInMilliseconds: int) -> Future[bool]: | |||
| return self.Move(timeInMilliseconds, pi) | |||
| return self.Move(timeInMilliseconds, 0) | |||
| def Attack(self, angle: float) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.Attack, angle) | |||
| # 道具和技能相关 | |||
| def PickProp(self, propType: THUAI6.PropType) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.PickProp, propType) | |||
| def UseProp(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.UseProp) | |||
| def UseProp(self, propType: THUAI6.PropType) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.UseProp, propType) | |||
| def UseSkill(self, skillID: int) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.UseSkill, skillID) | |||
| # 与地图交互相关 | |||
| def OpenDoor(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.OpenDoor) | |||
| def CloseDoor(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.CloseDoor) | |||
| def UseSkill(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.UseSkill) | |||
| def SkipWindow(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.SkipWindow) | |||
| def StartOpenGate(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.StartOpenGate) | |||
| def StartOpenChest(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.StartOpenChest) | |||
| def EndAllAction(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.EndAllAction) | |||
| # 消息相关,接收消息时无消息则返回(-1, '') | |||
| @@ -201,15 +263,33 @@ class TrickerAPI(ITrickerAPI, IGameTimer): | |||
| def GetProps(self) -> List[THUAI6.Prop]: | |||
| return self.__logic.GetProps() | |||
| def GetSelfInfo(self) -> Union[THUAI6.Student, THUAI6.Tricker]: | |||
| return self.__logic.GetSelfInfo() | |||
| def GetFullMap(self) -> List[List[THUAI6.PlaceType]]: | |||
| return self.__logic.GetFullMap() | |||
| def GetPlaceType(self, cellX: int, cellY: int) -> THUAI6.PlaceType: | |||
| return self.__logic.GetPlaceType(cellX, cellY) | |||
| def IsDoorOpen(self, cellX: int, cellY: int) -> bool: | |||
| return self.__logic.IsDoorOpen(cellX, cellY) | |||
| def GetChestProgress(self, cellX: int, cellY: int) -> int: | |||
| return self.__logic.GetChestProgress(cellX, cellY) | |||
| def GetGateProgress(self, cellX: int, cellY: int) -> int: | |||
| return self.__logic.GetGateProgress(cellX, cellY) | |||
| def GetClassroomProgress(self, cellX: int, cellY: int) -> int: | |||
| return self.__logic.GetClassroomProgress(cellX, cellY) | |||
| def GetDoorProgress(self, cellX: int, cellY: int) -> int: | |||
| return self.__logic.GetDoorProgress(cellX, cellY) | |||
| def GetHiddenGateState(self, cellX: int, cellY: int) -> THUAI6.HiddenGateState: | |||
| return self.__logic.GetHiddenGateState(cellX, cellY) | |||
| def GetGameInfo(self) -> THUAI6.GameInfo: | |||
| return self.__logic.GetGameInfo() | |||
| # 用于DEBUG的输出函数,仅在DEBUG模式下有效 | |||
| def PrintStudent(self) -> None: | |||
| @@ -226,17 +306,8 @@ class TrickerAPI(ITrickerAPI, IGameTimer): | |||
| # 屠夫阵营的特殊函数 | |||
| def Trick(self, angle: float) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.Trick, angle) | |||
| def StartExam(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.StartExam) | |||
| def EndExam(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.EndExam) | |||
| def MakeFail(self) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.MakeFail) | |||
| def GetSelfInfo(self) -> THUAI6.Tricker: | |||
| return cast(THUAI6.Tricker, self.__logic.GetSelfInfo()) | |||
| # Timer用 | |||
| @@ -247,4 +318,4 @@ class TrickerAPI(ITrickerAPI, IGameTimer): | |||
| pass | |||
| def Play(self, ai: IAI) -> None: | |||
| pass | |||
| ai.TrickerPlay(self) | |||
| @@ -6,7 +6,6 @@ import proto.Services_pb2_grpc as Services | |||
| import proto.Message2Clients_pb2 as Message2Clients | |||
| import threading | |||
| import grpc | |||
| from queue import Queue | |||
| # 使用gRPC的异步来减少通信对于选手而言损失的时间,而gRPC的return值有result()方法,故若连接错误时也应当返回一个具有result()方法的对象,使用此处的ErrorHandler类来实现 | |||
| @@ -21,7 +20,6 @@ class Communication: | |||
| __THUAI6Stub: Services.AvailableServiceStub | |||
| __haveNewMessage: bool | |||
| __message2Client: Message2Clients.MessageToClient | |||
| __messageQueue: Queue # Python的Queue是线程安全的,故无须自己实现Queue | |||
| __mtxMessage: threading.Lock | |||
| __cvMessage: threading.Condition | |||
| @@ -30,7 +28,6 @@ class Communication: | |||
| channel = grpc.insecure_channel(aim) | |||
| self.__THUAI6Stub = Services.AvailableServiceStub(channel) | |||
| self.__haveNewMessage = False | |||
| self.__messageQueue = Queue() | |||
| self.__cvMessage = threading.Condition() | |||
| def Move(self, time: int, angle: float, playerID: int) -> bool: | |||
| @@ -45,25 +42,25 @@ class Communication: | |||
| def PickProp(self, propType: THUAI6.PropType, playerID: int) -> bool: | |||
| try: | |||
| pickResult = self.__THUAI6Stub.PickProp( | |||
| THUAI62Proto.THUAI62ProtobufPick(propType, playerID)) | |||
| THUAI62Proto.THUAI62ProtobufProp(propType, playerID)) | |||
| except grpc.RpcError as e: | |||
| return False | |||
| else: | |||
| return pickResult.act_success | |||
| def UseProp(self, playerID: int): | |||
| def UseProp(self, propType: THUAI6.PropType, playerID: int): | |||
| try: | |||
| useResult = self.__THUAI6Stub.UseProp( | |||
| THUAI62Proto.THUAI62ProtobufID(playerID)) | |||
| THUAI62Proto.THUAI62ProtobufProp(propType, playerID)) | |||
| except grpc.RpcError as e: | |||
| return False | |||
| else: | |||
| return useResult.act_success | |||
| def UseSkill(self, playerID: int) -> bool: | |||
| def UseSkill(self, skillID: int, playerID: int) -> bool: | |||
| try: | |||
| useResult = self.__THUAI6Stub.UseSkill( | |||
| THUAI62Proto.THUAI62ProtobufID(playerID)) | |||
| THUAI62Proto.THUAI62ProtobufSkill(skillID, playerID)) | |||
| except grpc.RpcError as e: | |||
| return False | |||
| else: | |||
| @@ -78,29 +75,6 @@ class Communication: | |||
| else: | |||
| return sendResult.act_success | |||
| def HaveMessage(self) -> bool: | |||
| return not self.__messageQueue.empty() | |||
| def GetMessage(self) -> tuple[int, str]: | |||
| try: | |||
| message = self.__messageQueue.get_nowait() | |||
| except Exception as e: | |||
| return -1, '' | |||
| else: | |||
| return message | |||
| def ReadMessage(self, playerID: int) -> None: | |||
| def tRead(): | |||
| try: | |||
| for msg in self.__THUAI6Stub.GetMessage( | |||
| THUAI62Proto.THUAI62ProtobufID(playerID)): | |||
| self.__messageQueue.put( | |||
| (msg.from_player_id, msg.message_received)) | |||
| except grpc.RpcError as e: | |||
| return | |||
| threading.Thread(target=tRead).start() | |||
| def Graduate(self, playerID: int) -> bool: | |||
| try: | |||
| escapeResult = self.__THUAI6Stub.Graduate( | |||
| @@ -119,19 +93,19 @@ class Communication: | |||
| else: | |||
| return learnResult.act_success | |||
| def StartTreatMate(self, playerID: int) -> bool: | |||
| def StartTreatMate(self, playerID: int, mateID: int) -> bool: | |||
| try: | |||
| helpResult = self.__THUAI6Stub.StartTreatMate( | |||
| THUAI62Proto.THUAI62ProtobufID(playerID)) | |||
| THUAI62Proto.THUAI62ProtobufTreatAndRescue(playerID, mateID)) | |||
| except grpc.RpcError as e: | |||
| return False | |||
| else: | |||
| return helpResult.act_success | |||
| def StartRescueMate(self, playerID: int) -> bool: | |||
| def StartRescueMate(self, playerID: int, mateID: int) -> bool: | |||
| try: | |||
| helpResult = self.__THUAI6Stub.StartRescueMate( | |||
| THUAI62Proto.THUAI62ProtobufID(playerID)) | |||
| THUAI62Proto.THUAI62ProtobufTreatAndRescue(playerID, mateID)) | |||
| except grpc.RpcError as e: | |||
| return False | |||
| else: | |||
| @@ -140,7 +114,7 @@ class Communication: | |||
| def Attack(self, angle: float, playerID: int) -> bool: | |||
| try: | |||
| attackResult = self.__THUAI6Stub.Attack( | |||
| THUAI62Proto.THUAI62ProtobufTrick(angle, playerID)) | |||
| THUAI62Proto.THUAI62ProtobufAttack(angle, playerID)) | |||
| except grpc.RpcError as e: | |||
| return False | |||
| else: | |||
| @@ -1,6 +1,6 @@ | |||
| from math import pi | |||
| from concurrent.futures import ThreadPoolExecutor, Future | |||
| from typing import List, Union | |||
| from typing import List, cast | |||
| import logging | |||
| import os | |||
| import datetime | |||
| @@ -25,7 +25,7 @@ class StudentDebugAPI(IStudentAPI, IGameTimer): | |||
| os.path.realpath(__file__))) + "/logs") | |||
| fileHandler = logging.FileHandler(os.path.dirname( | |||
| os.path.dirname(os.path.realpath(__file__))) + "/logs/api-" + str(playerID) + "-log.txt") | |||
| os.path.dirname(os.path.realpath(__file__))) + "/logs/api-" + str(playerID) + "-log.txt", mode="w+", encoding="utf-8") | |||
| screenHandler = logging.StreamHandler() | |||
| if file: | |||
| fileHandler.setLevel(logging.DEBUG) | |||
| @@ -63,10 +63,23 @@ class StudentDebugAPI(IStudentAPI, IGameTimer): | |||
| return self.Move(timeInMilliseconds, pi * 1.5) | |||
| def MoveUp(self, timeInMilliseconds: int) -> Future[bool]: | |||
| return self.Move(timeInMilliseconds, 0) | |||
| return self.Move(timeInMilliseconds, pi) | |||
| def MoveDown(self, timeInMilliseconds: int) -> Future[bool]: | |||
| return self.Move(timeInMilliseconds, pi) | |||
| return self.Move(timeInMilliseconds, 0) | |||
| def Attack(self, angle: float) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"Attack: angle = {angle}, called at {self.__GetTime()}ms") | |||
| def logAttack() -> bool: | |||
| result = self.__logic.Attack(angle) | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"Attack: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logAttack) | |||
| # 道具和技能相关 | |||
| @@ -83,12 +96,12 @@ class StudentDebugAPI(IStudentAPI, IGameTimer): | |||
| return self.__pool.submit(logPick) | |||
| def UseProp(self) -> Future[bool]: | |||
| def UseProp(self, propType: THUAI6.PropType) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"UseProp: called at {self.__GetTime()}ms") | |||
| f"UseProp: prop = {propType.name}, called at {self.__GetTime()}ms") | |||
| def logUse() -> bool: | |||
| result = self.__logic.UseProp() | |||
| result = self.__logic.UseProp(propType) | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"UseProp: failed at {self.__GetTime()}ms") | |||
| @@ -96,12 +109,12 @@ class StudentDebugAPI(IStudentAPI, IGameTimer): | |||
| return self.__pool.submit(logUse) | |||
| def UseSkill(self) -> Future[bool]: | |||
| def UseSkill(self, skillID: int) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"UseSkill: called at {self.__GetTime()}ms") | |||
| f"UseSkill: skillID = {skillID}, called at {self.__GetTime()}ms") | |||
| def logUse() -> bool: | |||
| result = self.__logic.UseSkill() | |||
| result = self.__logic.UseSkill(skillID) | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"UseSkill: failed at {self.__GetTime()}ms") | |||
| @@ -109,6 +122,85 @@ class StudentDebugAPI(IStudentAPI, IGameTimer): | |||
| return self.__pool.submit(logUse) | |||
| # 与地图交互相关 | |||
| def OpenDoor(self) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"OpenDoor: called at {self.__GetTime()}ms") | |||
| def logOpen() -> bool: | |||
| result = self.__logic.OpenDoor() | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"OpenDoor: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logOpen) | |||
| def CloseDoor(self) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"CloseDoor: called at {self.__GetTime()}ms") | |||
| def logClose() -> bool: | |||
| result = self.__logic.CloseDoor() | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"CloseDoor: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logClose) | |||
| def SkipWindow(self) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"SkipWindow: called at {self.__GetTime()}ms") | |||
| def logSkip() -> bool: | |||
| result = self.__logic.SkipWindow() | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"SkipWindow: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logSkip) | |||
| def StartOpenGate(self) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"StartOpenGate: called at {self.__GetTime()}ms") | |||
| def logStart() -> bool: | |||
| result = self.__logic.StartOpenGate() | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"StartOpenGate: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logStart) | |||
| def StartOpenChest(self) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"StartOpenChest: called at {self.__GetTime()}ms") | |||
| def logStart() -> bool: | |||
| result = self.__logic.StartOpenChest() | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"StartOpenChest: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logStart) | |||
| def EndAllAction(self) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"EndAllAction: called at {self.__GetTime()}ms") | |||
| def logEnd() -> bool: | |||
| result = self.__logic.EndAllAction() | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"EndAllAction: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logEnd) | |||
| # 消息相关,接收消息时无消息则返回(-1, '') | |||
| def SendMessage(self, toID: int, message: str) -> Future[bool]: | |||
| @@ -177,15 +269,33 @@ class StudentDebugAPI(IStudentAPI, IGameTimer): | |||
| def GetProps(self) -> List[THUAI6.Prop]: | |||
| return self.__logic.GetProps() | |||
| def GetSelfInfo(self) -> Union[THUAI6.Student, THUAI6.Tricker]: | |||
| return self.__logic.GetSelfInfo() | |||
| def GetFullMap(self) -> List[List[THUAI6.PlaceType]]: | |||
| return self.__logic.GetFullMap() | |||
| def GetPlaceType(self, cellX: int, cellY: int) -> THUAI6.PlaceType: | |||
| return self.__logic.GetPlaceType(cellX, cellY) | |||
| def IsDoorOpen(self, cellX: int, cellY: int) -> bool: | |||
| return self.__logic.IsDoorOpen(cellX, cellY) | |||
| def GetChestProgress(self, cellX: int, cellY: int) -> int: | |||
| return self.__logic.GetChestProgress(cellX, cellY) | |||
| def GetGateProgress(self, cellX: int, cellY: int) -> int: | |||
| return self.__logic.GetGateProgress(cellX, cellY) | |||
| def GetClassroomProgress(self, cellX: int, cellY: int) -> int: | |||
| return self.__logic.GetClassroomProgress(cellX, cellY) | |||
| def GetDoorProgress(self, cellX: int, cellY: int) -> int: | |||
| return self.__logic.GetDoorProgress(cellX, cellY) | |||
| def GetHiddenGateState(self, cellX: int, cellY: int) -> THUAI6.HiddenGateState: | |||
| return self.__logic.GetHiddenGateState(cellX, cellY) | |||
| def GetGameInfo(self) -> THUAI6.GameInfo: | |||
| return self.__logic.GetGameInfo() | |||
| # 用于DEBUG的输出函数,仅在DEBUG模式下有效 | |||
| def PrintStudent(self) -> None: | |||
| @@ -194,14 +304,15 @@ class StudentDebugAPI(IStudentAPI, IGameTimer): | |||
| self.__logger.info( | |||
| f"playerID={student.playerID}, GUID={student.guid}, x={student.x}, y={student.y}") | |||
| self.__logger.info( | |||
| f"speed={student.speed}, view range={student.viewRange}, skill time={student.timeUntilSkillAvailable}, prop={student.prop.name}, place={student.place.name}") | |||
| self.__logger.info( | |||
| f"state={student.state.name}, determination={student.determination}, fail time={student.failTime}") | |||
| self.__logger.info("buff=") | |||
| studentBuff = "" | |||
| f"speed={student.speed}, view range={student.viewRange}, skill time={student.timeUntilSkillAvailable},place={student.place.name}") | |||
| studentBuff = "buff=" | |||
| for buff in student.buff: | |||
| studentBuff += buff.name + ", " | |||
| self.__logger.info(studentBuff) | |||
| studentProp = "prop=" | |||
| for prop in student.prop: | |||
| studentProp += prop.name + ", " | |||
| self.__logger.info(studentProp) | |||
| self.__logger.info("**********************") | |||
| def PrintTricker(self) -> None: | |||
| @@ -210,9 +321,7 @@ class StudentDebugAPI(IStudentAPI, IGameTimer): | |||
| self.__logger.info( | |||
| f"playerID={tricker.playerID}, GUID={tricker.guid}, x={tricker.x}, y={tricker.y}") | |||
| self.__logger.info( | |||
| f"speed={tricker.speed}, view range={tricker.viewRange}, skill time={tricker.timeUntilSkillAvailable}, prop={tricker.prop.name}, place={tricker.place.name}") | |||
| self.__logger.info( | |||
| f"damage={tricker.damage}, movable={tricker.movable}") | |||
| f"speed={tricker.speed}, view range={tricker.viewRange}, skill time={tricker.timeUntilSkillAvailable}, place={tricker.place.name}") | |||
| self.__logger.info("buff=") | |||
| trickerBuff = "" | |||
| for buff in tricker.buff: | |||
| @@ -224,7 +333,7 @@ class StudentDebugAPI(IStudentAPI, IGameTimer): | |||
| for prop in self.__logic.GetProps(): | |||
| self.__logger.info("******Prop Info******") | |||
| self.__logger.info( | |||
| f"GUID={prop.guid}, x={prop.x}, y={prop.y}, place={prop.place.name}, is moving={prop.isMoving}") | |||
| f"GUID={prop.guid}, x={prop.x}, y={prop.y}, place={prop.place.name}, ") | |||
| self.__logger.info("*********************") | |||
| def PrintSelfInfo(self) -> None: | |||
| @@ -233,18 +342,18 @@ class StudentDebugAPI(IStudentAPI, IGameTimer): | |||
| self.__logger.info( | |||
| f"playerID={mySelf.playerID}, GUID={mySelf.guid}, x={mySelf.x}, y={mySelf.y}") | |||
| self.__logger.info( | |||
| f"speed={mySelf.speed}, view range={mySelf.viewRange}, skill time={mySelf.timeUntilSkillAvailable}, prop={mySelf.prop.name}, place={mySelf.place.name}") | |||
| f"speed={mySelf.speed}, view range={mySelf.viewRange}, skill time={mySelf.timeUntilSkillAvailable}, place={mySelf.place.name}") | |||
| if isinstance(mySelf, THUAI6.Student): | |||
| self.__logger.info( | |||
| f"state={mySelf.state.name}, determination={mySelf.determination},fail num={mySelf.failNum}, fail time={mySelf.failTime}, emo time={mySelf.emoTime}") | |||
| else: | |||
| self.__logger.info( | |||
| f"damage={mySelf.damage}, movable={mySelf.movable}") | |||
| self.__logger.info("buff=") | |||
| mySelfBuff = "" | |||
| f"state={mySelf.playerState.name}, determination={mySelf.determination},") | |||
| mySelfBuff = "buff=" | |||
| for buff in mySelf.buff: | |||
| mySelfBuff += buff.name + ", " | |||
| self.__logger.info(mySelfBuff) | |||
| studentProp = "prop=" | |||
| for prop in mySelf.prop: | |||
| studentProp += prop.name + ", " | |||
| self.__logger.info(studentProp) | |||
| self.__logger.info("*********************") | |||
| # 人类阵营的特殊函数 | |||
| @@ -275,44 +384,34 @@ class StudentDebugAPI(IStudentAPI, IGameTimer): | |||
| return self.__pool.submit(logStart) | |||
| def EndLearning(self) -> Future[bool]: | |||
| def StartTreatMate(self, mateID: int) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"EndLearning: called at {self.__GetTime()}ms") | |||
| f"StartTreatMate: called at {self.__GetTime()}ms") | |||
| def logEnd() -> bool: | |||
| result = self.__logic.EndLearning() | |||
| def logStartTreatMate() -> bool: | |||
| result = self.__logic.StartTreatMate(mateID) | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"EndLearning: failed at {self.__GetTime()}ms") | |||
| f"StartTreatMate: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logEnd) | |||
| return self.__pool.submit(logStartTreatMate) | |||
| def StartHelpMate(self) -> Future[bool]: | |||
| def StartRescueMate(self, mateID: int) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"StartHelpMate: called at {self.__GetTime()}ms") | |||
| f"StartRescueMate: called at {self.__GetTime()}ms") | |||
| def logStart() -> bool: | |||
| result = self.__logic.StartHelpMate() | |||
| def logStartRescueMate() -> bool: | |||
| result = self.__logic.StartRescueMate(mateID) | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"StartHelpMate: failed at {self.__GetTime()}ms") | |||
| f"StartRescueMate: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logStart) | |||
| return self.__pool.submit(logStartRescueMate) | |||
| def EndHelpMate(self) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"EndHelpMate: called at {self.__GetTime()}ms") | |||
| def logEnd() -> bool: | |||
| result = self.__logic.EndHelpMate() | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"EndHelpMate: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logEnd) | |||
| def GetSelfInfo(self) -> THUAI6.Student: | |||
| return cast(THUAI6.Student, self.__logic.GetSelfInfo()) | |||
| # Timer用 | |||
| @@ -328,7 +427,7 @@ class StudentDebugAPI(IStudentAPI, IGameTimer): | |||
| self.__logger.info(f"Time elapsed: {self.__GetTime()}ms") | |||
| def Play(self, ai: IAI) -> None: | |||
| ai.play(self) | |||
| ai.StudentPlay(self) | |||
| class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||
| @@ -346,7 +445,7 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||
| os.path.realpath(__file__))) + "/logs") | |||
| fileHandler = logging.FileHandler(os.path.dirname( | |||
| os.path.dirname(os.path.realpath(__file__))) + "/logs/api-" + str(playerID) + "-log.txt") | |||
| os.path.dirname(os.path.realpath(__file__))) + "/logs/api-" + str(playerID) + "-log.txt", mode="w+", encoding="utf-8") | |||
| screenHandler = logging.StreamHandler() | |||
| if file: | |||
| fileHandler.setLevel(logging.DEBUG) | |||
| @@ -384,10 +483,25 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||
| return self.Move(timeInMilliseconds, pi * 1.5) | |||
| def MoveUp(self, timeInMilliseconds: int) -> Future[bool]: | |||
| return self.Move(timeInMilliseconds, 0) | |||
| return self.Move(timeInMilliseconds, pi) | |||
| def MoveDown(self, timeInMilliseconds: int) -> Future[bool]: | |||
| return self.Move(timeInMilliseconds, pi) | |||
| return self.Move(timeInMilliseconds, 0) | |||
| # 道具和技能相关 | |||
| def Attack(self, angle: float) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"Attack: angle = {angle}, called at {self.__GetTime()}ms") | |||
| def logAttack() -> bool: | |||
| result = self.__logic.Attack(angle) | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"Attack: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logAttack) | |||
| # 道具和技能相关 | |||
| @@ -404,12 +518,12 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||
| return self.__pool.submit(logPick) | |||
| def UseProp(self) -> Future[bool]: | |||
| def UseProp(self, propType: THUAI6.PropType) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"UseProp: called at {self.__GetTime()}ms") | |||
| f"UseProp: prop = {propType.name}, called at {self.__GetTime()}ms") | |||
| def logUse() -> bool: | |||
| result = self.__logic.UseProp() | |||
| result = self.__logic.UseProp(propType) | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"UseProp: failed at {self.__GetTime()}ms") | |||
| @@ -417,12 +531,12 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||
| return self.__pool.submit(logUse) | |||
| def UseSkill(self) -> Future[bool]: | |||
| def UseSkill(self, skillID: int) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"UseSkill: called at {self.__GetTime()}ms") | |||
| f"UseSkill: skillID = {skillID}, called at {self.__GetTime()}ms") | |||
| def logUse() -> bool: | |||
| result = self.__logic.UseSkill() | |||
| result = self.__logic.UseSkill(skillID) | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"UseSkill: failed at {self.__GetTime()}ms") | |||
| @@ -430,6 +544,85 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||
| return self.__pool.submit(logUse) | |||
| # 与地图交互相关 | |||
| def OpenDoor(self) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"OpenDoor: called at {self.__GetTime()}ms") | |||
| def logOpen() -> bool: | |||
| result = self.__logic.OpenDoor() | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"OpenDoor: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logOpen) | |||
| def CloseDoor(self) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"CloseDoor: called at {self.__GetTime()}ms") | |||
| def logClose() -> bool: | |||
| result = self.__logic.CloseDoor() | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"CloseDoor: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logClose) | |||
| def SkipWindow(self) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"SkipWindow: called at {self.__GetTime()}ms") | |||
| def logSkip() -> bool: | |||
| result = self.__logic.SkipWindow() | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"SkipWindow: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logSkip) | |||
| def StartOpenGate(self) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"StartOpenGate: called at {self.__GetTime()}ms") | |||
| def logStart() -> bool: | |||
| result = self.__logic.StartOpenGate() | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"StartOpenGate: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logStart) | |||
| def StartOpenChest(self) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"StartOpenChest: called at {self.__GetTime()}ms") | |||
| def logStart() -> bool: | |||
| result = self.__logic.StartOpenChest() | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"StartOpenChest: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logStart) | |||
| def EndAllAction(self) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"EndAllAction: called at {self.__GetTime()}ms") | |||
| def logEnd() -> bool: | |||
| result = self.__logic.EndAllAction() | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"EndAllAction: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logEnd) | |||
| # 消息相关,接收消息时无消息则返回(-1, '') | |||
| def SendMessage(self, toID: int, message: str) -> Future[bool]: | |||
| @@ -498,15 +691,33 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||
| def GetProps(self) -> List[THUAI6.Prop]: | |||
| return self.__logic.GetProps() | |||
| def GetSelfInfo(self) -> Union[THUAI6.Student, THUAI6.Tricker]: | |||
| return self.__logic.GetSelfInfo() | |||
| def GetFullMap(self) -> List[List[THUAI6.PlaceType]]: | |||
| return self.__logic.GetFullMap() | |||
| def GetPlaceType(self, cellX: int, cellY: int) -> THUAI6.PlaceType: | |||
| return self.__logic.GetPlaceType(cellX, cellY) | |||
| def IsDoorOpen(self, cellX: int, cellY: int) -> bool: | |||
| return self.__logic.IsDoorOpen(cellX, cellY) | |||
| def GetChestProgress(self, cellX: int, cellY: int) -> int: | |||
| return self.__logic.GetChestProgress(cellX, cellY) | |||
| def GetGateProgress(self, cellX: int, cellY: int) -> int: | |||
| return self.__logic.GetGateProgress(cellX, cellY) | |||
| def GetClassroomProgress(self, cellX: int, cellY: int) -> int: | |||
| return self.__logic.GetClassroomProgress(cellX, cellY) | |||
| def GetDoorProgress(self, cellX: int, cellY: int) -> int: | |||
| return self.__logic.GetDoorProgress(cellX, cellY) | |||
| def GetHiddenGateState(self, cellX: int, cellY: int) -> THUAI6.HiddenGateState: | |||
| return self.__logic.GetHiddenGateState(cellX, cellY) | |||
| def GetGameInfo(self) -> THUAI6.GameInfo: | |||
| return self.__logic.GetGameInfo() | |||
| # 用于DEBUG的输出函数,仅在DEBUG模式下有效 | |||
| def PrintStudent(self) -> None: | |||
| @@ -515,9 +726,9 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||
| self.__logger.info( | |||
| f"playerID={student.playerID}, GUID={student.guid}, x={student.x}, y={student.y}") | |||
| self.__logger.info( | |||
| f"speed={student.speed}, view range={student.viewRange}, skill time={student.timeUntilSkillAvailable}, prop={student.prop.name}, place={student.place.name}") | |||
| f"speed={student.speed}, view range={student.viewRange}, skill time={student.timeUntilSkillAvailable}, place={student.place.name}") | |||
| self.__logger.info( | |||
| f"state={student.state.name}, determination={student.determination}, fail num={student.failNum}, fail time={student.failTime}, emo time={student.emoTime}") | |||
| f"state={student.playerState.name}, determination={student.determination}") | |||
| self.__logger.info("buff=") | |||
| studentBuff = "" | |||
| for buff in student.buff: | |||
| @@ -531,9 +742,7 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||
| self.__logger.info( | |||
| f"playerID={tricker.playerID}, GUID={tricker.guid}, x={tricker.x}, y={tricker.y}") | |||
| self.__logger.info( | |||
| f"speed={tricker.speed}, view range={tricker.viewRange}, skill time={tricker.timeUntilSkillAvailable}, prop={tricker.prop.name}, place={tricker.place.name}") | |||
| self.__logger.info( | |||
| f"damage={tricker.damage}, movable={tricker.movable}") | |||
| f"speed={tricker.speed}, view range={tricker.viewRange}, skill time={tricker.timeUntilSkillAvailable}, place={tricker.place.name}") | |||
| self.__logger.info("buff=") | |||
| trickerBuff = "" | |||
| for buff in tricker.buff: | |||
| @@ -545,7 +754,7 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||
| for prop in self.__logic.GetProps(): | |||
| self.__logger.info("******Prop Info******") | |||
| self.__logger.info( | |||
| f"GUID={prop.guid}, x={prop.x}, y={prop.y}, place={prop.place.name}, is moving={prop.isMoving}") | |||
| f"GUID={prop.guid}, x={prop.x}, y={prop.y}, place={prop.place.name}") | |||
| self.__logger.info("*********************") | |||
| def PrintSelfInfo(self) -> None: | |||
| @@ -554,13 +763,10 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||
| self.__logger.info( | |||
| f"playerID={mySelf.playerID}, GUID={mySelf.guid}, x={mySelf.x}, y={mySelf.y}") | |||
| self.__logger.info( | |||
| f"speed={mySelf.speed}, view range={mySelf.viewRange}, skill time={mySelf.timeUntilSkillAvailable}, prop={mySelf.prop.name}, place={mySelf.place.name}") | |||
| f"speed={mySelf.speed}, view range={mySelf.viewRange}, skill time={mySelf.timeUntilSkillAvailable}, place={mySelf.place.name}") | |||
| if isinstance(mySelf, THUAI6.Student): | |||
| self.__logger.info( | |||
| f"state={mySelf.state.name}, determination={mySelf.determination}, fail time={mySelf.failTime}") | |||
| else: | |||
| self.__logger.info( | |||
| f"damage={mySelf.damage}, movable={mySelf.movable}") | |||
| f"state={mySelf.playerState.name}, determination={mySelf.determination}") | |||
| self.__logger.info("buff=") | |||
| mySelfBuff = "" | |||
| for buff in mySelf.buff: | |||
| @@ -570,57 +776,8 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||
| # 屠夫阵营的特殊函数 | |||
| def Trick(self, angle: float) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"Trick: angle = {angle}, called at {self.__GetTime()}ms") | |||
| def logTrick() -> bool: | |||
| result = self.__logic.Trick(angle) | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"Trick: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logTrick) | |||
| def StartExam(self) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"StartExam: called at {self.__GetTime()}ms") | |||
| def logCarry() -> bool: | |||
| result = self.__logic.StartExam() | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"StartExam: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logCarry) | |||
| def EndExam(self) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"EndExam: called at {self.__GetTime()}ms") | |||
| def logRelease() -> bool: | |||
| result = self.__logic.EndExam() | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"EndExam: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logRelease) | |||
| def MakeFail(self) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"MakeFail: called at {self.__GetTime()}ms") | |||
| def logHang() -> bool: | |||
| result = self.__logic.MakeFail() | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"MakeFail: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logHang) | |||
| def GetSelfInfo(self) -> THUAI6.Tricker: | |||
| return cast(THUAI6.Tricker, self.__logic.GetSelfInfo()) | |||
| # Timer用 | |||
| @@ -636,4 +793,4 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||
| self.__logger.info(f"Time elapsed: {self.__GetTime()}ms") | |||
| def Play(self, ai: IAI) -> None: | |||
| ai.play(self) | |||
| ai.TrickerPlay(self) | |||
| @@ -32,6 +32,34 @@ class ILogic(metaclass=ABCMeta): | |||
| def GetPlaceType(self, x: int, y: int) -> THUAI6.PlaceType: | |||
| pass | |||
| @abstractmethod | |||
| def GetClassroomProgress(self, x: int, y: int) -> int: | |||
| pass | |||
| @abstractmethod | |||
| def GetChestProgress(self, x: int, y: int) -> int: | |||
| pass | |||
| @abstractmethod | |||
| def GetGateProgress(self, x: int, y: int) -> int: | |||
| pass | |||
| @abstractmethod | |||
| def IsDoorOpen(self, x: int, y: int) -> bool: | |||
| pass | |||
| @abstractmethod | |||
| def GetHiddenGateState(self, x: int, y: int) -> THUAI6.HiddenGateState: | |||
| pass | |||
| @abstractmethod | |||
| def GetDoorProgress(self, x: int, y: int) -> int: | |||
| pass | |||
| @abstractmethod | |||
| def GetGameInfo(self) -> THUAI6.GameInfo: | |||
| pass | |||
| @abstractmethod | |||
| def Move(self, time: int, angle: float) -> bool: | |||
| pass | |||
| @@ -41,11 +69,11 @@ class ILogic(metaclass=ABCMeta): | |||
| pass | |||
| @abstractmethod | |||
| def UseProp(self) -> bool: | |||
| def UseProp(self, propType: THUAI6.PropType) -> bool: | |||
| pass | |||
| @abstractmethod | |||
| def UseSkill(self) -> bool: | |||
| def UseSkill(self, skillID: int) -> bool: | |||
| pass | |||
| @abstractmethod | |||
| @@ -72,44 +100,50 @@ class ILogic(metaclass=ABCMeta): | |||
| def GetPlayerGUIDs(self) -> List[int]: | |||
| pass | |||
| # IStudentAPI使用的接口 | |||
| @abstractmethod | |||
| def Attack(self, angle: float) -> bool: | |||
| pass | |||
| @abstractmethod | |||
| def Graduate(self) -> bool: | |||
| def OpenDoor(self) -> bool: | |||
| pass | |||
| @abstractmethod | |||
| def StartLearning(self) -> bool: | |||
| def CloseDoor(self) -> bool: | |||
| pass | |||
| @abstractmethod | |||
| def EndLearning(self) -> bool: | |||
| def SkipWindow(self) -> bool: | |||
| pass | |||
| @abstractmethod | |||
| def StartHelpMate(self) -> bool: | |||
| def StartOpenGate(self) -> bool: | |||
| pass | |||
| @abstractmethod | |||
| def EndHelpMate(self) -> bool: | |||
| def StartOpenChest(self) -> bool: | |||
| pass | |||
| # Tricker使用的接口 | |||
| @abstractmethod | |||
| def EndAllAction(self) -> bool: | |||
| pass | |||
| # IStudentAPI使用的接口 | |||
| @abstractmethod | |||
| def Trick(self, angle: float) -> bool: | |||
| def Graduate(self) -> bool: | |||
| pass | |||
| @abstractmethod | |||
| def StartExam(self) -> bool: | |||
| def StartLearning(self) -> bool: | |||
| pass | |||
| @abstractmethod | |||
| def EndExam(self) -> bool: | |||
| def StartTreatMate(self, mateID: int) -> bool: | |||
| pass | |||
| @abstractmethod | |||
| def MakeFail(self) -> bool: | |||
| def StartRescueMate(self, mateID: int) -> bool: | |||
| pass | |||
| @@ -147,11 +181,39 @@ class IAPI(metaclass=ABCMeta): | |||
| pass | |||
| @abstractmethod | |||
| def UseProp(self) -> Future[bool]: | |||
| def UseProp(self, propType: THUAI6.PropType) -> Future[bool]: | |||
| pass | |||
| @abstractmethod | |||
| def UseSkill(self, skillID: int) -> Future[bool]: | |||
| pass | |||
| @abstractmethod | |||
| def Attack(self, angle: float) -> Future[bool]: | |||
| pass | |||
| @abstractmethod | |||
| def OpenDoor(self) -> Future[bool]: | |||
| pass | |||
| @abstractmethod | |||
| def UseSkill(self) -> Future[bool]: | |||
| def CloseDoor(self) -> Future[bool]: | |||
| pass | |||
| @abstractmethod | |||
| def SkipWindow(self) -> Future[bool]: | |||
| pass | |||
| @abstractmethod | |||
| def StartOpenGate(self) -> Future[bool]: | |||
| pass | |||
| @abstractmethod | |||
| def StartOpenChest(self) -> Future[bool]: | |||
| pass | |||
| @abstractmethod | |||
| def EndAllAction(self) -> Future[bool]: | |||
| pass | |||
| # 消息相关,接收消息时无消息则返回(-1, '') | |||
| @@ -208,6 +270,34 @@ class IAPI(metaclass=ABCMeta): | |||
| def GetPlaceType(self, cellX: int, cellY: int) -> THUAI6.PlaceType: | |||
| pass | |||
| @abstractmethod | |||
| def IsDoorOpen(self, cellX: int, cellY: int) -> bool: | |||
| pass | |||
| @abstractmethod | |||
| def GetChestProgress(self, cellX: int, cellY: int) -> int: | |||
| pass | |||
| @abstractmethod | |||
| def GetGateProgress(self, cellX: int, cellY: int) -> int: | |||
| pass | |||
| @abstractmethod | |||
| def GetClassroomProgress(self, cellX: int, cellY: int) -> int: | |||
| pass | |||
| @abstractmethod | |||
| def GetDoorProgress(self, cellX: int, cellY: int) -> int: | |||
| pass | |||
| @abstractmethod | |||
| def GetHiddenGateState(self, cellX: int, cellY: int) -> THUAI6.HiddenGateState: | |||
| pass | |||
| @abstractmethod | |||
| def GetGameInfo(self) -> THUAI6.GameInfo: | |||
| pass | |||
| # 用于DEBUG的输出函数,仅在DEBUG模式下有效 | |||
| @abstractmethod | |||
| @@ -240,15 +330,15 @@ class IStudentAPI(IAPI, metaclass=ABCMeta): | |||
| pass | |||
| @abstractmethod | |||
| def EndLearning(self) -> Future[bool]: | |||
| def StartTreatMate(self, mateID: int) -> Future[bool]: | |||
| pass | |||
| @abstractmethod | |||
| def StartHelpMate(self) -> Future[bool]: | |||
| def StartRescueMate(self, mateID: int) -> Future[bool]: | |||
| pass | |||
| @abstractmethod | |||
| def EndHelpMate(self) -> Future[bool]: | |||
| def GetSelfInfo(self) -> THUAI6.Student: | |||
| pass | |||
| @@ -257,25 +347,17 @@ class ITrickerAPI(IAPI, metaclass=ABCMeta): | |||
| # 屠夫阵营的特殊函数 | |||
| @abstractmethod | |||
| def Trick(self, angle: float) -> Future[bool]: | |||
| pass | |||
| @abstractmethod | |||
| def StartExam(self) -> Future[bool]: | |||
| def GetSelfInfo(self) -> THUAI6.Tricker: | |||
| pass | |||
| @abstractmethod | |||
| def EndExam(self) -> Future[bool]: | |||
| pass | |||
| class IAI(metaclass=ABCMeta): | |||
| @abstractmethod | |||
| def MakeFail(self) -> Future[bool]: | |||
| def StudentPlay(self, api: IStudentAPI) -> None: | |||
| pass | |||
| class IAI(metaclass=ABCMeta): | |||
| @abstractmethod | |||
| def play(self, api: Union[IStudentAPI, ITrickerAPI]) -> None: | |||
| def TrickerPlay(self, api: ITrickerAPI) -> None: | |||
| pass | |||
| @@ -6,18 +6,18 @@ class State: | |||
| teamScore: int | |||
| self: Union[THUAI6.Student, THUAI6.Tricker] | |||
| students: List[THUAI6.Student] | |||
| trickers: List[THUAI6.Tricker] | |||
| students: List[THUAI6.Student] = [] | |||
| trickers: List[THUAI6.Tricker] = [] | |||
| props: List[THUAI6.Prop] | |||
| props: List[THUAI6.Prop] = [] | |||
| gameMap: List[List[THUAI6.PlaceType]] | |||
| gameMap: List[List[THUAI6.PlaceType]] = [] | |||
| bullets: List[THUAI6.Bullet] | |||
| bombedBullets: List[THUAI6.BombedBullet] | |||
| bullets: List[THUAI6.Bullet] = [] | |||
| bombedBullets: List[THUAI6.BombedBullet] = [] | |||
| mapInfo: THUAI6.GameMap | |||
| mapInfo: THUAI6.GameMap = THUAI6.GameMap() | |||
| gameInfo: THUAI6.GameInfo | |||
| gameInfo: THUAI6.GameInfo = THUAI6.GameInfo() | |||
| guids: List[int] | |||
| guids: List[int] = [] | |||
| @@ -6,6 +6,7 @@ import logging | |||
| import proto.MessageType_pb2 as MessageType | |||
| import proto.Message2Server_pb2 as Message2Server | |||
| import proto.Message2Clients_pb2 as Message2Clients | |||
| from queue import Queue | |||
| import PyAPI.structures as THUAI6 | |||
| from PyAPI.utils import Proto2THUAI6, AssistFunction | |||
| from PyAPI.DebugAPI import StudentDebugAPI, TrickerDebugAPI | |||
| @@ -27,8 +28,8 @@ class Logic(ILogic): | |||
| self.__comm: Communication | |||
| # 存储状态 | |||
| self.__currentState: State | |||
| self.__bufferState: State | |||
| self.__currentState: State = State() | |||
| self.__bufferState: State = State() | |||
| # timer,用于实际运行AI | |||
| self.__timer: IGameTimer | |||
| @@ -44,8 +45,8 @@ class Logic(ILogic): | |||
| self.__cvAI: threading.Condition = threading.Condition() | |||
| # 保存缓冲区数 | |||
| self.__counterState: int | |||
| self.__counterBuffer: int | |||
| self.__counterState: int = 0 | |||
| self.__counterBuffer: int = 0 | |||
| # 记录游戏状态 | |||
| self.__gameState: THUAI6.GameState = THUAI6.GameState.NullGameState | |||
| @@ -64,6 +65,8 @@ class Logic(ILogic): | |||
| self.__logger: logging.Logger = logging.getLogger("logic") | |||
| self.__messageQueue: Queue = Queue() | |||
| # IAPI统一可用的接口 | |||
| def GetTrickers(self) -> List[THUAI6.Tricker]: | |||
| @@ -102,14 +105,16 @@ class Logic(ILogic): | |||
| if (x, y) in self.__currentState.mapInfo.doorState: | |||
| return self.__currentState.mapInfo.doorState[(x, y)] | |||
| else: | |||
| self.__logger.warning("Door not found") | |||
| return False | |||
| def GetClassroomProgess(self, x: int, y: int) -> int: | |||
| def GetClassroomProgress(self, x: int, y: int) -> int: | |||
| with self.__mtxState: | |||
| self.__logger.debug("Called GetClassroomProgess") | |||
| self.__logger.debug("Called GetClassroomProgress") | |||
| if (x, y) in self.__currentState.mapInfo.classroomState: | |||
| return self.__currentState.mapInfo.classroomState[(x, y)] | |||
| else: | |||
| self.__logger.warning("Classroom not found") | |||
| return 0 | |||
| def GetChestProgress(self, x: int, y: int) -> int: | |||
| @@ -118,6 +123,7 @@ class Logic(ILogic): | |||
| if (x, y) in self.__currentState.mapInfo.chestState: | |||
| return self.__currentState.mapInfo.chestState[(x, y)] | |||
| else: | |||
| self.__logger.warning("Chest not found") | |||
| return 0 | |||
| def GetGateProgress(self, x: int, y: int) -> int: | |||
| @@ -126,6 +132,25 @@ class Logic(ILogic): | |||
| if (x, y) in self.__currentState.mapInfo.gateState: | |||
| return self.__currentState.mapInfo.gateState[(x, y)] | |||
| else: | |||
| self.__logger.warning("Gate not found") | |||
| return 0 | |||
| def GetHiddenGateState(self, x: int, y: int) -> THUAI6.HiddenGateState: | |||
| with self.__mtxState: | |||
| self.__logger.debug("Called GetHiddenGateState") | |||
| if (x, y) in self.__currentState.mapInfo.hiddenGateState: | |||
| return self.__currentState.mapInfo.hiddenGateState[(x, y)] | |||
| else: | |||
| self.__logger.warning("HiddenGate not found") | |||
| return THUAI6.HiddenGateState.Null | |||
| def GetDoorProgress(self, x: int, y: int) -> int: | |||
| with self.__mtxState: | |||
| self.__logger.debug("Called GetDoorProgress") | |||
| if (x, y) in self.__currentState.mapInfo.doorProgress: | |||
| return self.__currentState.mapInfo.doorProgress[(x, y)] | |||
| else: | |||
| self.__logger.warning("Door not found") | |||
| return 0 | |||
| def GetGameInfo(self) -> THUAI6.GameInfo: | |||
| @@ -141,13 +166,13 @@ class Logic(ILogic): | |||
| self.__logger.debug("Called PickProp") | |||
| return self.__comm.PickProp(propType, self.__playerID) | |||
| def UseProp(self) -> bool: | |||
| def UseProp(self, propType: THUAI6.PropType) -> bool: | |||
| self.__logger.debug("Called UseProp") | |||
| return self.__comm.UseProp(self.__playerID) | |||
| return self.__comm.UseProp(propType, self.__playerID) | |||
| def UseSkill(self) -> bool: | |||
| def UseSkill(self, skillID: int) -> bool: | |||
| self.__logger.debug("Called UseSkill") | |||
| return self.__comm.UseSkill(self.__playerID) | |||
| return self.__comm.UseSkill(skillID, self.__playerID) | |||
| def SendMessage(self, toID: int, message: str) -> bool: | |||
| self.__logger.debug("Called SendMessage") | |||
| @@ -155,11 +180,11 @@ class Logic(ILogic): | |||
| def HaveMessage(self) -> bool: | |||
| self.__logger.debug("Called HaveMessage") | |||
| return self.__comm.HaveMessage() | |||
| return self.__messageQueue.empty() | |||
| def GetMessage(self) -> tuple[int, str]: | |||
| self.__logger.debug("Called GetMessage") | |||
| return self.__comm.GetMessage() | |||
| return self.__messageQueue.get() | |||
| def WaitThread(self) -> bool: | |||
| self.__Update() | |||
| @@ -183,13 +208,13 @@ class Logic(ILogic): | |||
| self.__logger.debug("Called StartLearning") | |||
| return self.__comm.StartLearning(self.__playerID) | |||
| def StartTreatMate(self) -> bool: | |||
| def StartTreatMate(self, mateID: int) -> bool: | |||
| self.__logger.debug("Called StartTreatMate") | |||
| return self.__comm.StartTreatMate(self.__playerID) | |||
| return self.__comm.StartTreatMate(self.__playerID, mateID) | |||
| def StartRescueMate(self) -> bool: | |||
| def StartRescueMate(self, mateID: int) -> bool: | |||
| self.__logger.debug("Called StartRescueMate") | |||
| return self.__comm.StartRescueMate(self.__playerID) | |||
| return self.__comm.StartRescueMate(self.__playerID, mateID) | |||
| def Attack(self, angle: float) -> bool: | |||
| self.__logger.debug("Called Trick") | |||
| @@ -229,7 +254,6 @@ class Logic(ILogic): | |||
| self.__logger.info("Message thread start!") | |||
| self.__comm.AddPlayer(self.__playerID) | |||
| self.__logger.info("Join the player!") | |||
| self.__comm.ReadMessage(self.__playerID) | |||
| while self.__gameState != THUAI6.GameState.GameEnd: | |||
| # 读取消息,无消息时此处阻塞 | |||
| @@ -242,13 +266,31 @@ class Logic(ILogic): | |||
| # 读取玩家的GUID | |||
| self.__logger.info("Game start!") | |||
| self.__playerGUIDs.clear() | |||
| for student in clientMsg.student_message: | |||
| self.__playerGUIDs.append(student.guid) | |||
| for tricker in clientMsg.tricker_message: | |||
| self.__playerGUIDs.append(tricker.guid) | |||
| for obj in clientMsg.obj_message: | |||
| if obj.WhichOneof("message_of_obj") == "student_message": | |||
| self.__playerGUIDs.append(obj.student_message.guid) | |||
| for obj in clientMsg.obj_message: | |||
| if obj.WhichOneof("message_of_obj") == "tricker_message": | |||
| self.__playerGUIDs.append(obj.tricker_message.guid) | |||
| self.__currentState.guids = self.__playerGUIDs | |||
| self.__bufferState.guids = self.__playerGUIDs | |||
| for obj in clientMsg.obj_message: | |||
| if obj.WhichOneof("message_of_obj") == "map_message": | |||
| gameMap: List[List[THUAI6.PlaceType]] = [] | |||
| for row in obj.map_message.row: | |||
| col: List[THUAI6.PlaceType] = [] | |||
| for place in row.col: | |||
| col.append( | |||
| Proto2THUAI6.placeTypeDict[place]) | |||
| gameMap.append(col) | |||
| self.__currentState.gameMap = gameMap | |||
| self.__bufferState.gameMap = gameMap | |||
| self.__logger.info("Game map loaded!") | |||
| break | |||
| else: | |||
| self.__logger.error("Map not found!") | |||
| self.__LoadBuffer(clientMsg) | |||
| self.__AILoop = True | |||
| self.__UnBlockAI() | |||
| @@ -256,10 +298,12 @@ class Logic(ILogic): | |||
| elif self.__gameState == THUAI6.GameState.GameRunning: | |||
| # 读取玩家的GUID | |||
| self.__playerGUIDs.clear() | |||
| for student in clientMsg.student_message: | |||
| self.__playerGUIDs.append(student.guid) | |||
| for tricker in clientMsg.tricker_message: | |||
| self.__playerGUIDs.append(tricker.guid) | |||
| for obj in clientMsg.obj_message: | |||
| if obj.WhichOneof("message_of_obj") == "student_message": | |||
| self.__playerGUIDs.append(obj.student_message.guid) | |||
| for obj in clientMsg.obj_message: | |||
| if obj.WhichOneof("message_of_obj") == "tricker_message": | |||
| self.__playerGUIDs.append(obj.tricker_message.guid) | |||
| self.__currentState.guids = self.__playerGUIDs | |||
| self.__bufferState.guids = self.__playerGUIDs | |||
| self.__LoadBuffer(clientMsg) | |||
| @@ -282,38 +326,170 @@ class Logic(ILogic): | |||
| self.__bufferState.trickers.clear() | |||
| self.__bufferState.props.clear() | |||
| self.__logger.debug("Buffer cleared!") | |||
| self.__bufferState.map = Proto2THUAI6.Protobuf2THUAI6Map( | |||
| message.map_message) | |||
| self.__bufferState.gameInfo = Proto2THUAI6.Protobuf2THUAI6GameInfo( | |||
| message.all_message) | |||
| if Setting.playerType() == THUAI6.PlayerType.StudentPlayer: | |||
| for student in message.student_message: | |||
| if student.player_id == self.__playerID: | |||
| self.__bufferState.self = Proto2THUAI6.Protobuf2THUAI6Student( | |||
| student) | |||
| self.__bufferState.students.append( | |||
| Proto2THUAI6.Protobuf2THUAI6Student(student)) | |||
| self.__logger.debug("Add Student!") | |||
| for tricker in message.tricker_message: | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, tricker.x, tricker.y, self.__bufferState.map): | |||
| self.__bufferState.trickers.append( | |||
| Proto2THUAI6.Protobuf2THUAI6Tricker(tricker)) | |||
| self.__logger.debug("Add Tricker!") | |||
| else: | |||
| for tricker in message.tricker_message: | |||
| if tricker.player_id == self.__playerID: | |||
| self.__bufferState.self = Proto2THUAI6.Protobuf2THUAI6Tricker( | |||
| tricker) | |||
| self.__bufferState.trickers.append( | |||
| Proto2THUAI6.Protobuf2THUAI6Tricker(tricker)) | |||
| self.__logger.debug("Add Tricker!") | |||
| for student in message.student_message: | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, student.x, student.y, self.__bufferState.map): | |||
| for item in message.obj_message: | |||
| if item.WhichOneof("message_of_obj") == "student_message": | |||
| if item.student_message.player_id == self.__playerID: | |||
| self.__bufferState.self = Proto2THUAI6.Protobuf2THUAI6Student( | |||
| item.student_message) | |||
| self.__bufferState.students.append( | |||
| Proto2THUAI6.Protobuf2THUAI6Student(student)) | |||
| Proto2THUAI6.Protobuf2THUAI6Student(item.student_message)) | |||
| self.__logger.debug("Add Student!") | |||
| for prop in message.prop_message: | |||
| self.__bufferState.props.append( | |||
| Proto2THUAI6.Protobuf2THUAI6Prop(prop)) | |||
| self.__logger.debug("Add Prop!") | |||
| for item in message.obj_message: | |||
| if item.WhichOneof("message_of_obj") == "tricker_message": | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.tricker_message.x, item.tricker_message.y, self.__bufferState.gameMap): | |||
| self.__bufferState.trickers.append( | |||
| Proto2THUAI6.Protobuf2THUAI6Tricker(item.tricker_message)) | |||
| self.__logger.debug("Add Tricker!") | |||
| elif item.WhichOneof("message_of_obj") == "prop_message": | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.prop_message.x, item.prop_message.y, self.__bufferState.gameMap): | |||
| self.__bufferState.props.append( | |||
| Proto2THUAI6.Protobuf2THUAI6Prop(item.prop_message)) | |||
| self.__logger.debug("Add Prop!") | |||
| elif item.WhichOneof("message_of_obj") == "bullet_message": | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.bullet_message.x, item.bullet_message.y, self.__bufferState.gameMap): | |||
| self.__bufferState.bullets.append( | |||
| Proto2THUAI6.Protobuf2THUAI6Bullet(item.bullet_message)) | |||
| self.__logger.debug("Add Bullet!") | |||
| elif item.WhichOneof("message_of_obj") == "classroom_message": | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.classroom_message.x, item.classroom_message.y, self.__bufferState.gameMap): | |||
| pos = (AssistFunction.GridToCell( | |||
| item.classroom_message.x), AssistFunction.GridToCell(item.classroom_message.y)) | |||
| if pos in self.__bufferState.mapInfo.classroomState: | |||
| self.__bufferState.mapInfo.classroomState[pos] = item.classroom_message.progress | |||
| self.__logger.debug("Add Classroom!") | |||
| else: | |||
| self.__bufferState.mapInfo.classroomState[pos] = item.classroom_message.progress | |||
| self.__logger.debug("Update Classroom!") | |||
| elif item.WhichOneof("message_of_obj") == "chest_message": | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.chest_message.x, item.chest_message.y, self.__bufferState.gameMap): | |||
| pos = (AssistFunction.GridToCell( | |||
| item.chest_message.x), AssistFunction.GridToCell(item.chest_message.y)) | |||
| if pos in self.__bufferState.mapInfo.chestState: | |||
| self.__bufferState.mapInfo.chestState[pos] = item.chest_message.progress | |||
| self.__logger.debug("Add Chest!") | |||
| else: | |||
| self.__bufferState.mapInfo.chestState[pos] = item.chest_message.progress | |||
| self.__logger.debug("Update Chest!") | |||
| elif item.WhichOneof("message_of_obj") == "door_message": | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.door_message.x, item.door_message.y, self.__bufferState.gameMap): | |||
| pos = (AssistFunction.GridToCell( | |||
| item.door_message.x), AssistFunction.GridToCell(item.door_message.y)) | |||
| if pos in self.__bufferState.mapInfo.doorState: | |||
| self.__bufferState.mapInfo.doorState[pos] = item.door_message.is_open | |||
| self.__bufferState.mapInfo.doorProgress[pos] = item.door_message.progress | |||
| self.__logger.debug("Add Door!") | |||
| else: | |||
| self.__bufferState.mapInfo.doorState[pos] = item.door_message.is_open | |||
| self.__bufferState.mapInfo.doorProgress[pos] = item.door_message.progress | |||
| self.__logger.debug("Update Door!") | |||
| elif item.WhichOneof("message_of_obj") == "hidden_gate_message": | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.hidden_gate_message.x, item.hidden_gate_message.y, self.__bufferState.gameMap): | |||
| pos = (AssistFunction.GridToCell( | |||
| item.hidden_gate_message.x), AssistFunction.GridToCell(item.hidden_gate_message.y)) | |||
| if pos in self.__bufferState.mapInfo.hiddenGateState: | |||
| self.__bufferState.mapInfo.hiddenGateState[pos] = Proto2THUAI6.Bool2HiddenGateState( | |||
| item.hidden_gate_message.opened) | |||
| self.__logger.debug("Add HiddenGate!") | |||
| else: | |||
| self.__bufferState.mapInfo.hiddenGateState[pos] = Proto2THUAI6.Bool2HiddenGateState( | |||
| item.hidden_gate_message.opened) | |||
| self.__logger.debug("Update HiddenGate!") | |||
| elif item.WhichOneof("message_of_obj") == "gate_message": | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.gate_message.x, item.gate_message.y, self.__bufferState.gameMap): | |||
| pos = (AssistFunction.GridToCell( | |||
| item.gate_message.x), AssistFunction.GridToCell(item.gate_message.y)) | |||
| if pos in self.__bufferState.mapInfo.gateState: | |||
| self.__bufferState.mapInfo.gateState[pos] = item.gate_message.progress | |||
| self.__logger.debug("Add Gate!") | |||
| else: | |||
| self.__bufferState.mapInfo.gateState[pos] = item.gate_message.progress | |||
| self.__logger.debug("Update Gate!") | |||
| else: | |||
| self.__logger.debug("Unknown Message!") | |||
| else: | |||
| for item in message.obj_message: | |||
| if item.WhichOneof("message_of_obj") == "tricker_message": | |||
| if item.tricker_message.player_id == self.__playerID: | |||
| self.__bufferState.self = Proto2THUAI6.Protobuf2THUAI6Tricker( | |||
| item.tricker_message) | |||
| self.__bufferState.trickers.append( | |||
| Proto2THUAI6.Protobuf2THUAI6Tricker(item.tricker_message)) | |||
| self.__logger.debug("Add Tricker!") | |||
| for item in message.obj_message: | |||
| if item.WhichOneof("message_of_obj") == "student_message": | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.student_message.x, item.student_message.y, self.__bufferState.gameMap): | |||
| self.__bufferState.students.append( | |||
| Proto2THUAI6.Protobuf2THUAI6Student(item.student_message)) | |||
| self.__logger.debug("Add Student!") | |||
| elif item.WhichOneof("message_of_obj") == "prop_message": | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.prop_message.x, item.prop_message.y, self.__bufferState.gameMap): | |||
| self.__bufferState.props.append( | |||
| Proto2THUAI6.Protobuf2THUAI6Prop(item.prop_message)) | |||
| self.__logger.debug("Add Prop!") | |||
| elif item.WhichOneof("message_of_obj") == "bullet_message": | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.bullet_message.x, item.bullet_message.y, self.__bufferState.gameMap): | |||
| self.__bufferState.bullets.append( | |||
| Proto2THUAI6.Protobuf2THUAI6Bullet(item.bullet_message)) | |||
| self.__logger.debug("Add Bullet!") | |||
| elif item.WhichOneof("message_of_obj") == "classroom_message": | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.classroom_message.x, item.classroom_message.y, self.__bufferState.gameMap): | |||
| pos = (AssistFunction.GridToCell( | |||
| item.classroom_message.x), AssistFunction.GridToCell(item.classroom_message.y)) | |||
| if pos in self.__bufferState.mapInfo.classroomState: | |||
| self.__bufferState.mapInfo.classroomState[pos] = item.classroom_message.progress | |||
| self.__logger.debug("Add Classroom!") | |||
| else: | |||
| self.__bufferState.mapInfo.classroomState[pos] = item.classroom_message.progress | |||
| self.__logger.debug("Update Classroom!") | |||
| elif item.WhichOneof("message_of_obj") == "chest_message": | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.chest_message.x, item.chest_message.y, self.__bufferState.gameMap): | |||
| pos = (AssistFunction.GridToCell( | |||
| item.chest_message.x), AssistFunction.GridToCell(item.chest_message.y)) | |||
| if pos in self.__bufferState.mapInfo.chestState: | |||
| self.__bufferState.mapInfo.chestState[pos] = item.chest_message.progress | |||
| self.__logger.debug("Add Chest!") | |||
| else: | |||
| self.__bufferState.mapInfo.chestState[pos] = item.chest_message.progress | |||
| self.__logger.debug("Update Chest!") | |||
| elif item.WhichOneof("message_of_obj") == "door_message": | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.door_message.x, item.door_message.y, self.__bufferState.gameMap): | |||
| pos = (AssistFunction.GridToCell( | |||
| item.door_message.x), AssistFunction.GridToCell(item.door_message.y)) | |||
| if pos in self.__bufferState.mapInfo.doorState: | |||
| self.__bufferState.mapInfo.doorState[pos] = item.door_message.is_open | |||
| self.__bufferState.mapInfo.doorProgress[pos] = item.door_message.progress | |||
| self.__logger.debug("Add Door!") | |||
| else: | |||
| self.__bufferState.mapInfo.doorState[pos] = item.door_message.is_open | |||
| self.__bufferState.mapInfo.doorProgress[pos] = item.door_message.progress | |||
| self.__logger.debug("Update Door!") | |||
| elif item.WhichOneof("message_of_obj") == "hidden_gate_message": | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.hidden_gate_message.x, item.hidden_gate_message.y, self.__bufferState.gameMap): | |||
| pos = (AssistFunction.GridToCell( | |||
| item.hidden_gate_message.x), AssistFunction.GridToCell(item.hidden_gate_message.y)) | |||
| if pos in self.__bufferState.mapInfo.hiddenGateState: | |||
| self.__bufferState.mapInfo.hiddenGateState[pos] = Proto2THUAI6.Bool2HiddenGateState( | |||
| item.hidden_gate_message.opened) | |||
| self.__logger.debug("Add HiddenGate!") | |||
| else: | |||
| self.__bufferState.mapInfo.hiddenGateState[pos] = Proto2THUAI6.Bool2HiddenGateState( | |||
| item.hidden_gate_message.opened) | |||
| self.__logger.debug("Update HiddenGate!") | |||
| elif item.WhichOneof("message_of_obj") == "gate_message": | |||
| if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.gate_message.x, item.gate_message.y, self.__bufferState.gameMap): | |||
| pos = (AssistFunction.GridToCell( | |||
| item.gate_message.x), AssistFunction.GridToCell(item.gate_message.y)) | |||
| if pos in self.__bufferState.mapInfo.gateState: | |||
| self.__bufferState.mapInfo.gateState[pos] = item.gate_message.progress | |||
| self.__logger.debug("Add Gate!") | |||
| else: | |||
| self.__bufferState.mapInfo.gateState[pos] = item.gate_message.progress | |||
| self.__logger.debug("Update Gate!") | |||
| else: | |||
| self.__logger.debug("Unknown Message!") | |||
| if Setting.asynchronous(): | |||
| with self.__mtxState: | |||
| self.__currentState, self.__bufferState = self.__bufferState, self.__currentState | |||
| @@ -355,7 +531,7 @@ class Logic(ILogic): | |||
| os.path.realpath(__file__))) + "/logs") | |||
| fileHandler = logging.FileHandler(os.path.dirname( | |||
| os.path.dirname(os.path.realpath(__file__))) + "/logs/logic-log.txt") | |||
| os.path.dirname(os.path.realpath(__file__))) + "/logs/logic-log.txt", "w+", encoding="utf-8") | |||
| screenHandler = logging.StreamHandler() | |||
| if file: | |||
| fileHandler.setLevel(logging.DEBUG) | |||
| @@ -11,9 +11,9 @@ from typing import List, Callable | |||
| def THUAI6Main(argv: List[str], AIBuilder: Callable) -> None: | |||
| pID: int = 114514 | |||
| sIP: str = "114.51.41.91" | |||
| sPort: str = "9810" | |||
| pID: int = 0 | |||
| sIP: str = "172.22.32.1" | |||
| sPort: str = "8888" | |||
| file: bool = True | |||
| screen: bool = True | |||
| warnOnly: bool = False | |||
| @@ -18,8 +18,10 @@ class PlaceType(Enum): | |||
| Gate = 5 | |||
| HiddenGate = 6 | |||
| Window = 7 | |||
| Door = 8 | |||
| Chest = 9 | |||
| Door3 = 8 | |||
| Door5 = 9 | |||
| Door6 = 10 | |||
| Chest = 11 | |||
| class ShapeType(Enum): | |||
| @@ -36,13 +38,19 @@ class PlayerType(Enum): | |||
| class PropType(Enum): | |||
| NullPropType = 0 | |||
| PropType1 = 1 | |||
| Key3 = 1 | |||
| Key5 = 2 | |||
| Key6 = 3 | |||
| AddSpeed = 4 | |||
| AddLifeOrAp = 5 | |||
| AddHpOrAp = 6 | |||
| ShieldOrSpear = 7 | |||
| class BulletType(Enum): | |||
| NullBulletType = 0 | |||
| LineBullet = 1 | |||
| CommonBullet = 2 | |||
| FlyingKnife = 1 | |||
| CommonAttackOfTricker = 2 | |||
| FastBullet = 3 | |||
| OrdinaryBullet = 4 | |||
| AtomBomb = 5 | |||
| @@ -50,12 +58,12 @@ class BulletType(Enum): | |||
| class StudentType(Enum): | |||
| NullStudentType = 0 | |||
| StudentType1 = 1 | |||
| Athlete = 1 | |||
| class TrickerType(Enum): | |||
| NullTrickerType = 0 | |||
| TrickerType1 = 1 | |||
| Assassin = 1 | |||
| class StudentBuffType(Enum): | |||
| @@ -85,6 +93,9 @@ class PlayerState(Enum): | |||
| Locking = 13 | |||
| Rummaging = 14 | |||
| Climbing = 15 | |||
| OpeningAChest = 16 | |||
| UsingSpecialSkill = 17 | |||
| OpeningAGate = 18 | |||
| class MessageOfObj(Enum): | |||
| @@ -97,6 +108,16 @@ class MessageOfObj(Enum): | |||
| ClassroomMessage = 6 | |||
| GateMessage = 7 | |||
| ChestMessage = 8 | |||
| DoorMessage = 9 | |||
| MapMessage = 10 | |||
| NewsMessage = 11 | |||
| HiddenGateMessage = 12 | |||
| class HiddenGateState(Enum): | |||
| Null = 0 | |||
| Refreshed = 1 | |||
| Opened = 2 | |||
| class Player: | |||
| @@ -107,35 +128,42 @@ class Player: | |||
| playerID: int | |||
| guid: int | |||
| radius: int | |||
| damage: int | |||
| timeUntilSkillAvailable: List[float] | |||
| score: int | |||
| facingDirection: float | |||
| timeUntilSkillAvailable: List[float] = [] | |||
| playerType: PlayerType | |||
| prop: List[PropType] | |||
| prop: List[PropType] = [] | |||
| place: PlaceType | |||
| bulletType: BulletType | |||
| playerState: PlayerState | |||
| class Student(Player): | |||
| studentType: StudentType | |||
| determination: int | |||
| addiction: int | |||
| studentType: StudentType | |||
| buff: List[StudentBuffType] | |||
| treatProgress: int | |||
| rescueProgress: int | |||
| learningSpeed: int | |||
| treatSpeed: int | |||
| dangerAlert: float | |||
| buff: List[StudentBuffType] = [] | |||
| class Tricker(Player): | |||
| trickerType: TrickerType | |||
| buff: List[TrickerBuffType] | |||
| trickDesire: float | |||
| classVolume: float | |||
| buff: List[TrickerBuffType] = [] | |||
| class Prop: | |||
| x: int | |||
| y: int | |||
| size: int | |||
| guid: int | |||
| type: PropType | |||
| place: PlaceType | |||
| facingDirection: float | |||
| isMoving: bool | |||
| class Bullet: | |||
| @@ -147,9 +175,10 @@ class Bullet: | |||
| team: PlayerType | |||
| place: PlaceType | |||
| bombRange: float | |||
| speed: int | |||
| class BombedBullet(): | |||
| class BombedBullet: | |||
| bulletType: BulletType | |||
| x: int | |||
| y: int | |||
| @@ -159,10 +188,12 @@ class BombedBullet(): | |||
| class GameMap: | |||
| classroomState: Dict[tuple[int, int], int] | |||
| gateState: Dict[tuple[int, int], int] | |||
| chestState: Dict[tuple[int, int], bool] | |||
| doorState: Dict[tuple[int, int], bool] | |||
| classroomState: Dict[tuple[int, int], int] = {} | |||
| gateState: Dict[tuple[int, int], int] = {} | |||
| chestState: Dict[tuple[int, int], int] = {} | |||
| doorState: Dict[tuple[int, int], bool] = {} | |||
| doorProgress: Dict[tuple[int, int], int] = {} | |||
| hiddenGateState: Dict[tuple[int, int], HiddenGateState] = {} | |||
| class GameInfo: | |||
| @@ -172,6 +203,3 @@ class GameInfo: | |||
| studentQuited: int | |||
| studentScore: int | |||
| trickerScore: int | |||
| gateOpened: bool | |||
| hiddenGateRefreshed: bool | |||
| hiddenGateOpened: bool | |||
| @@ -25,14 +25,20 @@ class AssistFunction(NoInstance): | |||
| return grid // numOfGridPerCell | |||
| @staticmethod | |||
| def HaveView(viewRange: int, x: int, y: int, newX: int, newY: int, myPlace: THUAI6.PlaceType, newPlace: THUAI6.PlaceType, map: List[List[THUAI6.PlaceType]]) -> bool: | |||
| def HaveView(viewRange: int, x: int, y: int, newX: int, newY: int, map: List[List[THUAI6.PlaceType]]) -> bool: | |||
| deltaX: int = newX - x | |||
| deltaY: int = newY - y | |||
| distance: float = deltaX**2 + deltaY**2 | |||
| myPlace = map[AssistFunction.GridToCell( | |||
| x)][AssistFunction.GridToCell(y)] | |||
| newPlace = map[AssistFunction.GridToCell( | |||
| newX)][AssistFunction.GridToCell(newY)] | |||
| if myPlace != THUAI6.PlaceType.Grass and newPlace == THUAI6.PlaceType.Grass: | |||
| return False | |||
| if distance <= viewRange * viewRange: | |||
| divide: int = max(abs(deltaX), abs(deltaY)) // 100 | |||
| if divide == 0: | |||
| return True | |||
| dx: float = deltaX / divide | |||
| dy: float = deltaY / divide | |||
| selfX: float = float(x) | |||
| @@ -67,8 +73,10 @@ class Proto2THUAI6(NoInstance): | |||
| MessageType.GATE: THUAI6.PlaceType.Gate, | |||
| MessageType.HIDDEN_GATE: THUAI6.PlaceType.HiddenGate, | |||
| MessageType.WINDOW: THUAI6.PlaceType.Window, | |||
| MessageType.DOOR: THUAI6.PlaceType.Door, | |||
| } | |||
| MessageType.DOOR3: THUAI6.PlaceType.Door3, | |||
| MessageType.DOOR5: THUAI6.PlaceType.Door5, | |||
| MessageType.DOOR6: THUAI6.PlaceType.Door6, | |||
| MessageType.CHEST: THUAI6.PlaceType.Chest, } | |||
| shapeTypeDict: Final[dict] = { | |||
| MessageType.NULL_SHAPE_TYPE: THUAI6.ShapeType.NullShapeType, | |||
| @@ -77,7 +85,13 @@ class Proto2THUAI6(NoInstance): | |||
| propTypeDict: Final[dict] = { | |||
| MessageType.NULL_PROP_TYPE: THUAI6.PropType.NullPropType, | |||
| MessageType.PTYPE1: THUAI6.PropType.PropType1, } | |||
| MessageType.KEY3: THUAI6.PropType.Key3, | |||
| MessageType.KEY5: THUAI6.PropType.Key5, | |||
| MessageType.KEY6: THUAI6.PropType.Key6, | |||
| MessageType.ADD_SPEED: THUAI6.PropType.AddSpeed, | |||
| MessageType.ADD_HP_OR_AP: THUAI6.PropType.AddHpOrAp, | |||
| MessageType.ADD_LIFE_OR_AP: THUAI6.PropType.AddLifeOrAp, | |||
| MessageType.SHIELD_OR_SPEAR: THUAI6.PropType.ShieldOrSpear, } | |||
| playerTypeDict: Final[dict] = { | |||
| MessageType.NULL_PLAYER_TYPE: THUAI6.PlayerType.NullPlayerType, | |||
| @@ -86,11 +100,11 @@ class Proto2THUAI6(NoInstance): | |||
| studentTypeDict: Final[dict] = { | |||
| MessageType.NULL_STUDENT_TYPE: THUAI6.StudentType.NullStudentType, | |||
| MessageType.STUDENTTYPE1: THUAI6.StudentType.StudentType1, } | |||
| MessageType.ATHLETE: THUAI6.StudentType.Athlete, } | |||
| trickerTypeDict: Final[dict] = { | |||
| MessageType.NULL_TRICKER_TYPE: THUAI6.TrickerType.NullTrickerType, | |||
| MessageType.TRICKERTYPE1: THUAI6.TrickerType.TrickerType1, } | |||
| MessageType.ASSASSIN: THUAI6.TrickerType.Assassin, } | |||
| studentBuffTypeDict: Final[dict] = { | |||
| MessageType.NULL_SBUFF_TYPE: THUAI6.StudentBuffType.NullStudentBuffType, | |||
| @@ -111,7 +125,15 @@ class Proto2THUAI6(NoInstance): | |||
| MessageType.TREATED: THUAI6.PlayerState.Treated, | |||
| MessageType.STUNNED: THUAI6.PlayerState.Stunned, | |||
| MessageType.RESCUING: THUAI6.PlayerState.Rescuing, | |||
| MessageType.TREATING: THUAI6.PlayerState.Treating, } | |||
| MessageType.TREATING: THUAI6.PlayerState.Treating, | |||
| MessageType.SWINGING: THUAI6.PlayerState.Swinging, | |||
| MessageType.ATTACKING: THUAI6.PlayerState.Attacking, | |||
| MessageType.LOCKING: THUAI6.PlayerState.Locking, | |||
| MessageType.RUMMAGING: THUAI6.PlayerState.Rummaging, | |||
| MessageType.CLIMBING: THUAI6.PlayerState.Climbing, | |||
| MessageType.OPENING_A_CHEST: THUAI6.PlayerState.OpeningAChest, | |||
| MessageType.USING_SPECIAL_SKILL: THUAI6.PlayerState.UsingSpecialSkill, | |||
| MessageType.OPENING_A_GATE: THUAI6.PlayerState.OpeningAGate, } | |||
| gameStateDict: Final[dict] = { | |||
| MessageType.NULL_GAME_STATE: THUAI6.GameState.NullGameState, | |||
| @@ -121,24 +143,30 @@ class Proto2THUAI6(NoInstance): | |||
| bulletTypeDict: Final[dict] = { | |||
| MessageType.NULL_BULLET_TYPE: THUAI6.BulletType.NullBulletType, | |||
| MessageType.COMMON_BULLET: THUAI6.BulletType.CommonBullet, | |||
| MessageType.FLYING_KNIFE: THUAI6.BulletType.FlyingKnife, | |||
| MessageType.FAST_BULLET: THUAI6.BulletType.FastBullet, | |||
| MessageType.LINE_BULLET: THUAI6.BulletType.LineBullet, | |||
| MessageType.COMMON_ATTACK_OF_TRICKER: THUAI6.BulletType.CommonAttackOfTricker, | |||
| MessageType.ORDINARY_BULLET: THUAI6.BulletType.OrdinaryBullet, | |||
| MessageType.ATOM_BOMB: THUAI6.BulletType.AtomBomb, } | |||
| # 用于将Proto的对象转为THUAI6的对象 | |||
| @staticmethod | |||
| @ staticmethod | |||
| def Protobuf2THUAI6Tricker(trickerMsg: Message2Clients.MessageOfTricker) -> THUAI6.Tricker: | |||
| tricker = THUAI6.Tricker() | |||
| tricker.x = trickerMsg.x | |||
| tricker.y = trickerMsg.y | |||
| tricker.speed = trickerMsg.speed | |||
| tricker.damage = trickerMsg.damage | |||
| tricker.score = trickerMsg.score | |||
| tricker.facingDirection = trickerMsg.facing_direction | |||
| tricker.trickDesire = trickerMsg.trick_desire | |||
| tricker.classVolume = trickerMsg.class_volume | |||
| tricker.bulletType = Proto2THUAI6.bulletTypeDict[trickerMsg.bullet_type] | |||
| tricker.timeUntilSkillAvailable.clear() | |||
| for time in trickerMsg.time_until_skill_available: | |||
| tricker.timeUntilSkillAvailable.append(time) | |||
| tricker.place = Proto2THUAI6.placeTypeDict[trickerMsg.place] | |||
| tricker.playerState = Proto2THUAI6.playerStateDict[trickerMsg.player_state] | |||
| tricker.prop.clear() | |||
| for item in trickerMsg.prop: | |||
| tricker.prop.append(Proto2THUAI6.propTypeDict[item]) | |||
| tricker.trickerType = Proto2THUAI6.trickerTypeDict[trickerMsg.tricker_type] | |||
| @@ -149,9 +177,10 @@ class Proto2THUAI6(NoInstance): | |||
| tricker.buff.clear() | |||
| for buff in trickerMsg.buff: | |||
| tricker.buff.append(Proto2THUAI6.trickerBuffTypeDict[buff]) | |||
| tricker.playerType = THUAI6.PlayerType.TrickerPlayer | |||
| return tricker | |||
| @staticmethod | |||
| @ staticmethod | |||
| def Protobuf2THUAI6Student(studentMsg: Message2Clients.MessageOfStudent) -> THUAI6.Student: | |||
| student = THUAI6.Student() | |||
| student.x = studentMsg.x | |||
| @@ -159,10 +188,19 @@ class Proto2THUAI6(NoInstance): | |||
| student.speed = studentMsg.speed | |||
| student.determination = studentMsg.determination | |||
| student.addiction = studentMsg.addiction | |||
| student.score = studentMsg.score | |||
| student.facingDirection = studentMsg.facing_direction | |||
| student.bulletType = Proto2THUAI6.bulletTypeDict[studentMsg.bullet_type] | |||
| student.learningSpeed = studentMsg.learning_speed | |||
| student.treatSpeed = studentMsg.treat_speed | |||
| student.treatProgress = studentMsg.treat_progress | |||
| student.rescueProgress = studentMsg.rescue_progress | |||
| student.dangerAlert = studentMsg.danger_alert | |||
| student.timeUntilSkillAvailable.clear() | |||
| for time in studentMsg.time_until_skill_available: | |||
| student.timeUntilSkillAvailable.append(time) | |||
| student.damage = studentMsg.damage | |||
| student.place = Proto2THUAI6.placeTypeDict[studentMsg.place] | |||
| student.prop.clear() | |||
| for item in studentMsg.prop: | |||
| student.prop.append(Proto2THUAI6.propTypeDict[item]) | |||
| student.studentType = Proto2THUAI6.studentTypeDict[studentMsg.student_type] | |||
| @@ -171,23 +209,23 @@ class Proto2THUAI6(NoInstance): | |||
| student.playerID = studentMsg.player_id | |||
| student.viewRange = studentMsg.view_range | |||
| student.radius = studentMsg.radius | |||
| student.buff.clear() | |||
| for buff in studentMsg.buff: | |||
| student.buff.append(Proto2THUAI6.studentBuffTypeDict[buff]) | |||
| student.playerType = THUAI6.PlayerType.StudentPlayer | |||
| return student | |||
| @staticmethod | |||
| @ staticmethod | |||
| def Protobuf2THUAI6Prop(propMsg: Message2Clients.MessageOfProp) -> THUAI6.Prop: | |||
| prop = THUAI6.Prop() | |||
| prop.x = propMsg.x | |||
| prop.y = propMsg.y | |||
| prop.type = Proto2THUAI6.propTypeDict[propMsg.type] | |||
| prop.guid = propMsg.guid | |||
| prop.size = propMsg.size | |||
| prop.facingDirection = propMsg.facing_direction | |||
| prop.isMoving = propMsg.is_moving | |||
| return prop | |||
| @staticmethod | |||
| @ staticmethod | |||
| def Protobuf2THUAI6GameInfo(allMsg: Message2Clients.MessageOfAll): | |||
| gameInfo = THUAI6.GameInfo() | |||
| gameInfo.gameTime = allMsg.game_time | |||
| @@ -196,12 +234,9 @@ class Proto2THUAI6(NoInstance): | |||
| gameInfo.studentQuited = allMsg.student_quited | |||
| gameInfo.studentScore = allMsg.student_score | |||
| gameInfo.trickerScore = allMsg.tricker_score | |||
| gameInfo.gateOpened = allMsg.gate_opened | |||
| gameInfo.hiddenGateOpened = allMsg.hidden_gate_opened | |||
| gameInfo.hiddenGateRefreshed = allMsg.hidden_gate_refreshed | |||
| return gameInfo | |||
| @staticmethod | |||
| @ staticmethod | |||
| def Protobuf2THUAI6Bullet(bulletMsg: Message2Clients.MessageOfBullet) -> THUAI6.Bullet: | |||
| bullet = THUAI6.Bullet() | |||
| bullet.x = bulletMsg.x | |||
| @@ -214,7 +249,7 @@ class Proto2THUAI6(NoInstance): | |||
| bullet.bombRange = bulletMsg.bomb_range | |||
| return bullet | |||
| @staticmethod | |||
| @ staticmethod | |||
| def Protobuf2THUAI6BombedBullet(bulletMsg: Message2Clients.MessageOfBombedBullet) -> THUAI6.BombedBullet: | |||
| bullet = THUAI6.BombedBullet() | |||
| bullet.x = bulletMsg.x | |||
| @@ -225,15 +260,12 @@ class Proto2THUAI6(NoInstance): | |||
| bullet.bombRange = bulletMsg.bomb_range | |||
| return bullet | |||
| @staticmethod | |||
| def Protobuf2THUAI6Map(mapMsg: Message2Clients.MessageOfMap) -> List[List[THUAI6.PlaceType]]: | |||
| map = [] | |||
| for row in mapMsg.row: | |||
| newRow = [] | |||
| for place in row.col: | |||
| newRow.append(Proto2THUAI6.placeTypeDict[place]) | |||
| map.append(newRow) | |||
| return map | |||
| @ staticmethod | |||
| def Bool2HiddenGateState(gateMsg: bool) -> THUAI6.HiddenGateState: | |||
| if gateMsg: | |||
| return THUAI6.HiddenGateState.Opened | |||
| else: | |||
| return THUAI6.HiddenGateState.Refreshed | |||
| class THUAI62Proto(NoInstance): | |||
| @@ -245,7 +277,9 @@ class THUAI62Proto(NoInstance): | |||
| THUAI6.PlaceType.ClassRoom: MessageType.CLASSROOM, | |||
| THUAI6.PlaceType.Gate: MessageType.GATE, | |||
| THUAI6.PlaceType.HiddenGate: MessageType.HIDDEN_GATE, | |||
| THUAI6.PlaceType.Door: MessageType.DOOR, | |||
| THUAI6.PlaceType.Door3: MessageType.DOOR3, | |||
| THUAI6.PlaceType.Door5: MessageType.DOOR5, | |||
| THUAI6.PlaceType.Door6: MessageType.DOOR6, | |||
| THUAI6.PlaceType.Chest: MessageType.CHEST, | |||
| THUAI6.PlaceType.Window: MessageType.WINDOW, } | |||
| @@ -256,38 +290,55 @@ class THUAI62Proto(NoInstance): | |||
| studentTypeDict: Final[dict] = { | |||
| THUAI6.StudentType.NullStudentType: MessageType.NULL_STUDENT_TYPE, | |||
| THUAI6.StudentType.StudentType1: MessageType.STUDENTTYPE1, } | |||
| THUAI6.StudentType.Athlete: MessageType.ATHLETE, } | |||
| trickerTypeDict: Final[dict] = { | |||
| THUAI6.TrickerType.NullTrickerType: MessageType.NULL_TRICKER_TYPE, | |||
| THUAI6.TrickerType.TrickerType1: MessageType.TRICKERTYPE1, } | |||
| THUAI6.TrickerType.Assassin: MessageType.ASSASSIN, } | |||
| propTypeDict: Final[dict] = { | |||
| THUAI6.PropType.NullPropType: MessageType.NULL_PROP_TYPE, | |||
| THUAI6.PropType.PropType1: MessageType.PTYPE1, } | |||
| THUAI6.PropType.Key3: MessageType.KEY3, | |||
| THUAI6.PropType.Key5: MessageType.KEY5, | |||
| THUAI6.PropType.Key6: MessageType.KEY6, | |||
| THUAI6.PropType.AddHpOrAp: MessageType.ADD_HP_OR_AP, | |||
| THUAI6.PropType.AddLifeOrAp: MessageType.ADD_LIFE_OR_AP, | |||
| THUAI6.PropType.AddSpeed: MessageType.ADD_SPEED, | |||
| THUAI6.PropType.ShieldOrSpear: MessageType.SHIELD_OR_SPEAR, } | |||
| # 用于将THUAI6的对象转为Proto的对象 | |||
| @staticmethod | |||
| @ staticmethod | |||
| def THUAI62ProtobufPlayer(playerID: int, playerType: THUAI6.PlayerType, studentType: THUAI6.StudentType, trickerType: THUAI6.TrickerType) -> Message2Server.PlayerMsg: | |||
| return Message2Server.PlayerMsg(player_id=playerID, player_type=THUAI62Proto.playerTypeDict[playerType], student_type=THUAI62Proto.studentTypeDict[studentType], tricker_type=THUAI62Proto.trickerTypeDict[trickerType]) | |||
| if playerType == THUAI6.PlayerType.StudentPlayer: | |||
| return Message2Server.PlayerMsg(player_id=playerID, player_type=MessageType.STUDENT_PLAYER, student_type=THUAI62Proto.studentTypeDict[studentType]) | |||
| else: | |||
| return Message2Server.PlayerMsg(player_id=playerID, player_type=MessageType.TRICKER_PLAYER, tricker_type=THUAI62Proto.trickerTypeDict[trickerType]) | |||
| @staticmethod | |||
| @ staticmethod | |||
| def THUAI62ProtobufID(playerID: int) -> Message2Server.IDMsg: | |||
| return Message2Server.IDMsg(player_id=playerID) | |||
| @staticmethod | |||
| @ staticmethod | |||
| def THUAI62ProtobufMove(time: int, angle: float, id: int) -> Message2Server.MoveMsg: | |||
| return Message2Server.MoveMsg(player_id=id, angle=angle, time_in_milliseconds=time) | |||
| @staticmethod | |||
| def THUAI62ProtobufPick(prop: THUAI6.PropType, id: int) -> Message2Server.PropMsg: | |||
| @ staticmethod | |||
| def THUAI62ProtobufTreatAndRescue(playerID: int, mateID: int) -> Message2Server.TreatAndRescueMsg: | |||
| return Message2Server.TreatAndRescueMsg(player_id=playerID, to_player_id=mateID) | |||
| @ staticmethod | |||
| def THUAI62ProtobufProp(prop: THUAI6.PropType, id: int) -> Message2Server.PropMsg: | |||
| return Message2Server.PropMsg(player_id=id, prop_type=THUAI62Proto.propTypeDict[prop]) | |||
| @staticmethod | |||
| @ staticmethod | |||
| def THUAI62ProtobufSend(msg: str, toID: int, id: int) -> Message2Server.SendMsg: | |||
| return Message2Server.SendMsg(player_id=id, to_player_id=toID, message=msg) | |||
| @staticmethod | |||
| def THUAI62ProtobufTrick(angle: float, id: int) -> Message2Server.AttackMsg: | |||
| @ staticmethod | |||
| def THUAI62ProtobufAttack(angle: float, id: int) -> Message2Server.AttackMsg: | |||
| return Message2Server.AttackMsg(player_id=id, angle=angle) | |||
| @ staticmethod | |||
| def THUAI62ProtobufSkill(skillID: int, id: int) -> Message2Server.SkillMsg: | |||
| return Message2Server.SkillMsg(player_id=id, skill_id=skillID) | |||