Browse Source

Merge pull request #63 from DragonAura/dev

feat(CAPI):  complete basic logic
tags/0.1.0
wihn GitHub 2 years ago
parent
commit
8f96a375e6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 210 additions and 82 deletions
  1. +20
    -43
      CAPI/API/include/API.h
  2. +4
    -6
      CAPI/API/include/logic.h
  3. +9
    -0
      CAPI/API/include/structures.h
  4. +7
    -0
      CAPI/API/include/utils.hpp
  5. +40
    -10
      CAPI/API/src/API.cpp
  6. +60
    -10
      CAPI/API/src/DebugAPI.cpp
  7. +70
    -13
      CAPI/API/src/logic.cpp

+ 20
- 43
CAPI/API/include/API.h View File

@@ -63,6 +63,8 @@ public:
virtual bool CarryHuman() = 0; virtual bool CarryHuman() = 0;
virtual bool ReleaseHuman() = 0; virtual bool ReleaseHuman() = 0;
virtual bool HangHuman() = 0; virtual bool HangHuman() = 0;

virtual const std::vector<int64_t> GetPlayerGUIDs() const = 0;
}; };


class IAPI class IAPI
@@ -171,11 +173,9 @@ public:
} }
void Play(IAI& ai) override; void Play(IAI& ai) override;


std::future<bool> Move(int64_t timeInMilliseconds, double angleInRadian) override;
[[nodiscard]] int GetFrameCount() const override;


[[nodiscard]] int GetFrameCount() const override
{
}
std::future<bool> Move(int64_t timeInMilliseconds, double angleInRadian) override;


std::future<bool> MoveRight(int64_t timeInMilliseconds) override; std::future<bool> MoveRight(int64_t timeInMilliseconds) override;
std::future<bool> MoveUp(int64_t timeInMilliseconds) override; std::future<bool> MoveUp(int64_t timeInMilliseconds) override;
@@ -190,9 +190,7 @@ public:
[[nodiscard]] std::future<bool> HaveMessage() override; [[nodiscard]] std::future<bool> HaveMessage() override;
[[nodiscard]] std::future<std::pair<int64_t, std::string>> GetMessage() override; [[nodiscard]] std::future<std::pair<int64_t, std::string>> GetMessage() override;


std::future<bool> Wait() override
{
}
std::future<bool> Wait() override;


