feat(CAPI): ✨ add some missing interfaces
tags/0.1.0
| @@ -35,6 +35,7 @@ public: | |||
| [[nodiscard]] virtual std::vector<std::shared_ptr<const THUAI6::Tricker>> GetTrickers() const = 0; | |||
| [[nodiscard]] virtual std::vector<std::shared_ptr<const THUAI6::Student>> GetStudents() const = 0; | |||
| [[nodiscard]] virtual std::vector<std::shared_ptr<const THUAI6::Prop>> GetProps() const = 0; | |||
| [[nodiscard]] virtual std::vector<std::shared_ptr<const THUAI6::Bullet>> GetBullets() const = 0; | |||
| [[nodiscard]] virtual std::shared_ptr<const THUAI6::Student> StudentGetSelfInfo() const = 0; | |||
| [[nodiscard]] virtual std::shared_ptr<const THUAI6::Tricker> TrickerGetSelfInfo() const = 0; | |||
| @@ -54,6 +55,7 @@ public: | |||
| virtual bool Move(int64_t time, double angle) = 0; | |||
| virtual bool PickProp(THUAI6::PropType prop) = 0; | |||
| virtual bool UseProp(THUAI6::PropType prop) = 0; | |||
| virtual bool ThrowProp(THUAI6::PropType prop) = 0; | |||
| virtual bool UseSkill(int32_t skillID) = 0; | |||
| virtual bool SendMessage(int64_t toID, std::string message) = 0; | |||
| virtual bool HaveMessage() = 0; | |||
| @@ -99,6 +101,7 @@ public: | |||
| // 捡道具、使用技能 | |||
| virtual std::future<bool> PickProp(THUAI6::PropType prop) = 0; | |||
| virtual std::future<bool> UseProp(THUAI6::PropType prop) = 0; | |||
| virtual std::future<bool> ThrowProp(THUAI6::PropType prop) = 0; | |||
| virtual std::future<bool> UseSkill(int32_t skillID) = 0; | |||
| virtual std::future<bool> Attack(double angleInRadian) = 0; | |||
| @@ -124,7 +127,9 @@ public: | |||
| // 获取视野内可见的道具信息 | |||
| [[nodiscard]] virtual std::vector<std::shared_ptr<const THUAI6::Prop>> GetProps() const = 0; | |||
| // 获取地图信息,视野外的地图统一为Land | |||
| // 获取视野内可见的子弹信息 | |||
| [[nodiscard]] virtual std::vector<std::shared_ptr<const THUAI6::Bullet>> GetBullets() const = 0; | |||
| [[nodiscard]] virtual std::vector<std::vector<THUAI6::PlaceType>> GetFullMap() const = 0; | |||
| [[nodiscard]] virtual THUAI6::PlaceType GetPlaceType(int32_t cellX, int32_t cellY) const = 0; | |||
| @@ -221,6 +226,7 @@ public: | |||
| std::future<bool> PickProp(THUAI6::PropType prop) override; | |||
| std::future<bool> UseProp(THUAI6::PropType prop) override; | |||
| std::future<bool> ThrowProp(THUAI6::PropType prop) override; | |||
| std::future<bool> UseSkill(int32_t skillID) override; | |||
| std::future<bool> Attack(double angleInRadian) override; | |||
| @@ -243,6 +249,8 @@ public: | |||
| [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Prop>> GetProps() const override; | |||
| [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Bullet>> GetBullets() const override; | |||
| [[nodiscard]] std::vector<std::vector<THUAI6::PlaceType>> GetFullMap() const override; | |||
| [[nodiscard]] THUAI6::PlaceType GetPlaceType(int32_t cellX, int32_t cellY) const override; | |||
| @@ -308,6 +316,7 @@ public: | |||
| std::future<bool> PickProp(THUAI6::PropType prop) override; | |||
| std::future<bool> UseProp(THUAI6::PropType prop) override; | |||
| std::future<bool> ThrowProp(THUAI6::PropType prop) override; | |||
| std::future<bool> UseSkill(int32_t skillID) override; | |||
| std::future<bool> OpenDoor() override; | |||
| @@ -328,6 +337,8 @@ public: | |||
| [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Prop>> GetProps() const override; | |||
| [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Bullet>> GetBullets() const override; | |||
| [[nodiscard]] std::vector<std::vector<THUAI6::PlaceType>> GetFullMap() const override; | |||
| [[nodiscard]] THUAI6::PlaceType GetPlaceType(int32_t cellX, int32_t cellY) const override; | |||
| @@ -383,6 +394,7 @@ public: | |||
| std::future<bool> PickProp(THUAI6::PropType prop) override; | |||
| std::future<bool> UseProp(THUAI6::PropType prop) override; | |||
| std::future<bool> ThrowProp(THUAI6::PropType prop) override; | |||
| std::future<bool> UseSkill(int32_t skillID) override; | |||
| std::future<bool> Attack(double angleInRadian) override; | |||
| @@ -405,6 +417,8 @@ public: | |||
| [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Prop>> GetProps() const override; | |||
| [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Bullet>> GetBullets() const override; | |||
| [[nodiscard]] std::vector<std::vector<THUAI6::PlaceType>> GetFullMap() const override; | |||
| [[nodiscard]] THUAI6::PlaceType GetPlaceType(int32_t cellX, int32_t cellY) const override; | |||
| @@ -455,6 +469,7 @@ public: | |||
| std::future<bool> PickProp(THUAI6::PropType prop) override; | |||
| std::future<bool> UseProp(THUAI6::PropType prop) override; | |||
| std::future<bool> ThrowProp(THUAI6::PropType prop) override; | |||
| std::future<bool> UseSkill(int32_t skillID) override; | |||
| std::future<bool> OpenDoor() override; | |||
| @@ -475,6 +490,8 @@ public: | |||
| [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Prop>> GetProps() const override; | |||
| [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Bullet>> GetBullets() const override; | |||
| [[nodiscard]] std::vector<std::vector<THUAI6::PlaceType>> GetFullMap() const override; | |||
| [[nodiscard]] THUAI6::PlaceType GetPlaceType(int32_t cellX, int32_t cellY) const override; | |||
| @@ -26,6 +26,7 @@ public: | |||
| bool Move(int64_t time, double angle, int64_t playerID); | |||
| bool PickProp(THUAI6::PropType prop, int64_t playerID); | |||
| bool UseProp(THUAI6::PropType prop, int64_t playerID); | |||
| bool ThrowProp(THUAI6::PropType prop, int64_t playerID); | |||
| bool UseSkill(int32_t skillID, int64_t playerID); | |||
| bool SendMessage(int64_t toID, std::string message, int64_t playerID); | |||
| bool OpenDoor(int64_t playerID); | |||
| @@ -94,6 +94,7 @@ private: | |||
| [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Tricker>> GetTrickers() const override; | |||
| [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Student>> GetStudents() const override; | |||
| [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Prop>> GetProps() const override; | |||
| [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Bullet>> GetBullets() const override; | |||
| [[nodiscard]] std::shared_ptr<const THUAI6::Student> StudentGetSelfInfo() const override; | |||
| [[nodiscard]] std::shared_ptr<const THUAI6::Tricker> TrickerGetSelfInfo() const override; | |||
| [[nodiscard]] THUAI6::HiddenGateState GetHiddenGateState(int32_t cellX, int32_t cellY) const override; | |||
| @@ -113,6 +114,7 @@ private: | |||
| bool Move(int64_t time, double angle) override; | |||
| bool PickProp(THUAI6::PropType prop) override; | |||
| bool UseProp(THUAI6::PropType prop) override; | |||
| bool ThrowProp(THUAI6::PropType prop) override; | |||
| bool UseSkill(int32_t skillID) override; | |||
| bool SendMessage(int64_t toID, std::string message) override; | |||
| @@ -89,6 +89,18 @@ std::future<bool> TrickerAPI::UseProp(THUAI6::PropType prop) | |||
| { return logic.UseProp(prop); }); | |||
| } | |||
| std::future<bool> StudentAPI::ThrowProp(THUAI6::PropType prop) | |||
| { | |||
| return std::async(std::launch::async, [=]() | |||
| { return logic.ThrowProp(prop); }); | |||
| } | |||
| std::future<bool> TrickerAPI::ThrowProp(THUAI6::PropType prop) | |||
| { | |||
| return std::async(std::launch::async, [=]() | |||
| { return logic.ThrowProp(prop); }); | |||
| } | |||
| std::future<bool> StudentAPI::UseSkill(int32_t skillID) | |||
| { | |||
| return std::async(std::launch::async, [=]() | |||
| @@ -255,6 +267,16 @@ std::vector<std::shared_ptr<const THUAI6::Prop>> TrickerAPI::GetProps() const | |||
| return logic.GetProps(); | |||
| } | |||
| std::vector<std::shared_ptr<const THUAI6::Bullet>> StudentAPI::GetBullets() const | |||
| { | |||
| return logic.GetBullets(); | |||
| } | |||
| std::vector<std::shared_ptr<const THUAI6::Bullet>> TrickerAPI::GetBullets() const | |||
| { | |||
| return logic.GetBullets(); | |||
| } | |||
| std::vector<std::vector<THUAI6::PlaceType>> StudentAPI::GetFullMap() const | |||
| { | |||
| return logic.GetFullMap(); | |||
| @@ -51,6 +51,18 @@ bool Communication::UseProp(THUAI6::PropType prop, int64_t playerID) | |||
| return false; | |||
| } | |||
| bool Communication::ThrowProp(THUAI6::PropType prop, int64_t playerID) | |||
| { | |||
| protobuf::BoolRes throwPropResult; | |||
| ClientContext context; | |||
| auto request = THUAI62Proto::THUAI62ProtobufProp(prop, playerID); | |||
| auto status = THUAI6Stub->ThrowProp(&context, request, &throwPropResult); | |||
| if (status.ok()) | |||
| return throwPropResult.act_success(); | |||
| else | |||
| return false; | |||
| } | |||
| bool Communication::UseSkill(int32_t skillID, int64_t playerID) | |||
| { | |||
| protobuf::BoolRes useSkillResult; | |||
| @@ -187,6 +187,26 @@ std::future<bool> TrickerDebugAPI::UseProp(THUAI6::PropType prop) | |||
| return result; }); | |||
| } | |||
| std::future<bool> StudentDebugAPI::ThrowProp(THUAI6::PropType prop) | |||
| { | |||
| logger->info("ThrowProp: prop={}, called at {}ms", THUAI6::propTypeDict[prop], Time::TimeSinceStart(startPoint)); | |||
| return std::async(std::launch::async, [=]() | |||
| { auto result = logic.ThrowProp(prop); | |||
| if (!result) | |||
| logger->warn("ThrowProp: failed at {}ms", Time::TimeSinceStart(startPoint)); | |||
| return result; }); | |||
| } | |||
| std::future<bool> TrickerDebugAPI::ThrowProp(THUAI6::PropType prop) | |||
| { | |||
| logger->info("ThrowProp: prop={}, called at {}ms", THUAI6::propTypeDict[prop], Time::TimeSinceStart(startPoint)); | |||
| return std::async(std::launch::async, [=]() | |||
| { auto result = logic.ThrowProp(prop); | |||
| if (!result) | |||
| logger->warn("ThrowProp: failed at {}ms", Time::TimeSinceStart(startPoint)); | |||
| return result; }); | |||
| } | |||
| std::future<bool> StudentDebugAPI::UseSkill(int32_t skillID) | |||
| { | |||
| logger->info("UseSkill: skillID={}, called at {}ms", skillID, Time::TimeSinceStart(startPoint)); | |||
| @@ -435,6 +455,16 @@ std::vector<std::shared_ptr<const THUAI6::Prop>> TrickerDebugAPI::GetProps() con | |||
| return logic.GetProps(); | |||
| } | |||
| std::vector<std::shared_ptr<const THUAI6::Bullet>> StudentDebugAPI::GetBullets() const | |||
| { | |||
| return logic.GetBullets(); | |||
| } | |||
| std::vector<std::shared_ptr<const THUAI6::Bullet>> TrickerDebugAPI::GetBullets() const | |||
| { | |||
| return logic.GetBullets(); | |||
| } | |||
| std::vector<std::vector<THUAI6::PlaceType>> StudentDebugAPI::GetFullMap() const | |||
| { | |||
| return logic.GetFullMap(); | |||
| @@ -51,6 +51,15 @@ std::vector<std::shared_ptr<const THUAI6::Prop>> Logic::GetProps() const | |||
| return temp; | |||
| } | |||
| std::vector<std::shared_ptr<const THUAI6::Bullet>> Logic::GetBullets() const | |||
| { | |||
| std::unique_lock<std::mutex> lock(mtxState); | |||
| std::vector<std::shared_ptr<const THUAI6::Bullet>> temp; | |||
| temp.assign(currentState->bullets.begin(), currentState->bullets.end()); | |||
| logger->debug("Called GetBullets"); | |||
| return temp; | |||
| } | |||
| std::shared_ptr<const THUAI6::Student> Logic::StudentGetSelfInfo() const | |||
| { | |||
| std::unique_lock<std::mutex> lock(mtxState); | |||
| @@ -193,6 +202,12 @@ bool Logic::UseProp(THUAI6::PropType prop) | |||
| return pComm->UseProp(prop, playerID); | |||
| } | |||
| bool Logic::ThrowProp(THUAI6::PropType prop) | |||
| { | |||
| logger->debug("Called ThrowProp"); | |||
| return pComm->ThrowProp(prop, playerID); | |||
| } | |||
| bool Logic::UseSkill(int32_t skill) | |||
| { | |||
| logger->debug("Called UseSkill"); | |||
| @@ -528,6 +543,15 @@ void Logic::LoadBuffer(protobuf::MessageToClient& message) | |||
| } | |||
| case THUAI6::MessageOfObj::TrickerMessage: | |||
| { | |||
| bool flag = false; | |||
| for (int i = 0; i < item.tricker_message().buff_size(); i++) | |||
| if (Proto2THUAI6::trickerBuffTypeDict[item.tricker_message().buff(i)] == THUAI6::TrickerBuffType::Invisible) | |||
| { | |||
| flag = true; | |||
| break; | |||
| } | |||
| if (flag) | |||
| break; | |||
| if (AssistFunction::HaveView(bufferState->studentSelf->viewRange, bufferState->studentSelf->x, bufferState->studentSelf->y, item.tricker_message().x(), item.tricker_message().y(), bufferState->gameMap)) | |||
| { | |||
| bufferState->trickers.push_back(Proto2THUAI6::Protobuf2THUAI6Tricker(item.tricker_message())); | |||
| @@ -674,6 +698,15 @@ void Logic::LoadBuffer(protobuf::MessageToClient& message) | |||
| } | |||
| case THUAI6::MessageOfObj::StudentMessage: | |||
| { | |||
| bool flag = false; | |||
| for (int i = 0; i < item.student_message().buff_size(); i++) | |||
| if (Proto2THUAI6::studentBuffTypeDict[item.student_message().buff(i)] == THUAI6::StudentBuffType::Invisible) | |||
| { | |||
| flag = true; | |||
| break; | |||
| } | |||
| if (flag) | |||
| break; | |||
| if (AssistFunction::HaveView(bufferState->trickerSelf->viewRange, bufferState->trickerSelf->x, bufferState->trickerSelf->y, item.student_message().x(), item.student_message().y(), bufferState->gameMap)) | |||
| { | |||
| bufferState->students.push_back(Proto2THUAI6::Protobuf2THUAI6Student(item.student_message())); | |||
| @@ -1,6 +1,7 @@ | |||
| import PyAPI.structures as THUAI6 | |||
| from PyAPI.Interface import IStudentAPI, ITrickerAPI, IAI | |||
| from typing import Union, Final, cast | |||
| import queue | |||
| import time | |||
| @@ -9,7 +10,7 @@ class Setting: | |||
| # 为假则play()期间确保游戏状态不更新,为真则只保证游戏状态在调用相关方法时不更新 | |||
| @staticmethod | |||
| def asynchronous() -> bool: | |||
| return False | |||
| return True | |||
| # 选手必须修改该函数的返回值来选择自己的阵营 | |||
| @staticmethod | |||
| @@ -41,50 +42,109 @@ class AssistFunction: | |||
| return grid // numOfGridPerCell | |||
| arrive: bool = False | |||
| path = [] | |||
| cur = 0 | |||
| fixedclass = [] | |||
| class AI(IAI): | |||
| # 选手在这里实现自己的逻辑,要求和上面选择的阵营保持一致 | |||
| def StudentPlay(self, api: IStudentAPI) -> None: | |||
| api.Attack(float('nan')) | |||
| time.sleep(0.5) | |||
| api.PrintSelfInfo() | |||
| # api.SendMessage(4, "Hello World!") | |||
| # api.PrintSelfInfo() | |||
| # global arrive | |||
| # if not arrive: | |||
| # if api.GetSelfInfo().x < 25500: | |||
| # api.MoveDown(50) | |||
| # global fixedclass | |||
| # selfInfo = api.GetSelfInfo() | |||
| # available = [THUAI6.PlaceType.Land, | |||
| # THUAI6.PlaceType.Grass, THUAI6.PlaceType.Door3, THUAI6.PlaceType.Door6, THUAI6.PlaceType.Door5, THUAI6.PlaceType.Gate] | |||
| # def bfs(x, y): | |||
| # if api.GetPlaceType(x, y) not in available: | |||
| # return [] | |||
| # def GetSuccessors(x, y): | |||
| # successors = [] | |||
| # if x > 0 and api.GetPlaceType(x - 1, y) in available: | |||
| # successors.append((x - 1, y)) | |||
| # if x < 49 and api.GetPlaceType(x + 1, y) in available: | |||
| # successors.append((x + 1, y)) | |||
| # if y > 0 and api.GetPlaceType(x, y - 1) in available: | |||
| # successors.append((x, y - 1)) | |||
| # if y < 49 and api.GetPlaceType(x, y + 1) in available: | |||
| # successors.append((x, y + 1)) | |||
| # return successors | |||
| # selfX = AssistFunction.GridToCell(api.GetSelfInfo().x) | |||
| # selfY = AssistFunction.GridToCell(api.GetSelfInfo().y) | |||
| # frontier = queue.Queue() | |||
| # frontier.put((selfX, selfY, [])) | |||
| # visited = [] | |||
| # while not frontier.empty(): | |||
| # currentX, currentY, path = frontier.get() | |||
| # if currentX == x and currentY == y: | |||
| # return path | |||
| # for nextX, nextY in GetSuccessors(currentX, currentY): | |||
| # if (nextX, nextY) not in visited: | |||
| # visited.append((nextX, nextY)) | |||
| # frontier.put((nextX, nextY, path + [(nextX, nextY)])) | |||
| # return [] | |||
| # def GoTo(x, y): | |||
| # global path, cur | |||
| # if path != [] and cur < len(path): | |||
| # selfX = api.GetSelfInfo().x | |||
| # selfY = api.GetSelfInfo().y | |||
| # nextX, nextY = path[cur] | |||
| # nextX = AssistFunction.CellToGrid(nextX) | |||
| # nextY = AssistFunction.CellToGrid(nextY) | |||
| # if selfX < nextX - 100: | |||
| # api.MoveDown(10) | |||
| # time.sleep(0.01) | |||
| # return | |||
| # if selfX > nextX + 100: | |||
| # api.MoveUp(10) | |||
| # time.sleep(0.01) | |||
| # return | |||
| # if selfY < nextY - 100: | |||
| # api.MoveRight(10) | |||
| # time.sleep(0.01) | |||
| # return | |||
| # if selfY > nextY + 100: | |||
| # api.MoveLeft(10) | |||
| # time.sleep(0.01) | |||
| # return | |||
| # cur += 1 | |||
| # return | |||
| # if api.GetSelfInfo().y > 10500: | |||
| # api.MoveLeft(50) | |||
| # else: | |||
| # path = bfs(x, y) | |||
| # cur = 0 | |||
| # return | |||
| # arrive = True | |||
| # else: | |||
| # api.SkipWindow() | |||
| # # time.sleep(1) | |||
| # api.PrintSelfInfo() | |||
| # if api.GetSelfInfo().y < 18500: | |||
| # api.MoveRight(50) | |||
| # if (AssistFunction.GridToCell(api.GetSelfInfo().x), AssistFunction.GridToCell(api.GetSelfInfo().y)) == (6, 6) and api.GetGateProgress(5, 6) < 18000: | |||
| # api.StartOpenGate() | |||
| # return | |||
| # api.StartLearning() | |||
| # if api.GetSelfInfo().y > 7000: | |||
| # api.MoveLeft(50) | |||
| # return | |||
| # if api.GetSelfInfo().x > 20500: | |||
| # api.MoveUp(50) | |||
| # if (AssistFunction.GridToCell(api.GetSelfInfo().x), AssistFunction.GridToCell(api.GetSelfInfo().y)) == (6, 6) and api.GetGateProgress(5, 6) >= 18000: | |||
| # api.Graduate() | |||
| # return | |||
| # if api.GetSelfInfo().y > 4500: | |||
| # api.MoveLeft(50) | |||
| # if len(fixedclass) == 7: | |||
| # GoTo(6, 6) | |||
| # return | |||
| # if api.GetPlaceType(AssistFunction.GridToCell(api.GetSelfInfo().x) + 1, AssistFunction.GridToCell(api.GetSelfInfo().y)) == THUAI6.PlaceType.ClassRoom: | |||
| # api.Print("Trying to fix!") | |||
| # if api.GetClassroomProgress(AssistFunction.GridToCell(api.GetSelfInfo().x) + 1, AssistFunction.GridToCell(api.GetSelfInfo().y)) < 103000: | |||
| # api.StartLearning() | |||
| # return | |||
| # else: | |||
| # if (AssistFunction.GridToCell(api.GetSelfInfo().x) + 1, AssistFunction.GridToCell(api.GetSelfInfo().y)) not in fixedclass: | |||
| # fixedclass.append( | |||
| # (AssistFunction.GridToCell(api.GetSelfInfo().x) + 1, AssistFunction.GridToCell(api.GetSelfInfo().y))) | |||
| # for i in range(50): | |||
| # for j in range(50): | |||
| # if api.GetPlaceType(i, j) == THUAI6.PlaceType.ClassRoom and (i, j) not in fixedclass: | |||
| # if api.GetPlaceType(i - 1, j) in available: | |||
| # GoTo(i - 1, j) | |||
| # return | |||
| api.PrintTricker() | |||
| return | |||
| def TrickerPlay(self, api: ITrickerAPI) -> None: | |||
| return | |||
| @@ -41,6 +41,9 @@ class StudentAPI(IStudentAPI, IGameTimer): | |||
| def UseProp(self, propType: THUAI6.PropType) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.UseProp, propType) | |||
| def ThrowProp(self, propType: THUAI6.PropType) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.ThrowProp, propType) | |||
| def UseSkill(self, skillID: int) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.UseSkill, skillID) | |||
| @@ -99,6 +102,9 @@ class StudentAPI(IStudentAPI, IGameTimer): | |||
| def GetProps(self) -> List[THUAI6.Prop]: | |||
| return self.__logic.GetProps() | |||
| def GetBullets(self) -> List[THUAI6.Bullet]: | |||
| return self.__logic.GetBullets() | |||
| def GetFullMap(self) -> List[List[THUAI6.PlaceType]]: | |||
| return self.__logic.GetFullMap() | |||
| @@ -208,6 +214,9 @@ class TrickerAPI(ITrickerAPI, IGameTimer): | |||
| def UseProp(self, propType: THUAI6.PropType) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.UseProp, propType) | |||
| def ThrowProp(self, propType: THUAI6.PropType) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.ThrowProp, propType) | |||
| def UseSkill(self, skillID: int) -> Future[bool]: | |||
| return self.__pool.submit(self.__logic.UseSkill, skillID) | |||
| @@ -266,6 +275,9 @@ class TrickerAPI(ITrickerAPI, IGameTimer): | |||
| def GetProps(self) -> List[THUAI6.Prop]: | |||
| return self.__logic.GetProps() | |||
| def GetBullets(self) -> List[THUAI6.Bullet]: | |||
| return self.__logic.GetBullets() | |||
| def GetFullMap(self) -> List[List[THUAI6.PlaceType]]: | |||
| return self.__logic.GetFullMap() | |||
| @@ -48,7 +48,7 @@ class Communication: | |||
| else: | |||
| return pickResult.act_success | |||
| def UseProp(self, propType: THUAI6.PropType, playerID: int): | |||
| def UseProp(self, propType: THUAI6.PropType, playerID: int) -> bool: | |||
| try: | |||
| useResult = self.__THUAI6Stub.UseProp( | |||
| THUAI62Proto.THUAI62ProtobufProp(propType, playerID)) | |||
| @@ -57,6 +57,15 @@ class Communication: | |||
| else: | |||
| return useResult.act_success | |||
| def ThrowProp(self, propType: THUAI6.PropType, playerID: int) -> bool: | |||
| try: | |||
| throwResult = self.__THUAI6Stub.ThrowProp( | |||
| THUAI62Proto.THUAI62ProtobufProp(propType, playerID)) | |||
| except grpc.RpcError as e: | |||
| return False | |||
| else: | |||
| return throwResult.act_success | |||
| def UseSkill(self, skillID: int, playerID: int) -> bool: | |||
| try: | |||
| useResult = self.__THUAI6Stub.UseSkill( | |||
| @@ -109,6 +109,19 @@ class StudentDebugAPI(IStudentAPI, IGameTimer): | |||
| return self.__pool.submit(logUse) | |||
| def ThrowProp(self, propType: THUAI6.PropType) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"ThrowProp: prop = {propType.name}, called at {self.__GetTime()}ms") | |||
| def logThrow() -> bool: | |||
| result = self.__logic.ThrowProp(propType) | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"ThrowProp: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logThrow) | |||
| def UseSkill(self, skillID: int) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"UseSkill: skillID = {skillID}, called at {self.__GetTime()}ms") | |||
| @@ -261,6 +274,9 @@ class StudentDebugAPI(IStudentAPI, IGameTimer): | |||
| def GetProps(self) -> List[THUAI6.Prop]: | |||
| return self.__logic.GetProps() | |||
| def GetBullets(self) -> List[THUAI6.Bullet]: | |||
| return self.__logic.GetBullets() | |||
| def GetFullMap(self) -> List[List[THUAI6.PlaceType]]: | |||
| return self.__logic.GetFullMap() | |||
| @@ -545,6 +561,19 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||
| return self.__pool.submit(logUse) | |||
| def ThrowProp(self, propType: THUAI6.PropType) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"ThrowProp: prop = {propType.name}, called at {self.__GetTime()}ms") | |||
| def logThrow() -> bool: | |||
| result = self.__logic.ThrowProp(propType) | |||
| if not result: | |||
| self.__logger.warning( | |||
| f"ThrowProp: failed at {self.__GetTime()}ms") | |||
| return result | |||
| return self.__pool.submit(logThrow) | |||
| def UseSkill(self, skillID: int) -> Future[bool]: | |||
| self.__logger.info( | |||
| f"UseSkill: skillID = {skillID}, called at {self.__GetTime()}ms") | |||
| @@ -697,6 +726,9 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||
| def GetProps(self) -> List[THUAI6.Prop]: | |||
| return self.__logic.GetProps() | |||
| def GetBullets(self) -> List[THUAI6.Bullet]: | |||
| return self.__logic.GetBullets() | |||
| def GetFullMap(self) -> List[List[THUAI6.PlaceType]]: | |||
| return self.__logic.GetFullMap() | |||
| @@ -20,6 +20,10 @@ class ILogic(metaclass=ABCMeta): | |||
| def GetProps(self) -> List[THUAI6.Prop]: | |||
| pass | |||
| @abstractmethod | |||
| def GetBullets(self) -> List[THUAI6.Bullet]: | |||
| pass | |||
| @abstractmethod | |||
| def GetSelfInfo(self) -> Union[THUAI6.Student, THUAI6.Tricker]: | |||
| pass | |||
| @@ -72,6 +76,10 @@ class ILogic(metaclass=ABCMeta): | |||
| def UseProp(self, propType: THUAI6.PropType) -> bool: | |||
| pass | |||
| @abstractmethod | |||
| def ThrowProp(self, propType: THUAI6.PropType) -> bool: | |||
| pass | |||
| @abstractmethod | |||
| def UseSkill(self, skillID: int) -> bool: | |||
| pass | |||
| @@ -184,6 +192,10 @@ class IAPI(metaclass=ABCMeta): | |||
| def UseProp(self, propType: THUAI6.PropType) -> Future[bool]: | |||
| pass | |||
| @abstractmethod | |||
| def ThrowProp(self, propType: THUAI6.PropType) -> Future[bool]: | |||
| pass | |||
| @abstractmethod | |||
| def UseSkill(self, skillID: int) -> Future[bool]: | |||
| pass | |||
| @@ -258,6 +270,10 @@ class IAPI(metaclass=ABCMeta): | |||
| def GetProps(self) -> List[THUAI6.Prop]: | |||
| pass | |||
| @abstractmethod | |||
| def GetBullets(self) -> List[THUAI6.Bullet]: | |||
| pass | |||
| @abstractmethod | |||
| def GetSelfInfo(self) -> Union[THUAI6.Student, THUAI6.Tricker]: | |||
| pass | |||
| @@ -2,6 +2,7 @@ import os | |||
| from typing import List, Union, Callable, Tuple | |||
| import threading | |||
| import logging | |||
| import copy | |||
| import proto.MessageType_pb2 as MessageType | |||
| import proto.Message2Server_pb2 as Message2Server | |||
| import proto.Message2Clients_pb2 as Message2Clients | |||
| @@ -71,27 +72,32 @@ class Logic(ILogic): | |||
| def GetTrickers(self) -> List[THUAI6.Tricker]: | |||
| with self.__mtxState: | |||
| self.__logger.debug("Called GetTrickers") | |||
| return self.__currentState.trickers | |||
| return copy.deepcopy(self.__currentState.trickers) | |||
| def GetStudents(self) -> List[THUAI6.Student]: | |||
| with self.__mtxState: | |||
| self.__logger.debug("Called GetStudents") | |||
| return self.__currentState.students | |||
| return copy.deepcopy(self.__currentState.students) | |||
| def GetProps(self) -> List[THUAI6.Prop]: | |||
| with self.__mtxState: | |||
| self.__logger.debug("Called GetProps") | |||
| return self.__currentState.props | |||
| return copy.deepcopy(self.__currentState.props) | |||
| def GetBullets(self) -> List[THUAI6.Bullet]: | |||
| with self.__mtxState: | |||
| self.__logger.debug("Called GetBullets") | |||
| return copy.deepcopy(self.__currentState.bullets) | |||
| def GetSelfInfo(self) -> Union[THUAI6.Student, THUAI6.Tricker]: | |||
| with self.__mtxState: | |||
| self.__logger.debug("Called GetSelfInfo") | |||
| return self.__currentState.self | |||
| return copy.deepcopy(self.__currentState.self) | |||
| def GetFullMap(self) -> List[List[THUAI6.PlaceType]]: | |||
| with self.__mtxState: | |||
| self.__logger.debug("Called GetFullMap") | |||
| return self.__currentState.gameMap | |||
| return copy.deepcopy(self.__currentState.gameMap) | |||
| def GetPlaceType(self, x: int, y: int) -> THUAI6.PlaceType: | |||
| with self.__mtxState: | |||
| @@ -99,13 +105,13 @@ class Logic(ILogic): | |||
| self.__logger.warning("Invalid position") | |||
| return THUAI6.PlaceType.NullPlaceType | |||
| self.__logger.debug("Called GetPlaceType") | |||
| return self.__currentState.gameMap[x][y] | |||
| return copy.deepcopy(self.__currentState.gameMap[x][y]) | |||
| def IsDoorOpen(self, x: int, y: int) -> bool: | |||
| with self.__mtxState: | |||
| self.__logger.debug("Called IsDoorOpen") | |||
| if (x, y) in self.__currentState.mapInfo.doorState: | |||
| return self.__currentState.mapInfo.doorState[(x, y)] | |||
| return copy.deepcopy(self.__currentState.mapInfo.doorState[(x, y)]) | |||
| else: | |||
| self.__logger.warning("Door not found") | |||
| return False | |||
| @@ -114,7 +120,7 @@ class Logic(ILogic): | |||
| with self.__mtxState: | |||
| self.__logger.debug("Called GetClassroomProgress") | |||
| if (x, y) in self.__currentState.mapInfo.classroomState: | |||
| return self.__currentState.mapInfo.classroomState[(x, y)] | |||
| return copy.deepcopy(self.__currentState.mapInfo.classroomState[(x, y)]) | |||
| else: | |||
| self.__logger.warning("Classroom not found") | |||
| return 0 | |||
| @@ -123,7 +129,7 @@ class Logic(ILogic): | |||
| with self.__mtxState: | |||
| self.__logger.debug("Called GetChestProgress") | |||
| if (x, y) in self.__currentState.mapInfo.chestState: | |||
| return self.__currentState.mapInfo.chestState[(x, y)] | |||
| return copy.deepcopy(self.__currentState.mapInfo.chestState[(x, y)]) | |||
| else: | |||
| self.__logger.warning("Chest not found") | |||
| return 0 | |||
| @@ -132,7 +138,7 @@ class Logic(ILogic): | |||
| with self.__mtxState: | |||
| self.__logger.debug("Called GetGateProgress") | |||
| if (x, y) in self.__currentState.mapInfo.gateState: | |||
| return self.__currentState.mapInfo.gateState[(x, y)] | |||
| return copy.deepcopy(self.__currentState.mapInfo.gateState[(x, y)]) | |||
| else: | |||
| self.__logger.warning("Gate not found") | |||
| return 0 | |||
| @@ -141,7 +147,7 @@ class Logic(ILogic): | |||
| with self.__mtxState: | |||
| self.__logger.debug("Called GetHiddenGateState") | |||
| if (x, y) in self.__currentState.mapInfo.hiddenGateState: | |||
| return self.__currentState.mapInfo.hiddenGateState[(x, y)] | |||
| return copy.deepcopy(self.__currentState.mapInfo.hiddenGateState[(x, y)]) | |||
| else: | |||
| self.__logger.warning("HiddenGate not found") | |||
| return THUAI6.HiddenGateState.Null | |||
| @@ -150,7 +156,7 @@ class Logic(ILogic): | |||
| with self.__mtxState: | |||
| self.__logger.debug("Called GetDoorProgress") | |||
| if (x, y) in self.__currentState.mapInfo.doorProgress: | |||
| return self.__currentState.mapInfo.doorProgress[(x, y)] | |||
| return copy.deepcopy(self.__currentState.mapInfo.doorProgress[(x, y)]) | |||
| else: | |||
| self.__logger.warning("Door not found") | |||
| return 0 | |||
| @@ -158,7 +164,7 @@ class Logic(ILogic): | |||
| def GetGameInfo(self) -> THUAI6.GameInfo: | |||
| with self.__mtxState: | |||
| self.__logger.debug("Called GetGameInfo") | |||
| return self.__currentState.gameInfo | |||
| return copy.deepcopy(self.__currentState.gameInfo) | |||
| def Move(self, time: int, angle: float) -> bool: | |||
| self.__logger.debug("Called Move") | |||
| @@ -172,6 +178,10 @@ class Logic(ILogic): | |||
| self.__logger.debug("Called UseProp") | |||
| return self.__comm.UseProp(propType, self.__playerID) | |||
| def ThrowProp(self, propType: THUAI6.PropType) -> bool: | |||
| self.__logger.debug("Called ThrowProp") | |||
| return self.__comm.ThrowProp(propType, self.__playerID) | |||
| def UseSkill(self, skillID: int) -> bool: | |||
| self.__logger.debug("Called UseSkill") | |||
| return self.__comm.UseSkill(skillID, self.__playerID) | |||
| @@ -198,11 +208,11 @@ class Logic(ILogic): | |||
| def GetCounter(self) -> int: | |||
| with self.__mtxState: | |||
| return self.__counterState | |||
| return copy.deepcopy(self.__counterState) | |||
| def GetPlayerGUIDs(self) -> List[int]: | |||
| with self.__mtxState: | |||
| return self.__playerGUIDs | |||
| return copy.deepcopy(self.__playerGUIDs) | |||
| # IStudentAPI使用的接口 | |||
| @@ -348,6 +358,8 @@ class Logic(ILogic): | |||
| self.__logger.debug("Add Student!") | |||
| for item in message.obj_message: | |||
| if item.WhichOneof("message_of_obj") == "tricker_message": | |||
| if MessageType.TRICKER_INVISIBLE in item.tricker_message.buff: | |||
| continue | |||
| 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)) | |||
| @@ -440,6 +452,8 @@ class Logic(ILogic): | |||
| self.__logger.debug("Add Tricker!") | |||
| for item in message.obj_message: | |||
| if item.WhichOneof("message_of_obj") == "student_message": | |||
| if MessageType.STUDENT_INVISIBLE in item.student_message.buff: | |||
| continue | |||
| 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)) | |||
| @@ -39,7 +39,6 @@ def THUAI6Main(argv: List[str], AIBuilder: Callable) -> None: | |||
| file = args.file | |||
| screen = args.screen | |||
| warnOnly = args.warnOnly | |||
| print(warnOnly) | |||
| logic = Logic(pID) | |||
| logic.Main(AIBuilder, sIP, sPort, file, screen, warnOnly) | |||
| @@ -1,4 +1,6 @@ | |||
| #!/usr/bin/env bash | |||
| python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 0 -d -o & | |||
| # python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 1 -d -o & | |||
| # python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 1 -d & | |||
| # python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 2 -d & | |||
| # python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 3 -d & | |||