diff --git a/CAPI/API/include/API.h b/CAPI/API/include/API.h index 056cddc..0fb0f4b 100644 --- a/CAPI/API/include/API.h +++ b/CAPI/API/include/API.h @@ -45,23 +45,24 @@ public: virtual bool HaveMessage() = 0; virtual std::pair GetMessage() = 0; + virtual bool WaitThread() = 0; + + virtual int GetCounter() const = 0; + + // IHumanAPI使用的部分 virtual bool Escape() = 0; - // 说明:双向stream由三个函数共同实现,两个记录开始和结束,结果由Logic里的私有的成员变量记录,获得返回值则另调函数 virtual bool StartFixMachine() = 0; virtual bool EndFixMachine() = 0; virtual bool StartSaveHuman() = 0; virtual bool EndSaveHuman() = 0; + // IButcherAPI使用的部分 virtual bool Attack(double angle) = 0; virtual bool CarryHuman() = 0; virtual bool ReleaseHuman() = 0; virtual bool HangHuman() = 0; - - virtual bool WaitThread() = 0; - - virtual int GetCounter() = 0; }; class IAPI @@ -201,9 +202,7 @@ public: [[nodiscard]] std::vector> GetFullMap() const override; [[nodiscard]] THUAI6::PlaceType GetPlaceType(int32_t CellX, int32_t CellY) const override; - [[nodiscard]] const std::vector GetPlayerGUIDs() const override - { - } + [[nodiscard]] const std::vector GetPlayerGUIDs() const override; std::future StartFixMachine() override; std::future EndFixMachine() override; @@ -262,9 +261,7 @@ public: [[nodiscard]] std::vector> GetFullMap() const override; [[nodiscard]] THUAI6::PlaceType GetPlaceType(int32_t CellX, int32_t CellY) const override; - [[nodiscard]] const std::vector GetPlayerGUIDs() const override - { - } + [[nodiscard]] const std::vector GetPlayerGUIDs() const override; std::future Attack(double angleInRadian) override; std::future CarryHuman() override; @@ -291,91 +288,45 @@ public: } void Play(IAI& ai) override; - std::future Move(int64_t timeInMilliseconds, double angleInRadian) override - { - } + std::future Move(int64_t timeInMilliseconds, double angleInRadian) override; [[nodiscard]] int GetFrameCount() const override { } - std::future MoveRight(int64_t timeInMilliseconds) override - { - } - std::future MoveUp(int64_t timeInMilliseconds) override - { - } - std::future MoveLeft(int64_t timeInMilliseconds) override - { - } - std::future MoveDown(int64_t timeInMilliseconds) override - { - } + std::future MoveRight(int64_t timeInMilliseconds) override; + std::future MoveUp(int64_t timeInMilliseconds) override; + std::future MoveLeft(int64_t timeInMilliseconds) override; + std::future MoveDown(int64_t timeInMilliseconds) override; - std::future PickProp(THUAI6::PropType prop) override - { - } - std::future UseProp() override - { - } - std::future UseSkill() override - { - } + std::future PickProp(THUAI6::PropType prop) override; + std::future UseProp() override; + std::future UseSkill() override; - std::future SendMessage(int64_t, std::string) override - { - } - [[nodiscard]] std::future HaveMessage() override - { - } - [[nodiscard]] std::future> GetMessage() override - { - } + std::future SendMessage(int64_t, std::string) override; + [[nodiscard]] std::future HaveMessage() override; + [[nodiscard]] std::future> GetMessage() override; std::future Wait() override { } - [[nodiscard]] std::vector> GetHuman() const override - { - } - [[nodiscard]] std::vector> GetButcher() const override - { - } + [[nodiscard]] std::vector> GetHuman() const override; + [[nodiscard]] std::vector> GetButcher() const override; - [[nodiscard]] std::vector> GetProps() const override - { - } + [[nodiscard]] std::vector> GetProps() const override; - [[nodiscard]] std::vector> GetFullMap() const override - { - } - [[nodiscard]] THUAI6::PlaceType GetPlaceType(int32_t CellX, int32_t CellY) const override - { - } + [[nodiscard]] std::vector> GetFullMap() const override; + [[nodiscard]] THUAI6::PlaceType GetPlaceType(int32_t CellX, int32_t CellY) const override; - [[nodiscard]] const std::vector GetPlayerGUIDs() const override - { - } + [[nodiscard]] const std::vector GetPlayerGUIDs() const override; - std::future StartFixMachine() override - { - } - std::future EndFixMachine() override - { - } - std::future StartSaveHuman() override - { - } - std::future EndSaveHuman() override - { - } - std::future Escape() override - { - } - [[nodiscard]] virtual std::shared_ptr GetSelfInfo() const override - { - } + std::future StartFixMachine() override; + std::future EndFixMachine() override; + std::future StartSaveHuman() override; + std::future EndSaveHuman() override; + std::future Escape() override; + [[nodiscard]] virtual std::shared_ptr GetSelfInfo() const override; private: ILogic& logic; @@ -396,88 +347,44 @@ public: } void Play(IAI& ai) override; - std::future Move(int64_t timeInMilliseconds, double angleInRadian) override - { - } + std::future Move(int64_t timeInMilliseconds, double angleInRadian) override; [[nodiscard]] int GetFrameCount() const override { } - std::future MoveRight(int64_t timeInMilliseconds) override - { - } - std::future MoveUp(int64_t timeInMilliseconds) override - { - } - std::future MoveLeft(int64_t timeInMilliseconds) override - { - } - std::future MoveDown(int64_t timeInMilliseconds) override - { - } + std::future MoveRight(int64_t timeInMilliseconds) override; + std::future MoveUp(int64_t timeInMilliseconds) override; + std::future MoveLeft(int64_t timeInMilliseconds) override; + std::future MoveDown(int64_t timeInMilliseconds) override; - std::future PickProp(THUAI6::PropType prop) override - { - } - std::future UseProp() override - { - } - std::future UseSkill() override - { - } + std::future PickProp(THUAI6::PropType prop) override; + std::future UseProp() override; + std::future UseSkill() override; - std::future SendMessage(int64_t, std::string) override - { - } - [[nodiscard]] std::future HaveMessage() override - { - } - [[nodiscard]] std::future> GetMessage() override - { - } + std::future SendMessage(int64_t, std::string) override; + [[nodiscard]] std::future HaveMessage() override; + [[nodiscard]] std::future> GetMessage() override; std::future Wait() override { } - [[nodiscard]] std::vector> GetHuman() const override - { - } - [[nodiscard]] std::vector> GetButcher() const override - { - } + [[nodiscard]] std::vector> GetHuman() const override; + [[nodiscard]] std::vector> GetButcher() const override; - [[nodiscard]] std::vector> GetProps() const override - { - } + [[nodiscard]] std::vector> GetProps() const override; - [[nodiscard]] std::vector> GetFullMap() const override - { - } - [[nodiscard]] THUAI6::PlaceType GetPlaceType(int32_t CellX, int32_t CellY) const override - { - } + [[nodiscard]] std::vector> GetFullMap() const override; + [[nodiscard]] THUAI6::PlaceType GetPlaceType(int32_t CellX, int32_t CellY) const override; - [[nodiscard]] const std::vector GetPlayerGUIDs() const override - { - } + [[nodiscard]] const std::vector GetPlayerGUIDs() const override; - std::future Attack(double angleInRadian) override - { - } - std::future CarryHuman() override - { - } - std::future ReleaseHuman() override - { - } - std::future HangHuman() override - { - } - [[nodiscard]] std::shared_ptr GetSelfInfo() const override - { - } + std::future Attack(double angleInRadian) override; + std::future CarryHuman() override; + std::future ReleaseHuman() override; + std::future HangHuman() override; + [[nodiscard]] std::shared_ptr GetSelfInfo() const override; private: ILogic& logic; diff --git a/CAPI/API/include/logic.h b/CAPI/API/include/logic.h index 3daedd9..0ba4176 100644 --- a/CAPI/API/include/logic.h +++ b/CAPI/API/include/logic.h @@ -64,19 +64,20 @@ private: State* currentState; State* bufferState; + // 保存缓冲区数 + int counterState = 0; + int counterBuffer = 0; + // 是否应该执行player() std::atomic_bool AILoop = true; // buffer是否更新完毕 bool bufferUpdated = true; - // 是否可以启用当前状态 - bool currentStateAccessed = false; - // 是否应当启动AI bool AIStart = false; - // 控制内容更新的变量 + // asynchronous = true 时控制内容更新的变量 std::atomic_bool freshed = false; // 提供给API使用的函数 @@ -114,19 +115,12 @@ private: bool ReleaseHuman() override; bool HangHuman() override; - bool WaitThread() override - { - } + bool WaitThread() override; - int GetCounter() override - { - } + int GetCounter() const override; bool TryConnection(); - // 执行AI线程 - void PlayerWrapper(std::function player); - // THUAI5中的一系列用于处理信息的函数可能也不会再用 void ProcessMessage(); diff --git a/CAPI/API/src/AI.cpp b/CAPI/API/src/AI.cpp index c62b459..5f6b230 100644 --- a/CAPI/API/src/AI.cpp +++ b/CAPI/API/src/AI.cpp @@ -2,6 +2,9 @@ #include #include "AI.h" +// 为假则play()期间确保游戏状态不更新,为真则只保证游戏状态在调用相关方法时不更新 +extern const bool asynchronous = false; + // 选手必须定义该变量来选择自己的阵营 extern const THUAI6::PlayerType playerType = THUAI6::PlayerType::HumanPlayer; diff --git a/CAPI/API/src/API.cpp b/CAPI/API/src/API.cpp index 4f41f03..9273fca 100644 --- a/CAPI/API/src/API.cpp +++ b/CAPI/API/src/API.cpp @@ -176,6 +176,16 @@ std::vector> ButcherAPI::GetFullMap() const return logic.GetFullMap(); } +const std::vector HumanAPI::GetPlayerGUIDs() const +{ + // todo +} + +const std::vector ButcherAPI::GetPlayerGUIDs() const +{ + // todo +} + std::future HumanAPI::StartFixMachine() { std::async(std::launch::async, [&]() diff --git a/CAPI/API/src/Communication.cpp b/CAPI/API/src/Communication.cpp index f0855e1..5c4bcb9 100644 --- a/CAPI/API/src/Communication.cpp +++ b/CAPI/API/src/Communication.cpp @@ -78,11 +78,11 @@ bool Communication::HaveMessage(int64_t playerID) protobuf::BoolRes haveMessageResult; ClientContext context; auto request = THUAI62Proto::THUAI62ProtobufID(playerID); - auto status = THUAI6Stub->HaveMessage(&context, request, &haveMessageResult); - if (status.ok()) - return haveMessageResult.act_success(); - else - return false; + // auto status = THUAI6Stub->HaveMessage(&context, request, &haveMessageResult); + // if (status.ok()) + // return haveMessageResult.act_success(); + // else + // return false; } std::pair Communication::GetMessage(int64_t playerID) @@ -90,16 +90,16 @@ std::pair Communication::GetMessage(int64_t playerID) protobuf::MsgRes getMessageResult; ClientContext context; auto request = THUAI62Proto::THUAI62ProtobufID(playerID); - auto status = THUAI6Stub->GetMessage(&context, request, &getMessageResult); - if (status.ok()) - { - if (getMessageResult.have_message()) - return std::make_pair(getMessageResult.from_player_id(), getMessageResult.message_received()); - else - return std::make_pair(-1, ""); - } - else - return std::make_pair(-1, ""); + // auto status = THUAI6Stub->GetMessage(&context, request, &getMessageResult); + // if (status.ok()) + // { + // if (getMessageResult.have_message()) + // return std::make_pair(getMessageResult.from_player_id(), getMessageResult.message_received()); + // else + // return std::make_pair(-1, ""); + // } + // else + // return std::make_pair(-1, ""); } bool Communication::Escape(int64_t playerID) diff --git a/CAPI/API/src/DebugAPI.cpp b/CAPI/API/src/DebugAPI.cpp index fb521dc..5be7dba 100644 --- a/CAPI/API/src/DebugAPI.cpp +++ b/CAPI/API/src/DebugAPI.cpp @@ -1,5 +1,254 @@ #include "AI.h" #include "API.h" +#define PI 3.14159265358979323846 + +std::future HumanDebugAPI::Move(int64_t timeInMilliseconds, double angleInRadian) +{ + return std::async(std::launch::async, [&]() + { return logic.Move(timeInMilliseconds, angleInRadian); }); +} + +std::future HumanDebugAPI::MoveDown(int64_t timeInMilliseconds) +{ + return Move(timeInMilliseconds, 0); +} + +std::future HumanDebugAPI::MoveRight(int64_t timeInMilliseconds) +{ + return Move(timeInMilliseconds, PI * 0.5); +} + +std::future HumanDebugAPI::MoveUp(int64_t timeInMilliseconds) +{ + return Move(timeInMilliseconds, PI); +} + +std::future HumanDebugAPI::MoveLeft(int64_t timeInMilliseconds) +{ + return Move(timeInMilliseconds, PI * 1.5); +} + +std::future ButcherDebugAPI::Move(int64_t timeInMilliseconds, double angleInRadian) +{ + return std::async(std::launch::async, [&]() + { return logic.Move(timeInMilliseconds, angleInRadian); }); +} + +std::future ButcherDebugAPI::MoveDown(int64_t timeInMilliseconds) +{ + return Move(timeInMilliseconds, 0); +} + +std::future ButcherDebugAPI::MoveRight(int64_t timeInMilliseconds) +{ + return Move(timeInMilliseconds, PI * 0.5); +} + +std::future ButcherDebugAPI::MoveUp(int64_t timeInMilliseconds) +{ + return Move(timeInMilliseconds, PI); +} + +std::future ButcherDebugAPI::MoveLeft(int64_t timeInMilliseconds) +{ + return Move(timeInMilliseconds, PI * 1.5); +} + +std::future HumanDebugAPI::PickProp(THUAI6::PropType prop) +{ + return std::async(std::launch::async, [&]() + { return logic.PickProp(prop); }); +} + +std::future HumanDebugAPI::UseProp() +{ + return std::async(std::launch::async, [&]() + { return logic.UseProp(); }); +} + +std::future ButcherDebugAPI::PickProp(THUAI6::PropType prop) +{ + return std::async(std::launch::async, [&]() + { return logic.PickProp(prop); }); +} + +std::future ButcherDebugAPI::UseProp() +{ + return std::async(std::launch::async, [&]() + { return logic.UseProp(); }); +} + +std::future HumanDebugAPI::UseSkill() +{ + return std::async(std::launch::async, [&]() + { return logic.UseSkill(); }); +} + +std::future ButcherDebugAPI::UseSkill() +{ + return std::async(std::launch::async, [&]() + { return logic.UseSkill(); }); +} + +std::future HumanDebugAPI::SendMessage(int64_t toID, std::string message) +{ + return std::async(std::launch::async, [&]() + { return logic.SendMessage(toID, message); }); +} + +std::future ButcherDebugAPI::SendMessage(int64_t toID, std::string message) +{ + return std::async(std::launch::async, [&]() + { return logic.SendMessage(toID, message); }); +} + +std::future HumanDebugAPI::HaveMessage() +{ + return std::async(std::launch::async, [&]() + { return logic.HaveMessage(); }); +} + +std::future ButcherDebugAPI::HaveMessage() +{ + return std::async(std::launch::async, [&]() + { return logic.HaveMessage(); }); +} + +std::future> HumanDebugAPI::GetMessage() +{ + return std::async(std::launch::async, [&]() + { return logic.GetMessage(); }); +} + +std::future> ButcherDebugAPI::GetMessage() +{ + return std::async(std::launch::async, [&]() + { return logic.GetMessage(); }); +} + +std::vector> HumanDebugAPI::GetButcher() const +{ + return logic.GetButchers(); +} + +std::vector> HumanDebugAPI::GetHuman() const +{ + return logic.GetHumans(); +} + +std::vector> ButcherDebugAPI::GetButcher() const +{ + return logic.GetButchers(); +} + +std::vector> ButcherDebugAPI::GetHuman() const +{ + return logic.GetHumans(); +} + +std::vector> HumanDebugAPI::GetProps() const +{ + return logic.GetProps(); +} + +std::vector> ButcherDebugAPI::GetProps() const +{ + return logic.GetProps(); +} + +std::vector> HumanDebugAPI::GetFullMap() const +{ + return logic.GetFullMap(); +} + +THUAI6::PlaceType HumanDebugAPI::GetPlaceType(int32_t CellX, int32_t CellY) const +{ + return logic.GetPlaceType(CellX, CellY); +} + +THUAI6::PlaceType ButcherDebugAPI::GetPlaceType(int32_t CellX, int32_t CellY) const +{ + return logic.GetPlaceType(CellX, CellY); +} + +std::vector> ButcherDebugAPI::GetFullMap() const +{ + return logic.GetFullMap(); +} + +const std::vector HumanDebugAPI::GetPlayerGUIDs() const +{ + // todo +} + +const std::vector ButcherDebugAPI::GetPlayerGUIDs() const +{ + // todo +} + +std::future HumanDebugAPI::StartFixMachine() +{ + std::async(std::launch::async, [&]() + { return logic.StartFixMachine(); }); +} + +std::future HumanDebugAPI::EndFixMachine() +{ + std::async(std::launch::async, [&]() + { return logic.EndFixMachine(); }); +} + +std::future HumanDebugAPI::StartSaveHuman() +{ + std::async(std::launch::async, [&]() + { return logic.StartSaveHuman(); }); +} + +std::future HumanDebugAPI::EndSaveHuman() +{ + std::async(std::launch::async, [&]() + { return logic.EndSaveHuman(); }); +} + +std::future HumanDebugAPI::Escape() +{ + return std::async(std::launch::async, [&]() + { return logic.Escape(); }); +} + +std::shared_ptr HumanDebugAPI::GetSelfInfo() const +{ + return logic.HumanGetSelfInfo(); +} + +std::future ButcherDebugAPI::Attack(double angleInRadian) +{ + return std::async(std::launch::async, [&]() + { return logic.Attack(angleInRadian); }); +} + +std::future ButcherDebugAPI::CarryHuman() +{ + return std::async(std::launch::async, [&]() + { return logic.CarryHuman(); }); +} + +std::future ButcherDebugAPI::ReleaseHuman() +{ + return std::async(std::launch::async, [&]() + { return logic.ReleaseHuman(); }); +} + +std::future ButcherDebugAPI::HangHuman() +{ + return std::async(std::launch::async, [&]() + { return logic.HangHuman(); }); +} + +std::shared_ptr ButcherDebugAPI::GetSelfInfo() const +{ + return logic.ButcherGetSelfInfo(); +} void HumanDebugAPI::Play(IAI& ai) { diff --git a/CAPI/API/src/logic.cpp b/CAPI/API/src/logic.cpp index 58621f8..056c03a 100644 --- a/CAPI/API/src/logic.cpp +++ b/CAPI/API/src/logic.cpp @@ -5,9 +5,7 @@ #include "utils.hpp" #include "Communication.h" -// using grpc::ClientContext; -// using grpc::Status; - +extern const bool asynchronous; extern const THUAI6::PlayerType playerType; Logic::Logic(THUAI6::PlayerType type, int64_t ID, THUAI6::ButcherType butcher, THUAI6::HumanType human) : @@ -22,7 +20,7 @@ Logic::Logic(THUAI6::PlayerType type, int64_t ID, THUAI6::ButcherType butcher, T std::vector> Logic::GetButchers() const { - std::lock_guard lock(mtxState); + std::lock_guard lock(mtxBuffer); std::vector> temp; temp.assign(currentState->butchers.begin(), currentState->butchers.end()); return temp; @@ -30,7 +28,7 @@ std::vector> Logic::GetButchers() const std::vector> Logic::GetHumans() const { - std::lock_guard lock(mtxState); + std::unique_lock lock(mtxBuffer); std::vector> temp; temp.assign(currentState->humans.begin(), currentState->humans.end()); return temp; @@ -38,7 +36,7 @@ std::vector> Logic::GetHumans() const std::vector> Logic::GetProps() const { - std::lock_guard lock(mtxState); + std::unique_lock lock(mtxBuffer); std::vector> temp; temp.assign(currentState->props.begin(), currentState->props.end()); return temp; @@ -46,25 +44,25 @@ std::vector> Logic::GetProps() const std::shared_ptr Logic::HumanGetSelfInfo() const { - std::lock_guard lock(mtxState); + std::unique_lock lock(mtxBuffer); return currentState->humanSelf; } std::shared_ptr Logic::ButcherGetSelfInfo() const { - std::lock_guard lock(mtxState); + std::unique_lock lock(mtxBuffer); return currentState->butcherSelf; } std::vector> Logic::GetFullMap() const { - std::lock_guard lock(mtxState); + std::unique_lock lock(mtxBuffer); return currentState->gamemap; } THUAI6::PlaceType Logic::GetPlaceType(int32_t CellX, int32_t CellY) const { - std::lock_guard lock(mtxState); + std::unique_lock lock(mtxBuffer); return currentState->gamemap[CellX][CellY]; } @@ -148,6 +146,12 @@ bool Logic::HangHuman() return pComm->HangHuman(playerID); } +bool Logic::WaitThread() +{ + Update(); + return true; +} + void Logic::ProcessMessage() { auto messageThread = [&]() @@ -207,12 +211,70 @@ void Logic::LoadBuffer(protobuf::MessageToClient& message) } bufferState->gamemap = Proto2THUAI6::Protobuf2THUAI6Map(message.map_message()); - cvBuffer.notify_one(); + if (asynchronous) + { + { + std::lock_guard lock(mtxState); + std::swap(currentState, bufferState); + } + freshed = true; + } + else + bufferUpdated = true; + counterBuffer++; } + // 唤醒其他线程 + cvBuffer.notify_one(); } void Logic::Update() noexcept { + if (!asynchronous) + { + std::unique_lock lock(mtxBuffer); + + // 缓冲区被更新之后才可以使用 + cvBuffer.wait(lock, [&]() + { return bufferUpdated; }); + + std::swap(currentState, bufferState); + bufferUpdated = false; + counterState = counterBuffer; + } +} + +void Logic::Wait() noexcept +{ + freshed = false; + { + std::unique_lock lock(mtxBuffer); + cvBuffer.wait(lock, [&]() + { return freshed.load(); }); + } +} + +void Logic::UnBlockAI() +{ + { + std::lock_guard lock(mtxAI); + AIStart = true; + } + cvAI.notify_one(); +} + +void Logic::UnBlockBuffer() +{ + { + std::lock_guard lock(mtxBuffer); + bufferUpdated = true; + } + cvBuffer.notify_one(); +} + +int Logic::GetCounter() const +{ + std::unique_lock lock(mtxState); + return counterState; } bool Logic::TryConnection() @@ -244,6 +306,7 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port) cvAI.wait(lock, [this]() { return AIStart; }); } + std::cout << "AI Start!" << std::endl; auto ai = createAI(); ProcessMessage(); while (AILoop) @@ -265,6 +328,7 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port) { std::cout << "Join the AI thread." << std::endl; AIStart = true; + cvAI.notify_one(); tAI.join(); } } diff --git a/CAPI/API/src/main.cpp b/CAPI/API/src/main.cpp index 39846cf..3debc05 100644 --- a/CAPI/API/src/main.cpp +++ b/CAPI/API/src/main.cpp @@ -6,11 +6,13 @@ #pragma warning(disable : 4996) #endif +extern const bool asynchronous; + int THUAI6Main(CreateAIFunc AIBuilder) { // 仅供调试使用 int playerID = 123; - std::string sIP = "183.172.208.226"; + std::string sIP = "183.172.208.84"; std::string sPort = "8888"; extern const THUAI6::PlayerType playerType; extern const THUAI6::ButcherType butcherType;