diff --git a/CAPI/cpp/API/include/utils.hpp b/CAPI/cpp/API/include/utils.hpp index 05f1443..744e9ab 100644 --- a/CAPI/cpp/API/include/utils.hpp +++ b/CAPI/cpp/API/include/utils.hpp @@ -13,7 +13,7 @@ namespace AssistFunction { - constexpr int numOfGridPerCell = 100; + constexpr int numOfGridPerCell = 1000; [[nodiscard]] constexpr inline int GridToCell(int grid) noexcept { diff --git a/CAPI/cpp/API/src/AI.cpp b/CAPI/cpp/API/src/AI.cpp index 37832d3..386aa90 100644 --- a/CAPI/cpp/API/src/AI.cpp +++ b/CAPI/cpp/API/src/AI.cpp @@ -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) diff --git a/CAPI/cpp/API/src/logic.cpp b/CAPI/cpp/API/src/logic.cpp index b76af9d..36f863e 100644 --- a/CAPI/cpp/API/src/logic.cpp +++ b/CAPI/cpp/API/src/logic.cpp @@ -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(); + currentState->mapInfo = std::make_shared(); + bufferState->gameInfo = std::make_shared(); + bufferState->mapInfo = std::make_shared(); } std::vector> Logic::GetTrickers() const @@ -318,6 +322,8 @@ void Logic::ProcessMessage() std::vector 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)); diff --git a/CAPI/python/PyAPI/AI.py b/CAPI/python/PyAPI/AI.py index fc451d3..5dd375e 100644 --- a/CAPI/python/PyAPI/AI.py +++ b/CAPI/python/PyAPI/AI.py @@ -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 diff --git a/CAPI/python/PyAPI/API.py b/CAPI/python/PyAPI/API.py index 67e8dfd..70c1a38 100644 --- a/CAPI/python/PyAPI/API.py +++ b/CAPI/python/PyAPI/API.py @@ -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) diff --git a/CAPI/python/PyAPI/Communication.py b/CAPI/python/PyAPI/Communication.py index 57b6941..c9abcbd 100644 --- a/CAPI/python/PyAPI/Communication.py +++ b/CAPI/python/PyAPI/Communication.py @@ -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: diff --git a/CAPI/python/PyAPI/DebugAPI.py b/CAPI/python/PyAPI/DebugAPI.py index ebba670..6d09ab9 100644 --- a/CAPI/python/PyAPI/DebugAPI.py +++ b/CAPI/python/PyAPI/DebugAPI.py @@ -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) diff --git a/CAPI/python/PyAPI/Interface.py b/CAPI/python/PyAPI/Interface.py index e828821..21651f6 100644 --- a/CAPI/python/PyAPI/Interface.py +++ b/CAPI/python/PyAPI/Interface.py @@ -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 diff --git a/CAPI/python/PyAPI/State.py b/CAPI/python/PyAPI/State.py index eb80a3b..f2eb339 100644 --- a/CAPI/python/PyAPI/State.py +++ b/CAPI/python/PyAPI/State.py @@ -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] = [] diff --git a/CAPI/python/PyAPI/logic.py b/CAPI/python/PyAPI/logic.py index da5aa89..3c8b44a 100644 --- a/CAPI/python/PyAPI/logic.py +++ b/CAPI/python/PyAPI/logic.py @@ -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) diff --git a/CAPI/python/PyAPI/main.py b/CAPI/python/PyAPI/main.py index 46e8ef9..6705a6f 100644 --- a/CAPI/python/PyAPI/main.py +++ b/CAPI/python/PyAPI/main.py @@ -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 diff --git a/CAPI/python/PyAPI/structures.py b/CAPI/python/PyAPI/structures.py index 1c8ae05..d43f5e1 100644 --- a/CAPI/python/PyAPI/structures.py +++ b/CAPI/python/PyAPI/structures.py @@ -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 diff --git a/CAPI/python/PyAPI/utils.py b/CAPI/python/PyAPI/utils.py index d320ef9..737acb4 100644 --- a/CAPI/python/PyAPI/utils.py +++ b/CAPI/python/PyAPI/utils.py @@ -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)