feat(CAPI): ✨ add print info, and fix some bug
tags/0.1.0
| @@ -4,13 +4,11 @@ | |||||
| #include "API.h" | #include "API.h" | ||||
| // 暂定版本:Human和Butcher全部继承AI类, | |||||
| class IAI | class IAI | ||||
| { | { | ||||
| public: | public: | ||||
| IAI() | |||||
| { | |||||
| } | |||||
| virtual ~IAI() = default; | |||||
| IAI() = default; | |||||
| virtual void play(IHumanAPI& api) = 0; | virtual void play(IHumanAPI& api) = 0; | ||||
| virtual void play(IButcherAPI& api) = 0; | virtual void play(IButcherAPI& api) = 0; | ||||
| }; | }; | ||||
| @@ -128,6 +128,13 @@ public: | |||||
| { | { | ||||
| return grid / num_of_grid_per_cell; | return grid / num_of_grid_per_cell; | ||||
| } | } | ||||
| // 用于DEBUG的输出函数,选手仅在开启Debug模式的情况下可以使用 | |||||
| virtual void PrintHuman() const = 0; | |||||
| virtual void PrintButcher() const = 0; | |||||
| virtual void PrintProp() const = 0; | |||||
| virtual void PrintSelfInfo() const = 0; | |||||
| }; | }; | ||||
| class IHumanAPI : public IAPI | class IHumanAPI : public IAPI | ||||
| @@ -158,6 +165,7 @@ public: | |||||
| class IGameTimer | class IGameTimer | ||||
| { | { | ||||
| public: | public: | ||||
| virtual ~IGameTimer() = default; | |||||
| virtual void StartTimer() = 0; | virtual void StartTimer() = 0; | ||||
| virtual void EndTimer() = 0; | virtual void EndTimer() = 0; | ||||
| virtual void Play(IAI& ai) = 0; | virtual void Play(IAI& ai) = 0; | ||||
| @@ -214,6 +222,19 @@ public: | |||||
| std::future<bool> Escape() override; | std::future<bool> Escape() override; | ||||
| [[nodiscard]] std::shared_ptr<const THUAI6::Human> GetSelfInfo() const override; | [[nodiscard]] std::shared_ptr<const THUAI6::Human> GetSelfInfo() const override; | ||||
| void PrintHuman() const override | |||||
| { | |||||
| } | |||||
| void PrintButcher() const override | |||||
| { | |||||
| } | |||||
| void PrintProp() const override | |||||
| { | |||||
| } | |||||
| void PrintSelfInfo() const override | |||||
| { | |||||
| } | |||||
| private: | private: | ||||
| ILogic& logic; | ILogic& logic; | ||||
| }; | }; | ||||
| @@ -267,6 +288,19 @@ public: | |||||
| std::future<bool> HangHuman() override; | std::future<bool> HangHuman() override; | ||||
| [[nodiscard]] std::shared_ptr<const THUAI6::Butcher> GetSelfInfo() const override; | [[nodiscard]] std::shared_ptr<const THUAI6::Butcher> GetSelfInfo() const override; | ||||
| void PrintHuman() const override | |||||
| { | |||||
| } | |||||
| void PrintButcher() const override | |||||
| { | |||||
| } | |||||
| void PrintProp() const override | |||||
| { | |||||
| } | |||||
| void PrintSelfInfo() const override | |||||
| { | |||||
| } | |||||
| private: | private: | ||||
| ILogic& logic; | ILogic& logic; | ||||
| }; | }; | ||||
| @@ -314,6 +348,11 @@ public: | |||||
| std::future<bool> Escape() override; | std::future<bool> Escape() override; | ||||
| [[nodiscard]] virtual std::shared_ptr<const THUAI6::Human> GetSelfInfo() const override; | [[nodiscard]] virtual std::shared_ptr<const THUAI6::Human> GetSelfInfo() const override; | ||||
| void PrintHuman() const override; | |||||
| void PrintButcher() const override; | |||||
| void PrintProp() const override; | |||||
| void PrintSelfInfo() const override; | |||||
| private: | private: | ||||
| std::chrono::system_clock::time_point startPoint; | std::chrono::system_clock::time_point startPoint; | ||||
| std::unique_ptr<spdlog::logger> logger; | std::unique_ptr<spdlog::logger> logger; | ||||
| @@ -362,6 +401,11 @@ public: | |||||
| std::future<bool> HangHuman() override; | std::future<bool> HangHuman() override; | ||||
| [[nodiscard]] std::shared_ptr<const THUAI6::Butcher> GetSelfInfo() const override; | [[nodiscard]] std::shared_ptr<const THUAI6::Butcher> GetSelfInfo() const override; | ||||
| void PrintHuman() const override; | |||||
| void PrintButcher() const override; | |||||
| void PrintProp() const override; | |||||
| void PrintSelfInfo() const override; | |||||
| private: | private: | ||||
| std::chrono::system_clock::time_point startPoint; | std::chrono::system_clock::time_point startPoint; | ||||
| std::unique_ptr<spdlog::logger> logger; | std::unique_ptr<spdlog::logger> logger; | ||||
| @@ -159,7 +159,29 @@ namespace THUAI6 | |||||
| // 仅供DEBUG使用,名称可改动 | // 仅供DEBUG使用,名称可改动 | ||||
| // 还没写完,后面待续 | // 还没写完,后面待续 | ||||
| inline std::map<PlaceType, std::string> placeDict{ | |||||
| inline std::map<GameState, std::string> gameStateDict{ | |||||
| {GameState::NullGameState, "NullGameState"}, | |||||
| {GameState::GameStart, "GameStart"}, | |||||
| {GameState::GameRunning, "GameRunning"}, | |||||
| {GameState::GameEnd, "GameEnd"}, | |||||
| }; | |||||
| inline std::map<HumanState, std::string> humanStateDict{ | |||||
| {HumanState::NullHumanState, "NullHumanState"}, | |||||
| {HumanState::Idle, "Idle"}, | |||||
| {HumanState::Fixing, "Fixing"}, | |||||
| {HumanState::Dying, "Dying"}, | |||||
| {HumanState::OnChair, "OnChair"}, | |||||
| {HumanState::Dead, "Dead"}, | |||||
| }; | |||||
| inline std::map<PlayerType, std::string> playerTypeDict{ | |||||
| {PlayerType::NullPlayerType, "NullPlayerType"}, | |||||
| {PlayerType::HumanPlayer, "HumanPlayer"}, | |||||
| {PlayerType::ButcherPlayer, "ButcherPlayer"}, | |||||
| }; | |||||
| inline std::map<PlaceType, std::string> placeTypeDict{ | |||||
| {PlaceType::NullPlaceType, "NullPlaceType"}, | {PlaceType::NullPlaceType, "NullPlaceType"}, | ||||
| {PlaceType::Land, "Land"}, | {PlaceType::Land, "Land"}, | ||||
| {PlaceType::Wall, "Wall"}, | {PlaceType::Wall, "Wall"}, | ||||
| @@ -169,11 +191,21 @@ namespace THUAI6 | |||||
| {PlaceType::HiddenGate, "HiddenGate"}, | {PlaceType::HiddenGate, "HiddenGate"}, | ||||
| }; | }; | ||||
| inline std::map<PropType, std::string> propDict{ | |||||
| inline std::map<PropType, std::string> propTypeDict{ | |||||
| {PropType::NullPropType, "NullPropType"}, | {PropType::NullPropType, "NullPropType"}, | ||||
| }; | }; | ||||
| inline std::map<HumanBuffType, std::string> humanBuffDict{ | |||||
| {HumanBuffType::NullHumanBuffType, "NullHumanBuffType"}, | |||||
| }; | |||||
| inline std::map<ButcherBuffType, std::string> butcherBuffDict{ | |||||
| {ButcherBuffType::NullButcherBuffType, "NullButcherBuffType"}, | |||||
| }; | |||||
| } // namespace THUAI6 | } // namespace THUAI6 | ||||
| #endif | #endif | ||||
| @@ -148,7 +148,7 @@ std::future<bool> ButcherDebugAPI::MoveLeft(int64_t timeInMilliseconds) | |||||
| std::future<bool> HumanDebugAPI::PickProp(THUAI6::PropType prop) | std::future<bool> HumanDebugAPI::PickProp(THUAI6::PropType prop) | ||||
| { | { | ||||
| logger->info("PickProp: prop = {}, called at {}ms", THUAI6::propDict[prop], Time::TimeSinceStart(startPoint)); | |||||
| logger->info("PickProp: prop = {}, called at {}ms", THUAI6::propTypeDict[prop], Time::TimeSinceStart(startPoint)); | |||||
| return std::async(std::launch::async, [=]() | return std::async(std::launch::async, [=]() | ||||
| { auto result = logic.PickProp(prop); | { auto result = logic.PickProp(prop); | ||||
| if (!result) | if (!result) | ||||
| @@ -168,7 +168,7 @@ std::future<bool> HumanDebugAPI::UseProp() | |||||
| std::future<bool> ButcherDebugAPI::PickProp(THUAI6::PropType prop) | std::future<bool> ButcherDebugAPI::PickProp(THUAI6::PropType prop) | ||||
| { | { | ||||
| logger->info("PickProp: prop = {}, called at {}ms", THUAI6::propDict[prop], Time::TimeSinceStart(startPoint)); | |||||
| logger->info("PickProp: prop = {}, called at {}ms", THUAI6::propTypeDict[prop], Time::TimeSinceStart(startPoint)); | |||||
| return std::async(std::launch::async, [=]() | return std::async(std::launch::async, [=]() | ||||
| { auto result = logic.PickProp(prop); | { auto result = logic.PickProp(prop); | ||||
| if (!result) | if (!result) | ||||
| @@ -448,6 +448,118 @@ std::shared_ptr<const THUAI6::Butcher> ButcherDebugAPI::GetSelfInfo() const | |||||
| return logic.ButcherGetSelfInfo(); | return logic.ButcherGetSelfInfo(); | ||||
| } | } | ||||
| void HumanDebugAPI::PrintHuman() const | |||||
| { | |||||
| for (auto human : logic.GetHumans()) | |||||
| { | |||||
| logger->info("******Human Info******"); | |||||
| logger->info("playerID={}, GUID={}, x={}, y={}", human->playerID, human->guid, human->x, human->y); | |||||
| logger->info("speed={}, view range={}, skill time={}, prop={}, place={}", human->speed, human->viewRange, human->timeUntilSkillAvailable, THUAI6::propTypeDict[human->prop], THUAI6::placeTypeDict[human->place]); | |||||
| logger->info("state={}, life={}, hangedTime={}", THUAI6::humanStateDict[human->state], human->life, human->hangedTime); | |||||
| std::string humanBuff = "buff="; | |||||
| for (auto buff : human->buff) | |||||
| humanBuff += THUAI6::humanBuffDict[buff] + ", "; | |||||
| logger->info(humanBuff); | |||||
| logger->info("**********************"); | |||||
| } | |||||
| } | |||||
| void ButcherDebugAPI::PrintHuman() const | |||||
| { | |||||
| for (auto human : logic.GetHumans()) | |||||
| { | |||||
| logger->info("******Human Info******"); | |||||
| logger->info("playerID={}, GUID={}, x={}, y={}", human->playerID, human->guid, human->x, human->y); | |||||
| logger->info("speed={}, view range={}, skill time={}, prop={}, place={}", human->speed, human->viewRange, human->timeUntilSkillAvailable, THUAI6::propTypeDict[human->prop], THUAI6::placeTypeDict[human->place]); | |||||
| logger->info("state={}, life={}, hangedTime={}", THUAI6::humanStateDict[human->state], human->life, human->hangedTime); | |||||
| std::string humanBuff = "buff="; | |||||
| for (auto buff : human->buff) | |||||
| humanBuff += THUAI6::humanBuffDict[buff] + ", "; | |||||
| logger->info(humanBuff); | |||||
| logger->info("**********************"); | |||||
| } | |||||
| } | |||||
| void HumanDebugAPI::PrintButcher() const | |||||
| { | |||||
| for (auto butcher : logic.GetButchers()) | |||||
| { | |||||
| logger->info("******Butcher Info******"); | |||||
| logger->info("playerID={}, GUID={}, x={}, y={}", butcher->playerID, butcher->guid, butcher->x, butcher->y); | |||||
| logger->info("speed={}, view range={}, skill time={}, prop={}, place={}", butcher->speed, butcher->viewRange, butcher->timeUntilSkillAvailable, THUAI6::propTypeDict[butcher->prop], THUAI6::placeTypeDict[butcher->place]); | |||||
| logger->info("damage={}, movable={}", butcher->damage, butcher->movable); | |||||
| std::string butcherBuff = "buff="; | |||||
| for (auto buff : butcher->buff) | |||||
| butcherBuff += THUAI6::butcherBuffDict[buff] + ", "; | |||||
| logger->info(butcherBuff); | |||||
| logger->info("************************"); | |||||
| } | |||||
| } | |||||
| void ButcherDebugAPI::PrintButcher() const | |||||
| { | |||||
| for (auto butcher : logic.GetButchers()) | |||||
| { | |||||
| logger->info("******Butcher Info******"); | |||||
| logger->info("playerID={}, GUID={}, x={}, y={}", butcher->playerID, butcher->guid, butcher->x, butcher->y); | |||||
| logger->info("speed={}, view range={}, skill time={}, prop={}, place={}", butcher->speed, butcher->viewRange, butcher->timeUntilSkillAvailable, THUAI6::propTypeDict[butcher->prop], THUAI6::placeTypeDict[butcher->place]); | |||||
| logger->info("damage={}, movable={}", butcher->damage, butcher->movable); | |||||
| std::string butcherBuff = "buff="; | |||||
| for (auto buff : butcher->buff) | |||||
| butcherBuff += THUAI6::butcherBuffDict[buff] + ", "; | |||||
| logger->info(butcherBuff); | |||||
| logger->info("************************"); | |||||
| } | |||||
| } | |||||
| void HumanDebugAPI::PrintProp() const | |||||
| { | |||||
| for (auto prop : logic.GetProps()) | |||||
| { | |||||
| logger->info("******Prop Info******"); | |||||
| logger->info("GUID={}, x={}, y={}, place={}, is moving={}", prop->guid, prop->x, prop->y, THUAI6::placeTypeDict[prop->place], prop->isMoving); | |||||
| logger->info("*********************"); | |||||
| } | |||||
| } | |||||
| void ButcherDebugAPI::PrintProp() const | |||||
| { | |||||
| for (auto prop : logic.GetProps()) | |||||
| { | |||||
| logger->info("******Prop Info******"); | |||||
| logger->info("GUID={}, x={}, y={}, place={}, is moving={}", prop->guid, prop->x, prop->y, THUAI6::placeTypeDict[prop->place], prop->isMoving); | |||||
| logger->info("*********************"); | |||||
| } | |||||
| } | |||||
| void HumanDebugAPI::PrintSelfInfo() const | |||||
| { | |||||
| auto self = logic.HumanGetSelfInfo(); | |||||
| logger->info("******Self Info******"); | |||||
| logger->info("playerID={}, GUID={}, x={}, y={}", self->playerID, self->guid, self->x, self->y); | |||||
| logger->info("speed={}, view range={}, skill time={}, prop={}, place={}", self->speed, self->viewRange, self->timeUntilSkillAvailable, THUAI6::propTypeDict[self->prop], THUAI6::placeTypeDict[self->place]); | |||||
| logger->info("state={}, life={}, hangedTime={}", THUAI6::humanStateDict[self->state], self->life, self->hangedTime); | |||||
| std::string humanBuff = "buff="; | |||||
| for (auto buff : self->buff) | |||||
| humanBuff += THUAI6::humanBuffDict[buff] + ", "; | |||||
| logger->info(humanBuff); | |||||
| logger->info("*********************"); | |||||
| } | |||||
| void ButcherDebugAPI::PrintSelfInfo() const | |||||
| { | |||||
| auto self = logic.ButcherGetSelfInfo(); | |||||
| logger->info("******Self Info******"); | |||||
| logger->info("playerID={}, GUID={}, x={}, y={}", self->playerID, self->guid, self->x, self->y); | |||||
| logger->info("speed={}, view range={}, skill time={}, prop={}, place={}", self->speed, self->viewRange, self->timeUntilSkillAvailable, THUAI6::propTypeDict[self->prop], THUAI6::placeTypeDict[self->place]); | |||||
| logger->info("damage={}, movable={}", self->damage, self->movable); | |||||
| std::string butcherBuff = "buff="; | |||||
| for (auto buff : self->buff) | |||||
| butcherBuff += THUAI6::butcherBuffDict[buff] + ", "; | |||||
| logger->info(butcherBuff); | |||||
| logger->info("*********************"); | |||||
| } | |||||
| void HumanDebugAPI::Play(IAI& ai) | void HumanDebugAPI::Play(IAI& ai) | ||||
| { | { | ||||
| ai.play(*this); | ai.play(*this); | ||||
| @@ -451,6 +451,14 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool f | |||||
| printLogger->set_level(spdlog::level::warn); | printLogger->set_level(spdlog::level::warn); | ||||
| logger = std::make_unique<spdlog::logger>("logicLogger", spdlog::sinks_init_list{fileLogger, printLogger}); | logger = std::make_unique<spdlog::logger>("logicLogger", spdlog::sinks_init_list{fileLogger, printLogger}); | ||||
| // 打印当前的调试信息 | |||||
| logger->info("*********Basic Info*********"); | |||||
| logger->info("asynchronous: {}", asynchronous); | |||||
| logger->info("server: {}:{}", IP, port); | |||||
| logger->info("player ID: {}", playerID); | |||||
| logger->info("player type: {}", THUAI6::playerTypeDict[playerType]); | |||||
| logger->info("****************************"); | |||||
| // 建立与服务器之间通信的组件 | // 建立与服务器之间通信的组件 | ||||
| pComm = std::make_unique<Communication>(IP, port); | pComm = std::make_unique<Communication>(IP, port); | ||||
| @@ -499,12 +507,11 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool f | |||||
| } | } | ||||
| }; | }; | ||||
| tAI = std::thread(AIThread); | |||||
| // 连接服务器 | // 连接服务器 | ||||
| if (TryConnection()) | if (TryConnection()) | ||||
| { | { | ||||
| logger->info("Connect to the server successfully, AI thread will be start."); | logger->info("Connect to the server successfully, AI thread will be start."); | ||||
| tAI = std::thread(AIThread); | |||||
| if (tAI.joinable()) | if (tAI.joinable()) | ||||
| { | { | ||||
| logger->info("Join the AI thread!"); | logger->info("Join the AI thread!"); | ||||
| @@ -516,7 +523,7 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool f | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| logger->error("Connect to the server failed, AI thread will not be start."); | |||||
| logger->error("Connect to the server failed, AI thread will not be started."); | |||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| @@ -20,7 +20,7 @@ int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder) | |||||
| extern const THUAI6::HumanType humanType; | extern const THUAI6::HumanType humanType; | ||||
| // 仅供早期调试使用 | // 仅供早期调试使用 | ||||
| { | { | ||||
| file = true; | |||||
| file = false; | |||||
| print = true; | print = true; | ||||
| Logic logic(playerType, pID, butcherType, humanType); | Logic logic(playerType, pID, butcherType, humanType); | ||||
| logic.Main(AIBuilder, sIP, sPort, file, print, warnOnly); | logic.Main(AIBuilder, sIP, sPort, file, print, warnOnly); | ||||