[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Human>> GetHuman() const override; [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Human>> GetHuman() const override;
[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Butcher>> GetButcher() const override; [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Butcher>> GetButcher() const override;
@@ -230,12 +228,9 @@ public:
} }
void Play(IAI& ai) override; void Play(IAI& ai) override;


std::future<bool> Move(int64_t timeInMilliseconds, double angleInRadian) override;

[[nodiscard]] int GetFrameCount() const override
{
}
[[nodiscard]] int GetFrameCount() const override;


std::future<bool> Move(int64_t timeInMilliseconds, double angleInRadian) override;
std::future<bool> MoveRight(int64_t timeInMilliseconds) override; std::future<bool> MoveRight(int64_t timeInMilliseconds) override;
std::future<bool> MoveUp(int64_t timeInMilliseconds) override; std::future<bool> MoveUp(int64_t timeInMilliseconds) override;
std::future<bool> MoveLeft(int64_t timeInMilliseconds) override; std::future<bool> MoveLeft(int64_t timeInMilliseconds) override;
@@ -249,9 +244,7 @@ public:
[[nodiscard]] std::future<bool> HaveMessage() override; [[nodiscard]] std::future<bool> HaveMessage() override;
[[nodiscard]] std::future<std::pair<int64_t, std::string>> GetMessage() override; [[nodiscard]] std::future<std::pair<int64_t, std::string>> GetMessage() override;


std::future<bool> Wait() override
{
}
std::future<bool> Wait() override;


[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Human>> GetHuman() const override; [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Human>> GetHuman() const override;
[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Butcher>> GetButcher() const override; [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Butcher>> GetButcher() const override;
@@ -280,20 +273,13 @@ public:
logic(logic) logic(logic)
{ {
} }
void StartTimer() override
{
}
void EndTimer() override
{
}
void StartTimer() override;
void EndTimer() override;
void Play(IAI& ai) override; void Play(IAI& ai) override;


std::future<bool> Move(int64_t timeInMilliseconds, double angleInRadian) override;

[[nodiscard]] int GetFrameCount() const override
{
}
[[nodiscard]] int GetFrameCount() const override;


std::future<bool> Move(int64_t timeInMilliseconds, double angleInRadian) override;
std::future<bool> MoveRight(int64_t timeInMilliseconds) override; std::future<bool> MoveRight(int64_t timeInMilliseconds) override;
std::future<bool> MoveUp(int64_t timeInMilliseconds) override; std::future<bool> MoveUp(int64_t timeInMilliseconds) override;
std::future<bool> MoveLeft(int64_t timeInMilliseconds) override; std::future<bool> MoveLeft(int64_t timeInMilliseconds) override;
@@ -307,9 +293,7 @@ public:
[[nodiscard]] std::future<bool> HaveMessage() override; [[nodiscard]] std::future<bool> HaveMessage() override;
[[nodiscard]] std::future<std::pair<int64_t, std::string>> GetMessage() override; [[nodiscard]] std::future<std::pair<int64_t, std::string>> GetMessage() override;


std::future<bool> Wait() override
{
}
std::future<bool> Wait() override;


[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Human>> GetHuman() const override; [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Human>> GetHuman() const override;
[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Butcher>> GetButcher() const override; [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Butcher>> GetButcher() const override;
@@ -329,6 +313,7 @@ public:
[[nodiscard]] virtual std::shared_ptr<const THUAI6::Human> GetSelfInfo() const override; [[nodiscard]] virtual std::shared_ptr<const THUAI6::Human> GetSelfInfo() const override;


private: private:
std::chrono::system_clock::time_point StartPoint;
ILogic& logic; ILogic& logic;
}; };


@@ -339,20 +324,13 @@ public:
logic(logic) logic(logic)
{ {
} }
void StartTimer() override
{
}
void EndTimer() override
{
}
void StartTimer() override;
void EndTimer() override;
void Play(IAI& ai) override; void Play(IAI& ai) override;


std::future<bool> Move(int64_t timeInMilliseconds, double angleInRadian) override;

[[nodiscard]] int GetFrameCount() const override
{
}
[[nodiscard]] int GetFrameCount() const override;


std::future<bool> Move(int64_t timeInMilliseconds, double angleInRadian) override;
std::future<bool> MoveRight(int64_t timeInMilliseconds) override; std::future<bool> MoveRight(int64_t timeInMilliseconds) override;
std::future<bool> MoveUp(int64_t timeInMilliseconds) override; std::future<bool> MoveUp(int64_t timeInMilliseconds) override;
std::future<bool> MoveLeft(int64_t timeInMilliseconds) override; std::future<bool> MoveLeft(int64_t timeInMilliseconds) override;
@@ -366,9 +344,7 @@ public:
[[nodiscard]] std::future<bool> HaveMessage() override; [[nodiscard]] std::future<bool> HaveMessage() override;
[[nodiscard]] std::future<std::pair<int64_t, std::string>> GetMessage() override; [[nodiscard]] std::future<std::pair<int64_t, std::string>> GetMessage() override;


std::future<bool> Wait() override
{
}
std::future<bool> Wait() override;


[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Human>> GetHuman() const override; [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Human>> GetHuman() const override;
[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Butcher>> GetButcher() const override; [[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Butcher>> GetButcher() const override;
@@ -387,6 +363,7 @@ public:
[[nodiscard]] std::shared_ptr<const THUAI6::Butcher> GetSelfInfo() const override; [[nodiscard]] std::shared_ptr<const THUAI6::Butcher> GetSelfInfo() const override;


private: private:
std::chrono::system_clock::time_point StartPoint;
ILogic& logic; ILogic& logic;
}; };



+ 4
- 6
CAPI/API/include/logic.h View File

@@ -43,10 +43,6 @@ private:
// GUID信息 // GUID信息
std::vector<int64_t> playerGUIDs; std::vector<int64_t> playerGUIDs;


// THUAI5中的通信组件可以完全被我们的stub取代,故无须再写

std::unique_ptr<IAI> pAI;

std::unique_ptr<IGameTimer> timer; std::unique_ptr<IGameTimer> timer;


std::thread tAI; // 用于运行AI的线程 std::thread tAI; // 用于运行AI的线程
@@ -70,6 +66,8 @@ private:
int counterState = 0; int counterState = 0;
int counterBuffer = 0; int counterBuffer = 0;


THUAI6::GameState gameState = THUAI6::GameState::NullGameState;

// 是否应该执行player() // 是否应该执行player()
std::atomic_bool AILoop = true; std::atomic_bool AILoop = true;


@@ -84,8 +82,6 @@ private:


// 提供给API使用的函数 // 提供给API使用的函数


// 获取服务器发来的消息

std::vector<std::shared_ptr<const THUAI6::Butcher>> GetButchers() const override; std::vector<std::shared_ptr<const THUAI6::Butcher>> GetButchers() const override;
std::vector<std::shared_ptr<const THUAI6::Human>> GetHumans() const override; std::vector<std::shared_ptr<const THUAI6::Human>> GetHumans() const override;
std::vector<std::shared_ptr<const THUAI6::Prop>> GetProps() const override; std::vector<std::shared_ptr<const THUAI6::Prop>> GetProps() const override;
@@ -121,6 +117,8 @@ private:


int GetCounter() const override; int GetCounter() const override;


const std::vector<int64_t> GetPlayerGUIDs() const override;

bool TryConnection(); bool TryConnection();


// THUAI5中的一系列用于处理信息的函数可能也不会再用 // THUAI5中的一系列用于处理信息的函数可能也不会再用


+ 9
- 0
CAPI/API/include/structures.h View File

@@ -8,6 +8,15 @@


namespace THUAI6 namespace THUAI6
{ {

// 游戏状态
enum class GameState : unsigned char
{
NullGameState = 0,
GameStart = 1,
GameRunning = 2,
GameEnd = 3,
};
// 所有NullXXXType均为错误类型,其余为可能出现的正常类型 // 所有NullXXXType均为错误类型,其余为可能出现的正常类型


// 位置标志 // 位置标志


+ 7
- 0
CAPI/API/include/utils.hpp View File

@@ -85,6 +85,13 @@ namespace Proto2THUAI6
{protobuf::HumanState::DEAD, THUAI6::HumanState::Dead}, {protobuf::HumanState::DEAD, THUAI6::HumanState::Dead},
}; };


inline std::map<protobuf::GameState, THUAI6::GameState> gameStateDict{
{protobuf::GameState::NULL_GAME_STATE, THUAI6::GameState::NullGameState},
{protobuf::GameState::GAME_START, THUAI6::GameState::GameStart},
{protobuf::GameState::GAME_RUNNING, THUAI6::GameState::GameRunning},
{protobuf::GameState::GAME_END, THUAI6::GameState::GameEnd},
};

// 用于将Protobuf中的类转换为THUAI6的类 // 用于将Protobuf中的类转换为THUAI6的类
inline std::shared_ptr<THUAI6::Butcher> Protobuf2THUAI6Butcher(const protobuf::MessageOfButcher& butcherMsg) inline std::shared_ptr<THUAI6::Butcher> Protobuf2THUAI6Butcher(const protobuf::MessageOfButcher& butcherMsg)
{ {


+ 40
- 10
CAPI/API/src/API.cpp View File

@@ -2,6 +2,16 @@
#include "API.h" #include "API.h"
#define PI 3.14159265358979323846 #define PI 3.14159265358979323846


int HumanAPI::GetFrameCount() const
{
return logic.GetCounter();
}

int ButcherAPI::GetFrameCount() const
{
return logic.GetCounter();
}

std::future<bool> HumanAPI::Move(int64_t timeInMilliseconds, double angleInRadian) std::future<bool> HumanAPI::Move(int64_t timeInMilliseconds, double angleInRadian)
{ {
return std::async(std::launch::async, [&]() return std::async(std::launch::async, [&]()
@@ -126,6 +136,26 @@ std::future<std::pair<int64_t, std::string>> ButcherAPI::GetMessage()
{ return logic.GetMessage(); }); { return logic.GetMessage(); });
} }


std::future<bool> HumanAPI::Wait()
{
if (logic.GetCounter() == -1)
return std::async(std::launch::async, [&]()
{ return false; });
else
return std::async(std::launch::async, [&]()
{ return logic.WaitThread(); });
}

std::future<bool> ButcherAPI::Wait()
{
if (logic.GetCounter() == -1)
return std::async(std::launch::async, [&]()
{ return false; });
else
return std::async(std::launch::async, [&]()
{ return logic.WaitThread(); });
}

std::vector<std::shared_ptr<const THUAI6::Butcher>> HumanAPI::GetButcher() const std::vector<std::shared_ptr<const THUAI6::Butcher>> HumanAPI::GetButcher() const
{ {
return logic.GetButchers(); return logic.GetButchers();
@@ -178,36 +208,36 @@ std::vector<std::vector<THUAI6::PlaceType>> ButcherAPI::GetFullMap() const


const std::vector<int64_t> HumanAPI::GetPlayerGUIDs() const const std::vector<int64_t> HumanAPI::GetPlayerGUIDs() const
{ {
// todo
return logic.GetPlayerGUIDs();
} }


const std::vector<int64_t> ButcherAPI::GetPlayerGUIDs() const const std::vector<int64_t> ButcherAPI::GetPlayerGUIDs() const
{ {
// todo
return logic.GetPlayerGUIDs();
} }


std::future<bool> HumanAPI::StartFixMachine() std::future<bool> HumanAPI::StartFixMachine()
{ {
std::async(std::launch::async, [&]()
{ return logic.StartFixMachine(); });
return std::async(std::launch::async, [&]()
{ return logic.StartFixMachine(); });
} }


std::future<bool> HumanAPI::EndFixMachine() std::future<bool> HumanAPI::EndFixMachine()
{ {
std::async(std::launch::async, [&]()
{ return logic.EndFixMachine(); });
return std::async(std::launch::async, [&]()
{ return logic.EndFixMachine(); });
} }


std::future<bool> HumanAPI::StartSaveHuman() std::future<bool> HumanAPI::StartSaveHuman()
{ {
std::async(std::launch::async, [&]()
{ return logic.StartSaveHuman(); });
return std::async(std::launch::async, [&]()
{ return logic.StartSaveHuman(); });
} }


std::future<bool> HumanAPI::EndSaveHuman() std::future<bool> HumanAPI::EndSaveHuman()
{ {
std::async(std::launch::async, [&]()
{ return logic.EndSaveHuman(); });
return std::async(std::launch::async, [&]()
{ return logic.EndSaveHuman(); });
} }


std::future<bool> HumanAPI::Escape() std::future<bool> HumanAPI::Escape()


+ 60
- 10
CAPI/API/src/DebugAPI.cpp View File

@@ -2,6 +2,36 @@
#include "API.h" #include "API.h"
#define PI 3.14159265358979323846 #define PI 3.14159265358979323846


void HumanDebugAPI::StartTimer()
{
StartPoint = std::chrono::system_clock::now();
std::time_t t = std::chrono::system_clock::to_time_t(StartPoint);
}

void ButcherDebugAPI::StartTimer()
{
StartPoint = std::chrono::system_clock::now();
std::time_t t = std::chrono::system_clock::to_time_t(StartPoint);
}

void HumanDebugAPI::EndTimer()
{
}

void ButcherDebugAPI::EndTimer()
{
}

int HumanDebugAPI::GetFrameCount() const
{
return logic.GetCounter();
}

int ButcherDebugAPI::GetFrameCount() const
{
return logic.GetCounter();
}

std::future<bool> HumanDebugAPI::Move(int64_t timeInMilliseconds, double angleInRadian) std::future<bool> HumanDebugAPI::Move(int64_t timeInMilliseconds, double angleInRadian)
{ {
return std::async(std::launch::async, [&]() return std::async(std::launch::async, [&]()
@@ -126,6 +156,26 @@ std::future<std::pair<int64_t, std::string>> ButcherDebugAPI::GetMessage()
{ return logic.GetMessage(); }); { return logic.GetMessage(); });
} }


std::future<bool> HumanDebugAPI::Wait()
{
if (logic.GetCounter() == -1)
return std::async(std::launch::async, [&]()
{ return false; });
else
return std::async(std::launch::async, [&]()
{ return logic.WaitThread(); });
}

std::future<bool> ButcherDebugAPI::Wait()
{
if (logic.GetCounter() == -1)
return std::async(std::launch::async, [&]()
{ return false; });
else
return std::async(std::launch::async, [&]()
{ return logic.WaitThread(); });
}

std::vector<std::shared_ptr<const THUAI6::Butcher>> HumanDebugAPI::GetButcher() const std::vector<std::shared_ptr<const THUAI6::Butcher>> HumanDebugAPI::GetButcher() const
{ {
return logic.GetButchers(); return logic.GetButchers();
@@ -178,36 +228,36 @@ std::vector<std::vector<THUAI6::PlaceType>> ButcherDebugAPI::GetFullMap() const


const std::vector<int64_t> HumanDebugAPI::GetPlayerGUIDs() const const std::vector<int64_t> HumanDebugAPI::GetPlayerGUIDs() const
{ {
// todo
return logic.GetPlayerGUIDs();
} }


const std::vector<int64_t> ButcherDebugAPI::GetPlayerGUIDs() const const std::vector<int64_t> ButcherDebugAPI::GetPlayerGUIDs() const
{ {
// todo
return logic.GetPlayerGUIDs();
} }


std::future<bool> HumanDebugAPI::StartFixMachine() std::future<bool> HumanDebugAPI::StartFixMachine()
{ {
std::async(std::launch::async, [&]()
{ return logic.StartFixMachine(); });
return std::async(std::launch::async, [&]()
{ return logic.StartFixMachine(); });
} }


std::future<bool> HumanDebugAPI::EndFixMachine() std::future<bool> HumanDebugAPI::EndFixMachine()
{ {
std::async(std::launch::async, [&]()
{ return logic.EndFixMachine(); });
return std::async(std::launch::async, [&]()
{ return logic.EndFixMachine(); });
} }


std::future<bool> HumanDebugAPI::StartSaveHuman() std::future<bool> HumanDebugAPI::StartSaveHuman()
{ {
std::async(std::launch::async, [&]()
{ return logic.StartSaveHuman(); });
return std::async(std::launch::async, [&]()
{ return logic.StartSaveHuman(); });
} }


std::future<bool> HumanDebugAPI::EndSaveHuman() std::future<bool> HumanDebugAPI::EndSaveHuman()
{ {
std::async(std::launch::async, [&]()
{ return logic.EndSaveHuman(); });
return std::async(std::launch::async, [&]()
{ return logic.EndSaveHuman(); });
} }


std::future<bool> HumanDebugAPI::Escape() std::future<bool> HumanDebugAPI::Escape()


+ 70
- 13
CAPI/API/src/logic.cpp View File

@@ -158,13 +158,58 @@ void Logic::ProcessMessage()
{ {
std::cout << "Join Player!" << std::endl; std::cout << "Join Player!" << std::endl;
pComm->AddPlayer(playerID, playerType, humanType, butcherType); pComm->AddPlayer(playerID, playerType, humanType, butcherType);
while (true)
while (gameState != THUAI6::GameState::GameEnd)
{ {
if (pComm->HaveMessage2Client()) if (pComm->HaveMessage2Client())
{ {
std::cout << "Get Message!" << std::endl; std::cout << "Get Message!" << std::endl;
auto clientMsg = pComm->GetMessage2Client(); auto clientMsg = pComm->GetMessage2Client();
LoadBuffer(clientMsg);
gameState = Proto2THUAI6::gameStateDict[clientMsg.game_state()];
switch (gameState)
{
case THUAI6::GameState::GameStart:
std::cout << "Game Start!" << std::endl;

// 重新读取玩家的guid,guid确保人类在前屠夫在后
playerGUIDs.clear();
for (auto human : clientMsg.human_message())
playerGUIDs.push_back(human.guid());
for (auto butcher : clientMsg.butcher_message())
playerGUIDs.push_back(butcher.guid());
currentState->guids = playerGUIDs;
bufferState->guids = playerGUIDs;

LoadBuffer(clientMsg);

AILoop = true;
UnBlockAI();

break;
case THUAI6::GameState::GameRunning:
// 重新读取玩家的guid,guid确保人类在前屠夫在后
playerGUIDs.clear();
for (auto human : clientMsg.human_message())
playerGUIDs.push_back(human.guid());
for (auto butcher : clientMsg.butcher_message())
playerGUIDs.push_back(butcher.guid());
currentState->guids = playerGUIDs;
bufferState->guids = playerGUIDs;

LoadBuffer(clientMsg);
break;
case THUAI6::GameState::GameEnd:
AILoop = false;
{
std::lock_guard<std::mutex> lock(mtxBuffer);
bufferUpdated = true;
counterBuffer = -1;
}
cvBuffer.notify_one();
std::cout << "Game End!" << std::endl;
break;
default:
std::cerr << "Invalid GameState!" << std::endl;
}
} }
} }
}; };
@@ -277,6 +322,12 @@ int Logic::GetCounter() const
return counterState; return counterState;
} }


const std::vector<int64_t> Logic::GetPlayerGUIDs() const
{
std::unique_lock<std::mutex> lock(mtxState);
return currentState->guids;
}

bool Logic::TryConnection() bool Logic::TryConnection()
{ {
std::cout << "Trying to connect to server..." << std::endl; std::cout << "Trying to connect to server..." << std::endl;
@@ -286,9 +337,6 @@ bool Logic::TryConnection()


void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port) void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port)
{ {
// 构造AI
pAI = createAI();

// 建立与服务器之间通信的组件 // 建立与服务器之间通信的组件
pComm = std::make_unique<Communication>(IP, port); pComm = std::make_unique<Communication>(IP, port);


@@ -306,15 +354,24 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port)
cvAI.wait(lock, [this]() cvAI.wait(lock, [this]()
{ return AIStart; }); { return AIStart; });
} }
std::cout << "AI Start!" << std::endl;
auto ai = createAI(); auto ai = createAI();
ProcessMessage();
while (AILoop) while (AILoop)
{ {
Update();
timer->StartTimer();
timer->Play(*ai);
timer->EndTimer();
if (asynchronous)
{
Wait();
timer->StartTimer();
timer->Play(*ai);
timer->EndTimer();
}
else
{
Update();
timer->StartTimer();
timer->Play(*ai);
timer->EndTimer();
}
} }
}; };


@@ -327,8 +384,8 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port)
if (tAI.joinable()) if (tAI.joinable())
{ {
std::cout << "Join the AI thread." << std::endl; std::cout << "Join the AI thread." << std::endl;
AIStart = true;
cvAI.notify_one();
// 首先开启处理消息的线程
ProcessMessage();
tAI.join(); tAI.join();
} }
} }


Loading…
Cancel
Save