Browse Source

Merge pull request #102 from DragonAura/dev

refactor(API): 🎨 add HaveView function
tags/0.1.0
Timothy Liu GitHub 2 years ago
parent
commit
40bf1a0755
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 87 additions and 97 deletions
  1. +36
    -0
      CAPI/API/include/utils.hpp
  2. +2
    -55
      CAPI/API/src/logic.cpp
  3. +16
    -1
      PyAPI/PyAPI/AI.py
  4. +1
    -1
      PyAPI/PyAPI/DebugAPI.py
  5. +8
    -36
      PyAPI/PyAPI/logic.py
  6. +23
    -3
      PyAPI/PyAPI/utils.py
  7. +1
    -1
      PyAPI/requirements.txt

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

@@ -10,6 +10,42 @@

#include "structures.h"

namespace AssistFunction
{

constexpr int numOfGridPerCell = 100;

[[nodiscard]] constexpr inline int GridToCell(int grid) noexcept
{
return grid / numOfGridPerCell;
}

inline bool HaveView(int viewRange, int x, int y, int newX, int newY, const std::vector<std::vector<THUAI6::PlaceType>>& map)
{
int deltaX = newX - x;
int deltaY = newY - y;
double distance = deltaX * deltaX + deltaY * deltaY;
if (distance < viewRange * viewRange)
{
int divide = std::max(std::abs(deltaX), std::abs(deltaY)) / 100;
double dx = deltaX / divide;
double dy = deltaY / divide;
double myX = double(x);
double myY = double(y);
for (int i = 0; i < divide; i++)
{
myX += dx;
myY += dy;
if (map[GridToCell(myX)][GridToCell(myY)] != THUAI6::PlaceType::Land)
return false;
}
return true;
}
else
return false;
}
} // namespace AssistFunction

// 辅助函数,用于将proto信息转换为THUAI6信息
namespace Proto2THUAI6
{


+ 2
- 55
CAPI/API/src/logic.cpp View File

@@ -252,7 +252,6 @@ void Logic::LoadBuffer(protobuf::MessageToClient& message)

logger->debug("Buffer cleared!");
// 读取新的信息
// 读取消息的选择待补充,之后需要另外判断;具体做法应该是先读到自己,然后按照自己的视野做处理。此处暂时全部读了进来
bufferState->gamemap = Proto2THUAI6::Protobuf2THUAI6Map(message.map_message());
if (playerType == THUAI6::PlayerType::HumanPlayer)
{
@@ -267,33 +266,8 @@ void Logic::LoadBuffer(protobuf::MessageToClient& message)
}
for (const auto& item : message.butcher_message())
{
int vr = this->bufferState->humanSelf->viewRange;
int deltaX = item.x() - this->bufferState->humanSelf->x;
int deltaY = item.y() - this->bufferState->humanSelf->y;
double distance = deltaX * deltaX + deltaY * deltaY;
if (distance > vr * vr)
continue;
else
if (AssistFunction::HaveView(bufferState->humanSelf->viewRange, bufferState->humanSelf->x, bufferState->humanSelf->y, item.x(), item.y(), bufferState->gamemap))
{
int divide = abs(deltaX) > abs(deltaY) ? abs(deltaX) : abs(deltaY);
divide /= 100;
double dx = deltaX / divide;
double dy = deltaY / divide;
double myX = this->bufferState->humanSelf->x;
double myY = this->bufferState->humanSelf->y;
bool barrier = false;
for (int i = 0; i < divide; i++)
{
myX += dx;
myY += dy;
if (this->bufferState->gamemap[IAPI::GridToCell(myX)][IAPI::GridToCell(myY)] == THUAI6::PlaceType::Wall)
{
barrier = true;
break;
}
}
if (barrier)
continue;
bufferState->butchers.push_back(Proto2THUAI6::Protobuf2THUAI6Butcher(item));
logger->debug("Add Butcher!");
}
@@ -311,38 +285,11 @@ void Logic::LoadBuffer(protobuf::MessageToClient& message)
logger->debug("Add Butcher!");
}
for (const auto& item : message.human_message())
{
int vr = this->bufferState->butcherSelf->viewRange;
int deltaX = item.x() - this->bufferState->butcherSelf->x;
int deltaY = item.y() - this->bufferState->butcherSelf->y;
double distance = deltaX * deltaX + deltaY * deltaY;
if (distance > vr * vr)
continue;
else
if (AssistFunction::HaveView(bufferState->butcherSelf->viewRange, bufferState->butcherSelf->x, bufferState->butcherSelf->y, item.x(), item.y(), bufferState->gamemap))
{
int divide = abs(deltaX) > abs(deltaY) ? abs(deltaX) : abs(deltaY);
divide /= 100;
double dx = deltaX / divide;
double dy = deltaY / divide;
double myX = this->bufferState->butcherSelf->x;
double myY = this->bufferState->butcherSelf->y;
bool barrier = false;
for (int i = 0; i < divide; i++)
{
myX += dx;
myY += dy;
if (this->bufferState->gamemap[IAPI::GridToCell(myX)][IAPI::GridToCell(myY)] == THUAI6::PlaceType::Wall)
{
barrier = true;
break;
}
}
if (barrier)
continue;
bufferState->humans.push_back(Proto2THUAI6::Protobuf2THUAI6Human(item));
logger->debug("Add Human!");
}
}
}
for (const auto& item : message.prop_message())
{


+ 16
- 1
PyAPI/PyAPI/AI.py View File

@@ -1,6 +1,6 @@
import PyAPI.structures as THUAI6
from PyAPI.Interface import IHumanAPI, IButcherAPI, IAI
from typing import Union
from typing import Union, Final


class Setting:
@@ -24,6 +24,21 @@ class Setting:
return THUAI6.ButcherType.ButcherType1


# 辅助函数
numOfGridPerCell: Final[int] = 1000


class AssistFunction:

@staticmethod
def CellToGrid(cell: int) -> int:
return cell * numOfGridPerCell + numOfGridPerCell // 2

@staticmethod
def GridToCell(grid: int) -> int:
return grid // numOfGridPerCell


class AI(IAI):
def play(self, api: Union[IHumanAPI, IButcherAPI]) -> None:
# 选手在这里实现自己的逻辑,要求和上面选择的阵营保持一致,否则会发生错误


+ 1
- 1
PyAPI/PyAPI/DebugAPI.py View File

@@ -509,7 +509,7 @@ class ButcherDebugAPI(IButcherAPI, IGameTimer):

# 用于DEBUG的输出函数,仅在DEBUG模式下有效

def PrintHuman(self) -> None:
def PrintHuman(self) -> None:
for human in self.__logic.GetHumans():
self.__logger.info("******Human Info******")
self.__logger.info(


+ 8
- 36
PyAPI/PyAPI/logic.py View File

@@ -250,24 +250,10 @@ class Logic(ILogic):
Proto2THUAI6.Protobuf2THUAI6Human(human))
self.__logger.debug("Add Human!")
for butcher in message.butcher_message:
viewRange: int = self.__bufferState.self.viewRange
deltaX: int = butcher.x - self.__bufferState.self.x
deltaY: int = butcher.y - self.__bufferState.self.y
if deltaX * deltaX + deltaY * deltaY <= viewRange * viewRange:
divide: int = max(abs(deltaX), abs(deltaY)) // 100
dx: float = deltaX / divide
dy: float = deltaY / divide
selfX: float = self.__bufferState.self.x
selfY: float = self.__bufferState.self.y
for i in range(divide):
selfX += dx
selfY += dy
if self.__bufferState.map[AssistFunction.GridToCell(int(selfX))][AssistFunction.GridToCell(int(selfY))]:
break
else:
self.__bufferState.butchers.append(
Proto2THUAI6.Protobuf2THUAI6Butcher(butcher))
self.__logger.debug("Add Butcher!")
if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, butcher.x, butcher.y, self.__bufferState.map):
self.__bufferState.butchers.append(
Proto2THUAI6.Protobuf2THUAI6Butcher(butcher))
self.__logger.debug("Add Butcher!")
else:
for butcher in message.butcher_message:
if butcher.player_id == self.__playerID:
@@ -277,24 +263,10 @@ class Logic(ILogic):
Proto2THUAI6.Protobuf2THUAI6Butcher(butcher))
self.__logger.debug("Add Butcher!")
for human in message.human_message:
viewRange: int = self.__bufferState.self.viewRange
deltaX: int = human.x - self.__bufferState.self.x
deltaY: int = human.y - self.__bufferState.self.y
if deltaX * deltaX + deltaY * deltaY <= viewRange * viewRange:
divide: int = max(abs(deltaX), abs(deltaY)) // 100
dx: float = deltaX / divide
dy: float = deltaY / divide
selfX: float = self.__bufferState.self.x
selfY: float = self.__bufferState.self.y
for i in range(divide):
selfX += dx
selfY += dy
if self.__bufferState.map[AssistFunction.GridToCell(int(selfX))][AssistFunction.GridToCell(int(selfY))]:
break
else:
self.__bufferState.humans.append(
Proto2THUAI6.Protobuf2THUAI6Human(human))
self.__logger.debug("Add Human!")
if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, human.x, human.y, self.__bufferState.map):
self.__bufferState.humans.append(
Proto2THUAI6.Protobuf2THUAI6Human(human))
self.__logger.debug("Add Human!")
for prop in message.prop_message:
self.__bufferState.props.append(
Proto2THUAI6.Protobuf2THUAI6Prop(prop))


