| @@ -83,6 +83,8 @@ public: | |||||
| virtual bool Attack(double angle) = 0; | virtual bool Attack(double angle) = 0; | ||||
| virtual std::vector<int64_t> GetPlayerGUIDs() const = 0; | virtual std::vector<int64_t> GetPlayerGUIDs() const = 0; | ||||
| [[nodiscard]] virtual bool HaveView(int gridX, int gridY, int selfX, int selfY, int viewRange) const = 0; | |||||
| }; | }; | ||||
| class IAPI | class IAPI | ||||
| @@ -162,6 +164,8 @@ public: | |||||
| return grid / numOfGridPerCell; | return grid / numOfGridPerCell; | ||||
| } | } | ||||
| [[nodiscard]] virtual bool HaveView(int gridX, int gridY) const = 0; | |||||
| // 用于DEBUG的输出函数,选手仅在开启Debug模式的情况下可以使用 | // 用于DEBUG的输出函数,选手仅在开启Debug模式的情况下可以使用 | ||||
| virtual void Print(std::string str) const = 0; | virtual void Print(std::string str) const = 0; | ||||
| @@ -271,6 +275,8 @@ public: | |||||
| std::future<bool> Graduate() override; | std::future<bool> Graduate() override; | ||||
| [[nodiscard]] std::shared_ptr<const THUAI6::Student> GetSelfInfo() const override; | [[nodiscard]] std::shared_ptr<const THUAI6::Student> GetSelfInfo() const override; | ||||
| [[nodiscard]] bool HaveView(int gridX, int gridY) const override; | |||||
| void Print(std::string str) const override | void Print(std::string str) const override | ||||
| { | { | ||||
| } | } | ||||
| @@ -356,6 +362,8 @@ public: | |||||
| std::future<bool> Attack(double angleInRadian) override; | std::future<bool> Attack(double angleInRadian) override; | ||||
| [[nodiscard]] std::shared_ptr<const THUAI6::Tricker> GetSelfInfo() const override; | [[nodiscard]] std::shared_ptr<const THUAI6::Tricker> GetSelfInfo() const override; | ||||
| [[nodiscard]] bool HaveView(int gridX, int gridY) const override; | |||||
| void Print(std::string str) const override | void Print(std::string str) const override | ||||
| { | { | ||||
| } | } | ||||
| @@ -439,6 +447,8 @@ public: | |||||
| std::future<bool> Graduate() override; | std::future<bool> Graduate() override; | ||||
| [[nodiscard]] virtual std::shared_ptr<const THUAI6::Student> GetSelfInfo() const override; | [[nodiscard]] virtual std::shared_ptr<const THUAI6::Student> GetSelfInfo() const override; | ||||
| [[nodiscard]] bool HaveView(int gridX, int gridY) const override; | |||||
| void Print(std::string str) const override; | void Print(std::string str) const override; | ||||
| void PrintStudent() const override; | void PrintStudent() const override; | ||||
| void PrintTricker() const override; | void PrintTricker() const override; | ||||
| @@ -509,6 +519,8 @@ public: | |||||
| std::future<bool> Attack(double angleInRadian) override; | std::future<bool> Attack(double angleInRadian) override; | ||||
| [[nodiscard]] std::shared_ptr<const THUAI6::Tricker> GetSelfInfo() const override; | [[nodiscard]] std::shared_ptr<const THUAI6::Tricker> GetSelfInfo() const override; | ||||
| [[nodiscard]] bool HaveView(int gridX, int gridY) const override; | |||||
| void Print(std::string str) const override; | void Print(std::string str) const override; | ||||
| void PrintStudent() const override; | void PrintStudent() const override; | ||||
| void PrintTricker() const override; | void PrintTricker() const override; | ||||
| @@ -161,6 +161,8 @@ private: | |||||
| // 等待 | // 等待 | ||||
| void Wait() noexcept; | void Wait() noexcept; | ||||
| [[nodiscard]] bool HaveView(int gridX, int gridY, int selfX, int selfY, int viewRange) const override; | |||||
| public: | public: | ||||
| // 构造函数还需要传更多参数,有待补充 | // 构造函数还需要传更多参数,有待补充 | ||||
| Logic(THUAI6::PlayerType type, int64_t ID, THUAI6::TrickerType tricker, THUAI6::StudentType student); | Logic(THUAI6::PlayerType type, int64_t ID, THUAI6::TrickerType tricker, THUAI6::StudentType student); | ||||
| @@ -419,6 +419,18 @@ std::shared_ptr<const THUAI6::Tricker> TrickerAPI::GetSelfInfo() const | |||||
| return logic.TrickerGetSelfInfo(); | return logic.TrickerGetSelfInfo(); | ||||
| } | } | ||||
| bool StudentAPI::HaveView(int gridX, int gridY) const | |||||
| { | |||||
| auto selfInfo = GetSelfInfo(); | |||||
| return logic.HaveView(gridX, gridY, selfInfo->x, selfInfo->y, selfInfo->viewRange); | |||||
| } | |||||
| bool TrickerAPI::HaveView(int gridX, int gridY) const | |||||
| { | |||||
| auto selfInfo = GetSelfInfo(); | |||||
| return logic.HaveView(gridX, gridY, selfInfo->x, selfInfo->y, selfInfo->viewRange); | |||||
| } | |||||
| void StudentAPI::Play(IAI& ai) | void StudentAPI::Play(IAI& ai) | ||||
| { | { | ||||
| ai.play(*this); | ai.play(*this); | ||||
| @@ -631,6 +631,18 @@ std::shared_ptr<const THUAI6::Tricker> TrickerDebugAPI::GetSelfInfo() const | |||||
| return logic.TrickerGetSelfInfo(); | return logic.TrickerGetSelfInfo(); | ||||
| } | } | ||||
| bool StudentDebugAPI::HaveView(int gridX, int gridY) const | |||||
| { | |||||
| auto selfInfo = GetSelfInfo(); | |||||
| return logic.HaveView(gridX, gridY, selfInfo->x, selfInfo->y, selfInfo->viewRange); | |||||
| } | |||||
| bool TrickerDebugAPI::HaveView(int gridX, int gridY) const | |||||
| { | |||||
| auto selfInfo = GetSelfInfo(); | |||||
| return logic.HaveView(gridX, gridY, selfInfo->x, selfInfo->y, selfInfo->viewRange); | |||||
| } | |||||
| void StudentDebugAPI::Print(std::string str) const | void StudentDebugAPI::Print(std::string str) const | ||||
| { | { | ||||
| logger->info(str); | logger->info(str); | ||||
| @@ -686,6 +686,11 @@ bool Logic::TryConnection() | |||||
| return pComm->TryConnection(playerID); | return pComm->TryConnection(playerID); | ||||
| } | } | ||||
| bool Logic::HaveView(int gridX, int gridY, int selfX, int selfY, int viewRange) const | |||||
| { | |||||
| return AssistFunction::HaveView(viewRange, selfX, selfY, gridX, gridY, currentState->gameMap); | |||||
| } | |||||
| void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool file, bool print, bool warnOnly) | void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool file, bool print, bool warnOnly) | ||||
| { | { | ||||
| // 建立日志组件 | // 建立日志组件 | ||||
| @@ -132,6 +132,9 @@ class StudentAPI(IStudentAPI, IGameTimer): | |||||
| def GetGameInfo(self) -> THUAI6.GameInfo: | def GetGameInfo(self) -> THUAI6.GameInfo: | ||||
| return self.__logic.GetGameInfo() | return self.__logic.GetGameInfo() | ||||
| def HaveView(self, gridX: int, gridY: int) -> bool: | |||||
| return self.__logic.HaveView(gridX, gridY, self.GetSelfInfo().x, self.GetSelfInfo().y, self.GetSelfInfo().viewRange) | |||||
| # 用于DEBUG的输出函数,仅在DEBUG模式下有效 | # 用于DEBUG的输出函数,仅在DEBUG模式下有效 | ||||
| def Print(self, cont: str) -> None: | def Print(self, cont: str) -> None: | ||||
| @@ -305,6 +308,9 @@ class TrickerAPI(ITrickerAPI, IGameTimer): | |||||
| def GetGameInfo(self) -> THUAI6.GameInfo: | def GetGameInfo(self) -> THUAI6.GameInfo: | ||||
| return self.__logic.GetGameInfo() | return self.__logic.GetGameInfo() | ||||
| def HaveView(self, gridX: int, gridY: int) -> bool: | |||||
| return self.__logic.HaveView(gridX, gridY, self.GetSelfInfo().x, self.GetSelfInfo().y, self.GetSelfInfo().viewRange) | |||||
| # 用于DEBUG的输出函数,仅在DEBUG模式下有效 | # 用于DEBUG的输出函数,仅在DEBUG模式下有效 | ||||
| def Print(self, cont: str) -> None: | def Print(self, cont: str) -> None: | ||||
| @@ -304,6 +304,9 @@ class StudentDebugAPI(IStudentAPI, IGameTimer): | |||||
| def GetGameInfo(self) -> THUAI6.GameInfo: | def GetGameInfo(self) -> THUAI6.GameInfo: | ||||
| return self.__logic.GetGameInfo() | return self.__logic.GetGameInfo() | ||||
| def HaveView(self, gridX: int, gridY: int) -> bool: | |||||
| return self.__logic.HaveView(gridX, gridY, self.GetSelfInfo().x, self.GetSelfInfo().y, self.GetSelfInfo().viewRange) | |||||
| # 用于DEBUG的输出函数,仅在DEBUG模式下有效 | # 用于DEBUG的输出函数,仅在DEBUG模式下有效 | ||||
| def Print(self, cont: str) -> None: | def Print(self, cont: str) -> None: | ||||
| @@ -756,6 +759,9 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer): | |||||
| def GetGameInfo(self) -> THUAI6.GameInfo: | def GetGameInfo(self) -> THUAI6.GameInfo: | ||||
| return self.__logic.GetGameInfo() | return self.__logic.GetGameInfo() | ||||
| def HaveView(self, gridX: int, gridY: int) -> bool: | |||||
| return self.__logic.HaveView(gridX, gridY, self.GetSelfInfo().x, self.GetSelfInfo().y, self.GetSelfInfo().viewRange) | |||||
| # 用于DEBUG的输出函数,仅在DEBUG模式下有效 | # 用于DEBUG的输出函数,仅在DEBUG模式下有效 | ||||
| def Print(self, cont: str) -> None: | def Print(self, cont: str) -> None: | ||||
| @@ -154,6 +154,10 @@ class ILogic(metaclass=ABCMeta): | |||||
| def StartRouseMate(self, mateID: int) -> bool: | def StartRouseMate(self, mateID: int) -> bool: | ||||
| pass | pass | ||||
| @abstractmethod | |||||
| def HaveView(self, gridX: int, gridY: int, selfX: int, selfY: int, viewRange: int) -> bool: | |||||
| pass | |||||
| class IAPI(metaclass=ABCMeta): | class IAPI(metaclass=ABCMeta): | ||||
| @@ -314,6 +318,10 @@ class IAPI(metaclass=ABCMeta): | |||||
| def GetGameInfo(self) -> THUAI6.GameInfo: | def GetGameInfo(self) -> THUAI6.GameInfo: | ||||
| pass | pass | ||||
| @abstractmethod | |||||
| def HaveView(self, gridX: int, gridY: int) -> bool: | |||||
| pass | |||||
| # 用于DEBUG的输出函数,仅在DEBUG模式下有效 | # 用于DEBUG的输出函数,仅在DEBUG模式下有效 | ||||
| @abstractmethod | @abstractmethod | ||||
| @@ -262,6 +262,9 @@ class Logic(ILogic): | |||||
| self.__logger.debug("Called EndAllAction") | self.__logger.debug("Called EndAllAction") | ||||
| return self.__comm.EndAllAction(self.__playerID) | return self.__comm.EndAllAction(self.__playerID) | ||||
| def HaveView(self, gridX: int, gridY: int, selfX: int, selfY: int, viewRange: int) -> bool: | |||||
| return AssistFunction.HaveView(viewRange, selfX, selfY, gridX, gridY, self.__currentState.gameMap) | |||||
| # Logic内部逻辑 | # Logic内部逻辑 | ||||
| def __TryConnection(self) -> bool: | def __TryConnection(self) -> bool: | ||||
| self.__logger.info("Try to connect to server...") | self.__logger.info("Try to connect to server...") | ||||
| @@ -1,7 +1,7 @@ | |||||
| #!/usr/bin/env bash | #!/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 0 -d -o& | ||||
| python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 1& | |||||
| python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 1 -o& | |||||
| # python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 2& | # python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 2& | ||||
| # python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 3& | # python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 3& | ||||
| # python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 4& | # python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 4& | ||||
| @@ -1,6 +1,8 @@ | |||||
| #!/usr/local | #!/usr/local | ||||
| nice -10 ./Server/Server --port 8888 --studentCount 4 --trickerCount 1 --gameTimeInSecond 600 --url $URL --token $TOKEN | |||||
| python_dir=/usr/local/PlayerCode/CAPI/python/PyAPI | |||||
| nice -10 ./Server --port 8888 --studentCount 4 --trickerCount 1 --gameTimeInSecond 600 --url $URL --token $TOKEN | |||||
| sleep 5 | sleep 5 | ||||
| for k in {1..2} | for k in {1..2} | ||||
| do | do | ||||
| @@ -9,9 +11,10 @@ do | |||||
| for i in {1..4} | for i in {1..4} | ||||
| do | do | ||||
| j=$((i - 1)) | j=$((i - 1)) | ||||
| if [-f "./python/player$i.py"]; then | |||||
| nice -0 python3 ./python/player$i.py -I 127.0.0.1 -P 8888 -p $j | |||||
| elif [-f "./capi$i"]; then | |||||
| if [ -f "./player$i.py" ]; then | |||||
| cp -f ./player$i.py $python_dir/AI.py | |||||
| nice -0 python3 $python_dir/AI.py -I 127.0.0.1 -P 8888 -p $j | |||||
| elif [ -f "./capi$i" ]; then | |||||
| nice -0 ./capi$i -I 127.0.0.1 -P 8888 -p $j | nice -0 ./capi$i -I 127.0.0.1 -P 8888 -p $j | ||||
| else | else | ||||
| echo "ERROR. $i is not found." | echo "ERROR. $i is not found." | ||||
| @@ -21,9 +24,10 @@ do | |||||
| for i in {5..5} | for i in {5..5} | ||||
| do | do | ||||
| j=$((i - 1)) | j=$((i - 1)) | ||||
| if [-f "./python/player$i.py"]; then | |||||
| nice -0 python3 ./python/player$i.py -I 127.0.0.1 -P 8888 -p $j | |||||
| elif [-f "./capi$i"]; then | |||||
| if [ -f "./player$i.py" ]; then | |||||
| cp -f ./player$i.py $python_dir/AI.py | |||||
| nice -0 python3 $python_dir/AI.py -I 127.0.0.1 -P 8888 -p $j | |||||
| elif [ -f "./capi$i" ]; then | |||||
| nice -0 ./capi$i -I 127.0.0.1 -P 8888 -p $j | nice -0 ./capi$i -I 127.0.0.1 -P 8888 -p $j | ||||
| else | else | ||||
| echo "ERROR. $i is not found." | echo "ERROR. $i is not found." | ||||
| @@ -46,7 +46,7 @@ namespace GameClass.GameObj | |||||
| public bool Repair(int addDegree, Character character) | public bool Repair(int addDegree, Character character) | ||||
| { | { | ||||
| if (DegreeOfRepair == GameData.degreeOfFixedGenerator) return true; | |||||
| if (DegreeOfRepair == GameData.degreeOfFixedGenerator) return false; | |||||
| int orgDegreeOfRepair = degreeOfRepair; | int orgDegreeOfRepair = degreeOfRepair; | ||||
| DegreeOfRepair += addDegree; | DegreeOfRepair += addDegree; | ||||
| if (DegreeOfRepair > orgDegreeOfRepair) | if (DegreeOfRepair > orgDegreeOfRepair) | ||||
| @@ -203,7 +203,7 @@ namespace GameClass.GameObj | |||||
| } | } | ||||
| public bool Remove(GameObj gameObj) | public bool Remove(GameObj gameObj) | ||||
| { | { | ||||
| bool flag = false; | |||||
| GameObj? ToDel = null; | |||||
| GameObjLockDict[gameObj.Type].EnterWriteLock(); | GameObjLockDict[gameObj.Type].EnterWriteLock(); | ||||
| try | try | ||||
| { | { | ||||
| @@ -211,8 +211,7 @@ namespace GameClass.GameObj | |||||
| { | { | ||||
| if (gameObj.ID == obj.ID) | if (gameObj.ID == obj.ID) | ||||
| { | { | ||||
| GameObjDict[gameObj.Type].Remove(obj); | |||||
| flag = true; | |||||
| ToDel = obj; | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| @@ -221,7 +220,9 @@ namespace GameClass.GameObj | |||||
| { | { | ||||
| GameObjLockDict[gameObj.Type].ExitWriteLock(); | GameObjLockDict[gameObj.Type].ExitWriteLock(); | ||||
| } | } | ||||
| return flag; | |||||
| if (ToDel == null) return false; | |||||
| GameObjDict[gameObj.Type].Remove(ToDel); | |||||
| return true; | |||||
| } | } | ||||
| public bool RemoveJustFromMap(GameObj gameObj) | public bool RemoveJustFromMap(GameObj gameObj) | ||||
| { | { | ||||
| @@ -79,10 +79,9 @@ namespace Gaming | |||||
| loopToDo: () => | loopToDo: () => | ||||
| { | { | ||||
| if (generatorForFix.Repair(player.FixSpeed * GameData.frameDuration, player)) | if (generatorForFix.Repair(player.FixSpeed * GameData.frameDuration, player)) | ||||
| { | |||||
| characterManager.SetPlayerState(player); | |||||
| gameMap.NumOfRepairedGenerators++; | gameMap.NumOfRepairedGenerators++; | ||||
| } | |||||
| if (generatorForFix.DegreeOfRepair == GameData.degreeOfFixedGenerator) | |||||
| characterManager.SetPlayerState(player); | |||||
| }, | }, | ||||
| timeInterval: GameData.frameDuration, | timeInterval: GameData.frameDuration, | ||||
| finallyReturn: () => 0 | finallyReturn: () => 0 | ||||
| @@ -379,6 +379,7 @@ namespace Gaming | |||||
| #if DEBUG | #if DEBUG | ||||
| Debugger.Output(player, "die."); | Debugger.Output(player, "die."); | ||||
| #endif | #endif | ||||
| if (player.PlayerState == PlayerStateType.Deceased) return; | |||||
| player.RemoveFromGame(PlayerStateType.Deceased); | player.RemoveFromGame(PlayerStateType.Deceased); | ||||
| for (int i = 0; i < GameData.maxNumOfPropInPropInventory; i++) | for (int i = 0; i < GameData.maxNumOfPropInPropInventory; i++) | ||||
| @@ -397,8 +398,10 @@ namespace Gaming | |||||
| ((SummonGolem)(((Golem)player).Parent.FindIActiveSkill(ActiveSkillType.SummonGolem))).GolemSummoned = null; | ((SummonGolem)(((Golem)player).Parent.FindIActiveSkill(ActiveSkillType.SummonGolem))).GolemSummoned = null; | ||||
| player.FindIActiveSkill(ActiveSkillType.UseRobot).IsBeingUsed = false; | player.FindIActiveSkill(ActiveSkillType.UseRobot).IsBeingUsed = false; | ||||
| } | } | ||||
| gameMap.Remove(player); | |||||
| return; | return; | ||||
| } | } | ||||
| gameMap.Remove(player); | |||||
| ++gameMap.NumOfDeceasedStudent; | ++gameMap.NumOfDeceasedStudent; | ||||
| } | } | ||||