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 ReleaseHuman() = 0;
virtual bool HangHuman() = 0;

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

class IAPI
@@ -171,11 +173,9 @@ public:
}
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> MoveUp(int64_t timeInMilliseconds) override;
@@ -190,9 +190,7 @@ public:
[[nodiscard]] std::future<bool> HaveMessage() 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::Butcher>> GetButcher() const override;
@@ -230,12 +228,9 @@ public:
}
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> MoveUp(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<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::Butcher>> GetButcher() const override;
@@ -280,20 +273,13 @@ public:
logic(logic)
{
}
void StartTimer() override
{
}
void EndTimer() override
{
}
void StartTimer() override;
void EndTimer() 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> MoveUp(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<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::Butcher>> GetButcher() const override;
@@ -329,6 +313,7 @@ public:
[[nodiscard]] virtual std::shared_ptr<const THUAI6::Human> GetSelfInfo() const override;

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

@@ -339,20 +324,13 @@ public:
logic(logic)
{
}
void StartTimer() override
{
}
void EndTimer() override
{
}
void StartTimer() override;
void EndTimer() 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> MoveUp(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<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::Butcher>> GetButcher() const override;
@@ -387,6 +363,7 @@ public:
[[nodiscard]] std::shared_ptr<const THUAI6::Butcher> GetSelfInfo() const override;

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


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

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

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

std::unique_ptr<IAI> pAI;

std::unique_ptr<IGameTimer> timer;

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

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

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

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

// 提供给API使用的函数

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

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::Prop>> GetProps() const override;
@@ -121,6 +117,8 @@ private:

int GetCounter() const override;

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

bool TryConnection();

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


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

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

namespace THUAI6
{

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

// 位置标志


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

@@ -85,6 +85,13 @@ namespace Proto2THUAI6
{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的类
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"
#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)
{
return std::async(std::launch::async, [&]()
@@ -126,6 +136,26 @@ std::future<std::pair<int64_t, std::string>> ButcherAPI::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
{
return logic.GetButchers();
@@ -178,36 +208,36 @@ std::vector<std::vector<THUAI6::PlaceType>> ButcherAPI::GetFullMap() const

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

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

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::async(std::launch::async, [&]()
{ return logic.EndFixMachine(); });
return std::async(std::launch::async, [&]()
{ return logic.EndFixMachine(); });
}

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::async(std::launch::async, [&]()
{ return logic.EndSaveHuman(); });
return std::async(std::launch::async, [&]()
{ return logic.EndSaveHuman(); });
}

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


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

@@ -2,6 +2,36 @@
#include "API.h"
#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)
{
return std::async(std::launch::async, [&]()
@@ -126,6 +156,26 @@ std::future<std::pair<int64_t, std::string>> ButcherDebugAPI::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
{
return logic.GetButchers();
@@ -178,36 +228,36 @@ std::vector<std::vector<THUAI6::PlaceType>> ButcherDebugAPI::GetFullMap() const

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

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

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::async(std::launch::async, [&]()
{ return logic.EndFixMachine(); });
return std::async(std::launch::async, [&]()
{ return logic.EndFixMachine(); });
}

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::async(std::launch::async, [&]()
{ return logic.EndSaveHuman(); });
return std::async(std::launch::async, [&]()
{ return logic.EndSaveHuman(); });
}

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;
pComm->AddPlayer(playerID, playerType, humanType, butcherType);
while (true)
while (gameState != THUAI6::GameState::GameEnd)
{
if (pComm->HaveMessage2Client())
{
std::cout << "Get Message!" << std::endl;
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;
}

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

bool Logic::TryConnection()
{
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)
{
// 构造AI
pAI = createAI();

// 建立与服务器之间通信的组件
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]()
{ return AIStart; });
}
std::cout << "AI Start!" << std::endl;
auto ai = createAI();
ProcessMessage();
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())
{
std::cout << "Join the AI thread." << std::endl;
AIStart = true;
cvAI.notify_one();
// 首先开启处理消息的线程
ProcessMessage();
tAI.join();
}
}


Loading…
Cancel
Save