+ 23
- 3
PyAPI/PyAPI/utils.py View File

@@ -4,18 +4,18 @@ import proto.Message2Clients_pb2 as Message2Clients
import PyAPI.structures as THUAI6
from typing import Final, List


numOfGridPerCell: Final[int] = 1000


# 起到NameSpace的作用


class NoInstance:
def __call__(self):
raise TypeError("This class cannot be instantiated.")


class AssistFunction(NoInstance):
# 辅助函数
@staticmethod
def CellToGrid(cell: int) -> int:
return cell * numOfGridPerCell + numOfGridPerCell // 2
@@ -24,6 +24,26 @@ class AssistFunction(NoInstance):
def GridToCell(grid: int) -> int:
return grid // numOfGridPerCell

@staticmethod
def HaveView(viewRange: int, x: int, y: int, newX: int, newY: int, map: List[List[THUAI6.PlaceType]]) -> bool:
deltaX: int = newX - x
deltaY: int = newY - y
if deltaX * deltaX + deltaY * deltaY <= viewRange * viewRange:
divide: int = max(abs(deltaX), abs(deltaY)) // 100
dx: float = deltaX / divide
dy: float = deltaY / divide
selfX: float = float(x)
selfY: float = float(y)
for i in range(divide):
selfX += dx
selfY += dy
if map[AssistFunction.GridToCell(int(selfX))][AssistFunction.GridToCell(int(selfY))] != THUAI6.PlaceType.Land:
return False
else:
return True
else:
return False


class Proto2THUAI6(NoInstance):
placeTypeDict: Final[dict] = {


+ 1
- 1
PyAPI/requirements.txt View File

@@ -1,2 +1,2 @@
grpcio==1.51.1
grpcio-tools=1.49.1
grpcio-tools==1.49.1

Loading…
Cancel
Save