#pragma once #ifndef API_H #define API_H #ifdef _MSC_VER #pragma warning(disable : 4996) #endif #include "Message2Server.pb.h" #include "Message2Clients.pb.h" #include "MessageType.pb.h" #include "Services.grpc.pb.h" #include "Services.pb.h" #include #include #include #include #include #include #include #include "structures.h" const constexpr int num_of_grid_per_cell = 1000; class IAI; class ILogic { // API中依赖Logic的部分 public: // 获取服务器发来的消息 virtual std::vector> GetButchers() const = 0; virtual std::vector> GetHumans() const = 0; virtual std::vector> GetProps() const = 0; virtual std::shared_ptr HumanGetSelfInfo() const = 0; virtual std::shared_ptr ButcherGetSelfInfo() const = 0; virtual std::vector> GetFullMap() const = 0; virtual THUAI6::PlaceType GetPlaceType(int32_t CellX, int32_t CellY) const = 0; // 供IAPI使用的操作相关的部分 virtual bool Move(int64_t time, double angle) = 0; virtual bool PickProp(THUAI6::PropType prop) = 0; virtual bool UseProp() = 0; virtual bool UseSkill() = 0; virtual bool SendMessage(int64_t toID, std::string message) = 0; virtual bool HaveMessage() = 0; virtual std::optional> GetMessage() = 0; virtual bool WaitThread() = 0; virtual int GetCounter() const = 0; // IHumanAPI使用的部分 virtual bool Escape() = 0; 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 const std::vector GetPlayerGUIDs() const = 0; }; class IAPI { public: // 选手可执行的操作,应当保证所有函数的返回值都应当为std::future,例如下面的移动函数: // 指挥本角色进行移动,`timeInMilliseconds` 为移动时间,单位为毫秒;`angleInRadian` 表示移动的方向,单位是弧度,使用极坐标——竖直向下方向为 x 轴,水平向右方向为 y 轴 virtual std::future Move(int64_t timeInMilliseconds, double angleInRadian) = 0; // 向特定方向移动 virtual std::future MoveRight(int64_t timeInMilliseconds) = 0; virtual std::future MoveUp(int64_t timeInMilliseconds) = 0; virtual std::future MoveLeft(int64_t timeInMilliseconds) = 0; virtual std::future MoveDown(int64_t timeInMilliseconds) = 0; // 捡道具、使用技能 virtual std::future PickProp(THUAI6::PropType prop) = 0; virtual std::future UseProp() = 0; virtual std::future UseSkill() = 0; // 发送信息、接受信息,注意收消息时无消息则返回nullopt virtual std::future SendMessage(int64_t, std::string) = 0; [[nodiscard]] virtual std::future HaveMessage() = 0; [[nodiscard]] virtual std::future>> GetMessage() = 0; // 等待下一帧 virtual std::future Wait() = 0; // 获取视野内可见的人类/屠夫的信息 [[nodiscard]] virtual std::vector> GetHuman() const = 0; [[nodiscard]] virtual std::vector> GetButcher() const = 0; // 获取视野内可见的道具信息 [[nodiscard]] virtual std::vector> GetProps() const = 0; // 获取地图信息,视野外的地图统一为Land [[nodiscard]] virtual std::vector> GetFullMap() const = 0; [[nodiscard]] virtual THUAI6::PlaceType GetPlaceType(int32_t CellX, int32_t CellY) const = 0; // 获取所有玩家的GUID [[nodiscard]] virtual const std::vector GetPlayerGUIDs() const = 0; // 获取游戏目前所进行的帧数 [[nodiscard]] virtual int GetFrameCount() const = 0; /*****选手可能用的辅助函数*****/ // 获取指定格子中心的坐标 [[nodiscard]] static inline int CellToGrid(int cell) noexcept { return cell * num_of_grid_per_cell + num_of_grid_per_cell / 2; } // 获取指定坐标点所位于的格子的 X 序号 [[nodiscard]] static inline int GridToCell(int grid) noexcept { return grid / num_of_grid_per_cell; } }; class IHumanAPI : public IAPI { public: /*****人类阵营的特定函数*****/ virtual std::future StartFixMachine() = 0; virtual std::future EndFixMachine() = 0; virtual std::future StartSaveHuman() = 0; virtual std::future EndSaveHuman() = 0; virtual std::future Escape() = 0; [[nodiscard]] virtual std::shared_ptr GetSelfInfo() const = 0; }; class IButcherAPI : public IAPI { public: /*****屠夫阵营的特定函数*****/ virtual std::future Attack(double angleInRadian) = 0; virtual std::future CarryHuman() = 0; virtual std::future ReleaseHuman() = 0; virtual std::future HangHuman() = 0; [[nodiscard]] virtual std::shared_ptr GetSelfInfo() const = 0; }; class IGameTimer { public: virtual void StartTimer() = 0; virtual void EndTimer() = 0; virtual void Play(IAI& ai) = 0; }; class HumanAPI : public IHumanAPI, public IGameTimer { public: HumanAPI(ILogic& logic) : logic(logic) { } void StartTimer() override { } void EndTimer() override { } void Play(IAI& ai) override; [[nodiscard]] int GetFrameCount() const override; std::future Move(int64_t timeInMilliseconds, double angleInRadian) 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 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> GetProps() 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; std::future StartFixMachine() override; std::future EndFixMachine() override; std::future StartSaveHuman() override; std::future EndSaveHuman() override; std::future Escape() override; [[nodiscard]] std::shared_ptr GetSelfInfo() const override; private: ILogic& logic; }; class ButcherAPI : public IButcherAPI, public IGameTimer { public: ButcherAPI(ILogic& logic) : logic(logic) { } void StartTimer() override { } void EndTimer() override { } void Play(IAI& ai) override; [[nodiscard]] int GetFrameCount() const override; std::future Move(int64_t timeInMilliseconds, double angleInRadian) 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 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> GetProps() 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; 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; }; class HumanDebugAPI : public IHumanAPI, public IGameTimer { public: HumanDebugAPI(ILogic& logic, bool file, bool print, bool warnOnly, int64_t playerID); void StartTimer() override; void EndTimer() override; void Play(IAI& ai) override; [[nodiscard]] int GetFrameCount() const override; std::future Move(int64_t timeInMilliseconds, double angleInRadian) 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 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> GetProps() 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; 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: std::chrono::system_clock::time_point startPoint; std::unique_ptr logger; ILogic& logic; }; class ButcherDebugAPI : public IButcherAPI, public IGameTimer { public: ButcherDebugAPI(ILogic& logic, bool file, bool print, bool warnOnly, int64_t playerID); void StartTimer() override; void EndTimer() override; void Play(IAI& ai) override; [[nodiscard]] int GetFrameCount() const override; std::future Move(int64_t timeInMilliseconds, double angleInRadian) 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 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> GetProps() 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; 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: std::chrono::system_clock::time_point startPoint; std::unique_ptr logger; ILogic& logic; }; #endif