Browse Source

Merge branch 'eesast:dev' into new

tags/v0.1.0
shangfengh GitHub 2 years ago
parent
commit
859794ed98
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 903 additions and 418 deletions
  1. +3
    -0
      CAPI/cpp/API/include/Communication.h
  2. +107
    -2
      CAPI/cpp/API/src/Communication.cpp
  3. +2
    -0
      CAPI/cpp/proto/Services.grpc.pb.h
  4. +14
    -4
      CAPI/python/PyAPI/API.py
  5. +112
    -20
      CAPI/python/PyAPI/Communication.py
  6. +215
    -184
      CAPI/python/PyAPI/DebugAPI.py
  7. +3
    -6
      CAPI/python/PyAPI/Interface.py
  8. +1
    -0
      CAPI/python/PyAPI/State.py
  9. +59
    -55
      CAPI/python/PyAPI/constants.py
  10. +225
    -79
      CAPI/python/PyAPI/logic.py
  11. +47
    -16
      CAPI/python/PyAPI/main.py
  12. +115
    -52
      CAPI/python/PyAPI/utils.py

+ 3
- 0
CAPI/cpp/API/include/Communication.h View File

@@ -57,6 +57,9 @@ private:
bool haveNewMessage = false; bool haveNewMessage = false;
protobuf::MessageToClient message2Client; protobuf::MessageToClient message2Client;
std::mutex mtxMessage; std::mutex mtxMessage;
std::mutex mtxLimit;
int counter;
static constexpr const int limit = 50;
std::condition_variable cvMessage; std::condition_variable cvMessage;
}; };




+ 107
- 2
CAPI/cpp/API/src/Communication.cpp View File

@@ -20,6 +20,12 @@ Communication::Communication(std::string sIP, std::string sPort)


bool Communication::Move(int64_t time, double angle, int64_t playerID) bool Communication::Move(int64_t time, double angle, int64_t playerID)
{ {
{
std::lock_guard<std::mutex> lock(mtxLimit);
if (counter > limit)
return false;
counter++;
}
protobuf::MoveRes moveResult; protobuf::MoveRes moveResult;
ClientContext context; ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufMove(time, angle, playerID); auto request = THUAI62Proto::THUAI62ProtobufMove(time, angle, playerID);
@@ -32,6 +38,12 @@ bool Communication::Move(int64_t time, double angle, int64_t playerID)


bool Communication::PickProp(THUAI6::PropType prop, int64_t playerID) bool Communication::PickProp(THUAI6::PropType prop, int64_t playerID)
{ {
{
std::lock_guard<std::mutex> lock(mtxLimit);
if (counter > limit)
return false;
counter++;
}
protobuf::BoolRes pickPropResult; protobuf::BoolRes pickPropResult;
ClientContext context; ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufProp(prop, playerID); auto request = THUAI62Proto::THUAI62ProtobufProp(prop, playerID);
@@ -44,6 +56,12 @@ bool Communication::PickProp(THUAI6::PropType prop, int64_t playerID)


bool Communication::UseProp(THUAI6::PropType prop, int64_t playerID) bool Communication::UseProp(THUAI6::PropType prop, int64_t playerID)
{ {
{
std::lock_guard<std::mutex> lock(mtxLimit);
if (counter > limit)
return false;
counter++;
}
protobuf::BoolRes usePropResult; protobuf::BoolRes usePropResult;
ClientContext context; ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufProp(prop, playerID); auto request = THUAI62Proto::THUAI62ProtobufProp(prop, playerID);
@@ -56,6 +74,12 @@ bool Communication::UseProp(THUAI6::PropType prop, int64_t playerID)


bool Communication::ThrowProp(THUAI6::PropType prop, int64_t playerID) bool Communication::ThrowProp(THUAI6::PropType prop, int64_t playerID)
{ {
{
std::lock_guard<std::mutex> lock(mtxLimit);
if (counter > limit)
return false;
counter++;
}
protobuf::BoolRes throwPropResult; protobuf::BoolRes throwPropResult;
ClientContext context; ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufProp(prop, playerID); auto request = THUAI62Proto::THUAI62ProtobufProp(prop, playerID);
@@ -68,6 +92,12 @@ bool Communication::ThrowProp(THUAI6::PropType prop, int64_t playerID)


bool Communication::UseSkill(int32_t skillID, int64_t playerID) bool Communication::UseSkill(int32_t skillID, int64_t playerID)
{ {
{
std::lock_guard<std::mutex> lock(mtxLimit);
if (counter > limit)
return false;
counter++;
}
protobuf::BoolRes useSkillResult; protobuf::BoolRes useSkillResult;
ClientContext context; ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufSkill(skillID, playerID); auto request = THUAI62Proto::THUAI62ProtobufSkill(skillID, playerID);
@@ -80,6 +110,12 @@ bool Communication::UseSkill(int32_t skillID, int64_t playerID)


bool Communication::SendMessage(int64_t toID, std::string message, bool binary, int64_t playerID) bool Communication::SendMessage(int64_t toID, std::string message, bool binary, int64_t playerID)
{ {
{
std::lock_guard<std::mutex> lock(mtxLimit);
if (counter > limit)
return false;
counter++;
}
protobuf::BoolRes sendMessageResult; protobuf::BoolRes sendMessageResult;
ClientContext context; ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufSend(message, toID, binary, playerID); auto request = THUAI62Proto::THUAI62ProtobufSend(message, toID, binary, playerID);
@@ -92,6 +128,12 @@ bool Communication::SendMessage(int64_t toID, std::string message, bool binary,


bool Communication::OpenDoor(int64_t playerID) bool Communication::OpenDoor(int64_t playerID)
{ {
{
std::lock_guard<std::mutex> lock(mtxLimit);
if (counter > limit)
return false;
counter++;
}
protobuf::BoolRes openDoorResult; protobuf::BoolRes openDoorResult;
ClientContext context; ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID); auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
@@ -104,6 +146,12 @@ bool Communication::OpenDoor(int64_t playerID)


bool Communication::CloseDoor(int64_t playerID) bool Communication::CloseDoor(int64_t playerID)
{ {
{
std::lock_guard<std::mutex> lock(mtxLimit);
if (counter > limit)
return false;
counter++;
}
protobuf::BoolRes closeDoorResult; protobuf::BoolRes closeDoorResult;
ClientContext context; ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID); auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
@@ -116,6 +164,12 @@ bool Communication::CloseDoor(int64_t playerID)


bool Communication::SkipWindow(int64_t playerID) bool Communication::SkipWindow(int64_t playerID)
{ {
{
std::lock_guard<std::mutex> lock(mtxLimit);
if (counter > limit)
return false;
counter++;
}
protobuf::BoolRes skipWindowResult; protobuf::BoolRes skipWindowResult;
ClientContext context; ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID); auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
@@ -128,6 +182,12 @@ bool Communication::SkipWindow(int64_t playerID)


bool Communication::StartOpenGate(int64_t playerID) bool Communication::StartOpenGate(int64_t playerID)
{ {
{
std::lock_guard<std::mutex> lock(mtxLimit);
if (counter > limit)
return false;
counter++;
}
protobuf::BoolRes startOpenGateResult; protobuf::BoolRes startOpenGateResult;
ClientContext context; ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID); auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
@@ -140,6 +200,12 @@ bool Communication::StartOpenGate(int64_t playerID)


bool Communication::StartOpenChest(int64_t playerID) bool Communication::StartOpenChest(int64_t playerID)
{ {
{
std::lock_guard<std::mutex> lock(mtxLimit);
if (counter > limit)
return false;
counter++;
}
protobuf::BoolRes startOpenChestResult; protobuf::BoolRes startOpenChestResult;
ClientContext context; ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID); auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
@@ -152,6 +218,12 @@ bool Communication::StartOpenChest(int64_t playerID)


bool Communication::EndAllAction(int64_t playerID) bool Communication::EndAllAction(int64_t playerID)
{ {
{
std::lock_guard<std::mutex> lock(mtxLimit);
if (counter > limit)
return false;
counter++;
}
protobuf::BoolRes endAllActionResult; protobuf::BoolRes endAllActionResult;
ClientContext context; ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID); auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
@@ -164,6 +236,12 @@ bool Communication::EndAllAction(int64_t playerID)


bool Communication::Graduate(int64_t playerID) bool Communication::Graduate(int64_t playerID)
{ {
{
std::lock_guard<std::mutex> lock(mtxLimit);
if (counter > limit)
return false;
counter++;
}
protobuf::BoolRes graduateResult; protobuf::BoolRes graduateResult;
ClientContext context; ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID); auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
@@ -176,6 +254,12 @@ bool Communication::Graduate(int64_t playerID)


bool Communication::StartLearning(int64_t playerID) bool Communication::StartLearning(int64_t playerID)
{ {
{
std::lock_guard<std::mutex> lock(mtxLimit);
if (counter > limit)
return false;
counter++;
}
protobuf::BoolRes startLearningResult; protobuf::BoolRes startLearningResult;
ClientContext context; ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID); auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
@@ -188,6 +272,12 @@ bool Communication::StartLearning(int64_t playerID)


bool Communication::StartRouseMate(int64_t playerID, int64_t mateID) bool Communication::StartRouseMate(int64_t playerID, int64_t mateID)
{ {
{
std::lock_guard<std::mutex> lock(mtxLimit);
if (counter > limit)
return false;
counter++;
}
protobuf::BoolRes saveStudentResult; protobuf::BoolRes saveStudentResult;
ClientContext context; ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufTreatAndRescue(playerID, mateID); auto request = THUAI62Proto::THUAI62ProtobufTreatAndRescue(playerID, mateID);
@@ -200,6 +290,12 @@ bool Communication::StartRouseMate(int64_t playerID, int64_t mateID)


bool Communication::StartEncourageMate(int64_t playerID, int64_t mateID) bool Communication::StartEncourageMate(int64_t playerID, int64_t mateID)
{ {
{
std::lock_guard<std::mutex> lock(mtxLimit);
if (counter > limit)
return false;
counter++;
}
protobuf::BoolRes healStudentResult; protobuf::BoolRes healStudentResult;
ClientContext context; ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufTreatAndRescue(playerID, mateID); auto request = THUAI62Proto::THUAI62ProtobufTreatAndRescue(playerID, mateID);
@@ -212,6 +308,12 @@ bool Communication::StartEncourageMate(int64_t playerID, int64_t mateID)


bool Communication::Attack(double angle, int64_t playerID) bool Communication::Attack(double angle, int64_t playerID)
{ {
{
std::lock_guard<std::mutex> lock(mtxLimit);
if (counter > limit)
return false;
counter++;
}
protobuf::BoolRes attackResult; protobuf::BoolRes attackResult;
ClientContext context; ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufAttack(angle, playerID); auto request = THUAI62Proto::THUAI62ProtobufAttack(angle, playerID);
@@ -229,9 +331,7 @@ bool Communication::TryConnection(int64_t playerID)
auto request = THUAI62Proto::THUAI62ProtobufID(playerID); auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->TryConnection(&context, request, &reply); auto status = THUAI6Stub->TryConnection(&context, request, &reply);
if (status.ok()) if (status.ok())
{
return true; return true;
}
else else
return false; return false;
} }
@@ -254,6 +354,7 @@ void Communication::AddPlayer(int64_t playerID, THUAI6::PlayerType playerType, T
auto MessageReader = THUAI6Stub->AddPlayer(&context, playerMsg); auto MessageReader = THUAI6Stub->AddPlayer(&context, playerMsg);


protobuf::MessageToClient buffer2Client; protobuf::MessageToClient buffer2Client;
counter = 0;


while (MessageReader->Read(&buffer2Client)) while (MessageReader->Read(&buffer2Client))
{ {
@@ -261,6 +362,10 @@ void Communication::AddPlayer(int64_t playerID, THUAI6::PlayerType playerType, T
std::lock_guard<std::mutex> lock(mtxMessage); std::lock_guard<std::mutex> lock(mtxMessage);
message2Client = std::move(buffer2Client); message2Client = std::move(buffer2Client);
haveNewMessage = true; haveNewMessage = true;
{
std::lock_guard<std::mutex> lock(mtxLimit);
counter = 0;
}
} }
cvMessage.notify_one(); cvMessage.notify_one();
} }


+ 2
- 0
CAPI/cpp/proto/Services.grpc.pb.h View File

@@ -25,6 +25,8 @@
#include <grpcpp/impl/codegen/stub_options.h> #include <grpcpp/impl/codegen/stub_options.h>
#include <grpcpp/impl/codegen/sync_stream.h> #include <grpcpp/impl/codegen/sync_stream.h>


#undef SendMessage

namespace protobuf namespace protobuf
{ {




+ 14
- 4
CAPI/python/PyAPI/API.py View File

@@ -6,7 +6,6 @@ from typing import List, cast, Tuple, Union




class StudentAPI(IStudentAPI, IGameTimer): class StudentAPI(IStudentAPI, IGameTimer):

def __init__(self, logic: ILogic) -> None: def __init__(self, logic: ILogic) -> None:
self.__logic = logic self.__logic = logic
self.__pool = ThreadPoolExecutor(20) self.__pool = ThreadPoolExecutor(20)
@@ -133,7 +132,13 @@ class StudentAPI(IStudentAPI, IGameTimer):
return self.__logic.GetGameInfo() return self.__logic.GetGameInfo()


def HaveView(self, gridX: int, gridY: int) -> bool: def HaveView(self, gridX: int, gridY: int) -> bool:
return self.__logic.HaveView(gridX, gridY, self.GetSelfInfo().x, self.GetSelfInfo().y, self.GetSelfInfo().viewRange)
return self.__logic.HaveView(
gridX,
gridY,
self.GetSelfInfo().x,
self.GetSelfInfo().y,
self.GetSelfInfo().viewRange,
)


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


@@ -182,7 +187,6 @@ class StudentAPI(IStudentAPI, IGameTimer):




class TrickerAPI(ITrickerAPI, IGameTimer): class TrickerAPI(ITrickerAPI, IGameTimer):

def __init__(self, logic: ILogic) -> None: def __init__(self, logic: ILogic) -> None:
self.__logic = logic self.__logic = logic
self.__pool = ThreadPoolExecutor(20) self.__pool = ThreadPoolExecutor(20)
@@ -309,7 +313,13 @@ class TrickerAPI(ITrickerAPI, IGameTimer):
return self.__logic.GetGameInfo() return self.__logic.GetGameInfo()


def HaveView(self, gridX: int, gridY: int) -> bool: def HaveView(self, gridX: int, gridY: int) -> bool:
return self.__logic.HaveView(gridX, gridY, self.GetSelfInfo().x, self.GetSelfInfo().y, self.GetSelfInfo().viewRange)
return self.__logic.HaveView(
gridX,
gridY,
self.GetSelfInfo().x,
self.GetSelfInfo().y,
self.GetSelfInfo().viewRange,
)


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




+ 112
- 20
CAPI/python/PyAPI/Communication.py View File

@@ -19,17 +19,25 @@ class BoolErrorHandler(IErrorHandler):


class Communication: class Communication:
def __init__(self, sIP: str, sPort: str): def __init__(self, sIP: str, sPort: str):
aim = sIP + ':' + sPort
aim = sIP + ":" + sPort
channel = grpc.insecure_channel(aim) channel = grpc.insecure_channel(aim)
self.__THUAI6Stub = Services.AvailableServiceStub(channel) self.__THUAI6Stub = Services.AvailableServiceStub(channel)
self.__haveNewMessage = False self.__haveNewMessage = False
self.__cvMessage = threading.Condition() self.__cvMessage = threading.Condition()
self.__message2Client: Message2Clients.MessageToClient self.__message2Client: Message2Clients.MessageToClient
self.__mtxLimit = threading.Lock()
self.__counter = 0
self.__limit = 50


def Move(self, time: int, angle: float, playerID: int) -> bool: def Move(self, time: int, angle: float, playerID: int) -> bool:
try: try:
with self.__mtxLimit:
if self.__counter > self.__limit:
return False
self.__counter += 1
moveResult = self.__THUAI6Stub.Move( moveResult = self.__THUAI6Stub.Move(
THUAI62Proto.THUAI62ProtobufMove(time, angle, playerID))
THUAI62Proto.THUAI62ProtobufMove(time, angle, playerID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -37,8 +45,13 @@ class Communication:


def PickProp(self, propType: THUAI6.PropType, playerID: int) -> bool: def PickProp(self, propType: THUAI6.PropType, playerID: int) -> bool:
try: try:
with self.__mtxLimit:
if self.__counter > self.__limit:
return False
self.__counter += 1
pickResult = self.__THUAI6Stub.PickProp( pickResult = self.__THUAI6Stub.PickProp(
THUAI62Proto.THUAI62ProtobufProp(propType, playerID))
THUAI62Proto.THUAI62ProtobufProp(propType, playerID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -46,8 +59,13 @@ class Communication:


def UseProp(self, propType: THUAI6.PropType, playerID: int) -> bool: def UseProp(self, propType: THUAI6.PropType, playerID: int) -> bool:
try: try:
with self.__mtxLimit:
if self.__counter > self.__limit:
return False
self.__counter += 1
useResult = self.__THUAI6Stub.UseProp( useResult = self.__THUAI6Stub.UseProp(
THUAI62Proto.THUAI62ProtobufProp(propType, playerID))
THUAI62Proto.THUAI62ProtobufProp(propType, playerID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -55,8 +73,13 @@ class Communication:


def ThrowProp(self, propType: THUAI6.PropType, playerID: int) -> bool: def ThrowProp(self, propType: THUAI6.PropType, playerID: int) -> bool:
try: try:
with self.__mtxLimit:
if self.__counter > self.__limit:
return False
self.__counter += 1
throwResult = self.__THUAI6Stub.ThrowProp( throwResult = self.__THUAI6Stub.ThrowProp(
THUAI62Proto.THUAI62ProtobufProp(propType, playerID))
THUAI62Proto.THUAI62ProtobufProp(propType, playerID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -64,8 +87,13 @@ class Communication:


def UseSkill(self, skillID: int, playerID: int) -> bool: def UseSkill(self, skillID: int, playerID: int) -> bool:
try: try:
with self.__mtxLimit:
if self.__counter > self.__limit:
return False
self.__counter += 1
useResult = self.__THUAI6Stub.UseSkill( useResult = self.__THUAI6Stub.UseSkill(
THUAI62Proto.THUAI62ProtobufSkill(skillID, playerID))
THUAI62Proto.THUAI62ProtobufSkill(skillID, playerID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -73,8 +101,13 @@ class Communication:


def SendMessage(self, toID: int, message: Union[str, bytes], playerID: int) -> bool: def SendMessage(self, toID: int, message: Union[str, bytes], playerID: int) -> bool:
try: try:
with self.__mtxLimit:
if self.__counter > self.__limit:
return False
self.__counter += 1
sendResult = self.__THUAI6Stub.SendMessage( sendResult = self.__THUAI6Stub.SendMessage(
THUAI62Proto.THUAI62ProtobufSend(message, toID, playerID))
THUAI62Proto.THUAI62ProtobufSend(message, toID, playerID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -82,8 +115,13 @@ class Communication:


def Graduate(self, playerID: int) -> bool: def Graduate(self, playerID: int) -> bool:
try: try:
with self.__mtxLimit:
if self.__counter > self.__limit:
return False
self.__counter += 1
escapeResult = self.__THUAI6Stub.Graduate( escapeResult = self.__THUAI6Stub.Graduate(
THUAI62Proto.THUAI62ProtobufID(playerID))
THUAI62Proto.THUAI62ProtobufID(playerID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -91,8 +129,13 @@ class Communication:


def StartLearning(self, playerID: int) -> bool: def StartLearning(self, playerID: int) -> bool:
try: try:
with self.__mtxLimit:
if self.__counter > self.__limit:
return False
self.__counter += 1
learnResult = self.__THUAI6Stub.StartLearning( learnResult = self.__THUAI6Stub.StartLearning(
THUAI62Proto.THUAI62ProtobufID(playerID))
THUAI62Proto.THUAI62ProtobufID(playerID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -100,8 +143,13 @@ class Communication:


def StartEncourageMate(self, playerID: int, mateID: int) -> bool: def StartEncourageMate(self, playerID: int, mateID: int) -> bool:
try: try:
with self.__mtxLimit:
if self.__counter > self.__limit:
return False
self.__counter += 1
helpResult = self.__THUAI6Stub.StartTreatMate( helpResult = self.__THUAI6Stub.StartTreatMate(
THUAI62Proto.THUAI62ProtobufTreatAndRescue(playerID, mateID))
THUAI62Proto.THUAI62ProtobufTreatAndRescue(playerID, mateID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -109,8 +157,13 @@ class Communication:


def StartRouseMate(self, playerID: int, mateID: int) -> bool: def StartRouseMate(self, playerID: int, mateID: int) -> bool:
try: try:
with self.__mtxLimit:
if self.__counter > self.__limit:
return False
self.__counter += 1
helpResult = self.__THUAI6Stub.StartRescueMate( helpResult = self.__THUAI6Stub.StartRescueMate(
THUAI62Proto.THUAI62ProtobufTreatAndRescue(playerID, mateID))
THUAI62Proto.THUAI62ProtobufTreatAndRescue(playerID, mateID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -118,8 +171,13 @@ class Communication:


def Attack(self, angle: float, playerID: int) -> bool: def Attack(self, angle: float, playerID: int) -> bool:
try: try:
with self.__mtxLimit:
if self.__counter > self.__limit:
return False
self.__counter += 1
attackResult = self.__THUAI6Stub.Attack( attackResult = self.__THUAI6Stub.Attack(
THUAI62Proto.THUAI62ProtobufAttack(angle, playerID))
THUAI62Proto.THUAI62ProtobufAttack(angle, playerID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -127,8 +185,13 @@ class Communication:


def OpenDoor(self, playerID: int) -> bool: def OpenDoor(self, playerID: int) -> bool:
try: try:
with self.__mtxLimit:
if self.__counter > self.__limit:
return False
self.__counter += 1
openResult = self.__THUAI6Stub.OpenDoor( openResult = self.__THUAI6Stub.OpenDoor(
THUAI62Proto.THUAI62ProtobufID(playerID))
THUAI62Proto.THUAI62ProtobufID(playerID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -136,8 +199,13 @@ class Communication:


def CloseDoor(self, playerID: int) -> bool: def CloseDoor(self, playerID: int) -> bool:
try: try:
with self.__mtxLimit:
if self.__counter > self.__limit:
return False
self.__counter += 1
closeResult = self.__THUAI6Stub.CloseDoor( closeResult = self.__THUAI6Stub.CloseDoor(
THUAI62Proto.THUAI62ProtobufID(playerID))
THUAI62Proto.THUAI62ProtobufID(playerID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -145,8 +213,13 @@ class Communication:


def SkipWindow(self, playerID: int) -> bool: def SkipWindow(self, playerID: int) -> bool:
try: try:
with self.__mtxLimit:
if self.__counter > self.__limit:
return False
self.__counter += 1
skipResult = self.__THUAI6Stub.SkipWindow( skipResult = self.__THUAI6Stub.SkipWindow(
THUAI62Proto.THUAI62ProtobufID(playerID))
THUAI62Proto.THUAI62ProtobufID(playerID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -154,8 +227,13 @@ class Communication:


def StartOpenGate(self, playerID: int) -> bool: def StartOpenGate(self, playerID: int) -> bool:
try: try:
with self.__mtxLimit:
if self.__counter > self.__limit:
return False
self.__counter += 1
openResult = self.__THUAI6Stub.StartOpenGate( openResult = self.__THUAI6Stub.StartOpenGate(
THUAI62Proto.THUAI62ProtobufID(playerID))
THUAI62Proto.THUAI62ProtobufID(playerID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -163,8 +241,13 @@ class Communication:


def StartOpenChest(self, playerID: int) -> bool: def StartOpenChest(self, playerID: int) -> bool:
try: try:
with self.__mtxLimit:
if self.__counter > self.__limit:
return False
self.__counter += 1
openResult = self.__THUAI6Stub.StartOpenChest( openResult = self.__THUAI6Stub.StartOpenChest(
THUAI62Proto.THUAI62ProtobufID(playerID))
THUAI62Proto.THUAI62ProtobufID(playerID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -172,8 +255,13 @@ class Communication:


def EndAllAction(self, playerID: int) -> bool: def EndAllAction(self, playerID: int) -> bool:
try: try:
with self.__mtxLimit:
if self.__counter > self.__limit:
return False
self.__counter += 1
endResult = self.__THUAI6Stub.EndAllAction( endResult = self.__THUAI6Stub.EndAllAction(
THUAI62Proto.THUAI62ProtobufID(playerID))
THUAI62Proto.THUAI62ProtobufID(playerID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -182,7 +270,8 @@ class Communication:
def TryConnection(self, playerID: int) -> bool: def TryConnection(self, playerID: int) -> bool:
try: try:
connectResult = self.__THUAI6Stub.TryConnection( connectResult = self.__THUAI6Stub.TryConnection(
THUAI62Proto.THUAI62ProtobufID(playerID))
THUAI62Proto.THUAI62ProtobufID(playerID)
)
except grpc.RpcError as e: except grpc.RpcError as e:
return False return False
else: else:
@@ -202,12 +291,15 @@ class Communication:
else: else:
studentType = THUAI6.StudentType.NullStudentType studentType = THUAI6.StudentType.NullStudentType
playerMsg = THUAI62Proto.THUAI62ProtobufPlayer( playerMsg = THUAI62Proto.THUAI62ProtobufPlayer(
playerID, playerType, studentType, Setting.trickerType())
playerID, playerType, studentType, Setting.trickerType()
)
for msg in self.__THUAI6Stub.AddPlayer(playerMsg): for msg in self.__THUAI6Stub.AddPlayer(playerMsg):
with self.__cvMessage: with self.__cvMessage:
self.__haveNewMessage = True self.__haveNewMessage = True
self.__message2Client = msg self.__message2Client = msg
self.__cvMessage.notify() self.__cvMessage.notify()
with self.__mtxLimit:
self.__counter = 0
except grpc.RpcError as e: except grpc.RpcError as e:
return return




+ 215
- 184
CAPI/python/PyAPI/DebugAPI.py View File

@@ -10,22 +10,34 @@ from PyAPI.Interface import ILogic, IStudentAPI, ITrickerAPI, IGameTimer, IAI




class StudentDebugAPI(IStudentAPI, IGameTimer): class StudentDebugAPI(IStudentAPI, IGameTimer):

def __init__(self, logic: ILogic, file: bool, screen: bool, warnOnly: bool, playerID: int) -> None:
def __init__(
self, logic: ILogic, file: bool, screen: bool, warnOnly: bool, playerID: int
) -> None:
self.__logic = logic self.__logic = logic
self.__pool = ThreadPoolExecutor(20) self.__pool = ThreadPoolExecutor(20)
self.__startPoint = datetime.datetime.now() self.__startPoint = datetime.datetime.now()
self.__logger = logging.getLogger("api " + str(playerID)) self.__logger = logging.getLogger("api " + str(playerID))
self.__logger.setLevel(logging.DEBUG) self.__logger.setLevel(logging.DEBUG)
formatter = logging.Formatter( formatter = logging.Formatter(
"[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s", '%H:%M:%S')
"[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s",
"%H:%M:%S",
)
# 确保文件存在 # 确保文件存在
if not os.path.exists(os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/logs"):
os.makedirs(os.path.dirname(os.path.dirname(
os.path.realpath(__file__))) + "/logs")

fileHandler = logging.FileHandler(os.path.dirname(
os.path.dirname(os.path.realpath(__file__))) + "/logs/api-" + str(playerID) + "-log.txt", mode="w+", encoding="utf-8")
if not os.path.exists(
os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/logs"
):
os.makedirs(
os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/logs"
)

fileHandler = logging.FileHandler(
os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
+ "/logs/api-"
+ str(playerID)
+ "-log.txt",
mode="w+",
encoding="utf-8",
)
screenHandler = logging.StreamHandler() screenHandler = logging.StreamHandler()
if file: if file:
fileHandler.setLevel(logging.DEBUG) fileHandler.setLevel(logging.DEBUG)
@@ -43,13 +55,13 @@ class StudentDebugAPI(IStudentAPI, IGameTimer):


def Move(self, timeInMilliseconds: int, angle: float) -> Future[bool]: def Move(self, timeInMilliseconds: int, angle: float) -> Future[bool]:
self.__logger.info( self.__logger.info(
f"Move: timeInMilliseconds = {timeInMilliseconds}, angle = {angle}, called at {self.__GetTime()}ms")
f"Move: timeInMilliseconds = {timeInMilliseconds}, angle = {angle}, called at {self.__GetTime()}ms"
)


def logMove() -> bool: def logMove() -> bool:
result = self.__logic.Move(timeInMilliseconds, angle) result = self.__logic.Move(timeInMilliseconds, angle)
if not result: if not result:
self.__logger.warning(
f"Move: failed at {self.__GetTime()}ms")
self.__logger.warning(f"Move: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logMove) return self.__pool.submit(logMove)
@@ -69,14 +81,12 @@ class StudentDebugAPI(IStudentAPI, IGameTimer):
return self.Move(timeInMilliseconds, 0) return self.Move(timeInMilliseconds, 0)


def Attack(self, angle: float) -> Future[bool]: def Attack(self, angle: float) -> Future[bool]:
self.__logger.info(
f"Attack: angle = {angle}, called at {self.__GetTime()}ms")
self.__logger.info(f"Attack: angle = {angle}, called at {self.__GetTime()}ms")


def logAttack() -> bool: def logAttack() -> bool:
result = self.__logic.Attack(angle) result = self.__logic.Attack(angle)
if not result: if not result:
self.__logger.warning(
f"Attack: failed at {self.__GetTime()}ms")
self.__logger.warning(f"Attack: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logAttack) return self.__pool.submit(logAttack)
@@ -85,131 +95,119 @@ class StudentDebugAPI(IStudentAPI, IGameTimer):


def PickProp(self, propType: THUAI6.PropType) -> Future[bool]: def PickProp(self, propType: THUAI6.PropType) -> Future[bool]:
self.__logger.info( self.__logger.info(
f"PickProp: prop = {propType.name}, called at {self.__GetTime()}ms")
f"PickProp: prop = {propType.name}, called at {self.__GetTime()}ms"
)


def logPick() -> bool: def logPick() -> bool:
result = self.__logic.PickProp(propType) result = self.__logic.PickProp(propType)
if not result: if not result:
self.__logger.warning(
f"PickProp: failed at {self.__GetTime()}ms")
self.__logger.warning(f"PickProp: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logPick) return self.__pool.submit(logPick)


def UseProp(self, propType: THUAI6.PropType) -> Future[bool]: def UseProp(self, propType: THUAI6.PropType) -> Future[bool]:
self.__logger.info( self.__logger.info(
f"UseProp: prop = {propType.name}, called at {self.__GetTime()}ms")
f"UseProp: prop = {propType.name}, called at {self.__GetTime()}ms"
)


def logUse() -> bool: def logUse() -> bool:
result = self.__logic.UseProp(propType) result = self.__logic.UseProp(propType)
if not result: if not result:
self.__logger.warning(
f"UseProp: failed at {self.__GetTime()}ms")
self.__logger.warning(f"UseProp: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logUse) return self.__pool.submit(logUse)


def ThrowProp(self, propType: THUAI6.PropType) -> Future[bool]: def ThrowProp(self, propType: THUAI6.PropType) -> Future[bool]:
self.__logger.info( self.__logger.info(
f"ThrowProp: prop = {propType.name}, called at {self.__GetTime()}ms")
f"ThrowProp: prop = {propType.name}, called at {self.__GetTime()}ms"
)


def logThrow() -> bool: def logThrow() -> bool:
result = self.__logic.ThrowProp(propType) result = self.__logic.ThrowProp(propType)
if not result: if not result:
self.__logger.warning(
f"ThrowProp: failed at {self.__GetTime()}ms")
self.__logger.warning(f"ThrowProp: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logThrow) return self.__pool.submit(logThrow)


def UseSkill(self, skillID: int) -> Future[bool]: def UseSkill(self, skillID: int) -> Future[bool]:
self.__logger.info( self.__logger.info(
f"UseSkill: skillID = {skillID}, called at {self.__GetTime()}ms")
f"UseSkill: skillID = {skillID}, called at {self.__GetTime()}ms"
)


def logUse() -> bool: def logUse() -> bool:
result = self.__logic.UseSkill(skillID) result = self.__logic.UseSkill(skillID)
if not result: if not result:
self.__logger.warning(
f"UseSkill: failed at {self.__GetTime()}ms")
self.__logger.warning(f"UseSkill: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logUse) return self.__pool.submit(logUse)


# 与地图交互相关 # 与地图交互相关
def OpenDoor(self) -> Future[bool]: def OpenDoor(self) -> Future[bool]:
self.__logger.info(
f"OpenDoor: called at {self.__GetTime()}ms")
self.__logger.info(f"OpenDoor: called at {self.__GetTime()}ms")


def logOpen() -> bool: def logOpen() -> bool:
result = self.__logic.OpenDoor() result = self.__logic.OpenDoor()
if not result: if not result:
self.__logger.warning(
f"OpenDoor: failed at {self.__GetTime()}ms")
self.__logger.warning(f"OpenDoor: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logOpen) return self.__pool.submit(logOpen)


def CloseDoor(self) -> Future[bool]: def CloseDoor(self) -> Future[bool]:
self.__logger.info(
f"CloseDoor: called at {self.__GetTime()}ms")
self.__logger.info(f"CloseDoor: called at {self.__GetTime()}ms")


def logClose() -> bool: def logClose() -> bool:
result = self.__logic.CloseDoor() result = self.__logic.CloseDoor()
if not result: if not result:
self.__logger.warning(
f"CloseDoor: failed at {self.__GetTime()}ms")
self.__logger.warning(f"CloseDoor: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logClose) return self.__pool.submit(logClose)


def SkipWindow(self) -> Future[bool]: def SkipWindow(self) -> Future[bool]:
self.__logger.info(
f"SkipWindow: called at {self.__GetTime()}ms")
self.__logger.info(f"SkipWindow: called at {self.__GetTime()}ms")


def logSkip() -> bool: def logSkip() -> bool:
result = self.__logic.SkipWindow() result = self.__logic.SkipWindow()
if not result: if not result:
self.__logger.warning(
f"SkipWindow: failed at {self.__GetTime()}ms")
self.__logger.warning(f"SkipWindow: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logSkip) return self.__pool.submit(logSkip)


def StartOpenGate(self) -> Future[bool]: def StartOpenGate(self) -> Future[bool]:
self.__logger.info(
f"StartOpenGate: called at {self.__GetTime()}ms")
self.__logger.info(f"StartOpenGate: called at {self.__GetTime()}ms")


def logStart() -> bool: def logStart() -> bool:
result = self.__logic.StartOpenGate() result = self.__logic.StartOpenGate()
if not result: if not result:
self.__logger.warning(
f"StartOpenGate: failed at {self.__GetTime()}ms")
self.__logger.warning(f"StartOpenGate: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logStart) return self.__pool.submit(logStart)


def StartOpenChest(self) -> Future[bool]: def StartOpenChest(self) -> Future[bool]:
self.__logger.info(
f"StartOpenChest: called at {self.__GetTime()}ms")
self.__logger.info(f"StartOpenChest: called at {self.__GetTime()}ms")


def logStart() -> bool: def logStart() -> bool:
result = self.__logic.StartOpenChest() result = self.__logic.StartOpenChest()
if not result: if not result:
self.__logger.warning(
f"StartOpenChest: failed at {self.__GetTime()}ms")
self.__logger.warning(f"StartOpenChest: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logStart) return self.__pool.submit(logStart)


def EndAllAction(self) -> Future[bool]: def EndAllAction(self) -> Future[bool]:
self.__logger.info(
f"EndAllAction: called at {self.__GetTime()}ms")
self.__logger.info(f"EndAllAction: called at {self.__GetTime()}ms")


def logEnd() -> bool: def logEnd() -> bool:
result = self.__logic.EndAllAction() result = self.__logic.EndAllAction()
if not result: if not result:
self.__logger.warning(
f"EndAllAction: failed at {self.__GetTime()}ms")
self.__logger.warning(f"EndAllAction: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logEnd) return self.__pool.submit(logEnd)
@@ -218,40 +216,35 @@ class StudentDebugAPI(IStudentAPI, IGameTimer):


def SendMessage(self, toID: int, message: Union[str, bytes]) -> Future[bool]: def SendMessage(self, toID: int, message: Union[str, bytes]) -> Future[bool]:
self.__logger.info( self.__logger.info(
f"SendMessage: toID = {toID}, message = {message}, called at {self.__GetTime()}ms")
f"SendMessage: toID = {toID}, message = {message}, called at {self.__GetTime()}ms"
)


def logSend() -> bool: def logSend() -> bool:
result = self.__logic.SendMessage(toID, message) result = self.__logic.SendMessage(toID, message)
if not result: if not result:
self.__logger.warning(
f"SendMessage: failed at {self.__GetTime()}ms")
self.__logger.warning(f"SendMessage: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logSend) return self.__pool.submit(logSend)


def HaveMessage(self) -> bool: def HaveMessage(self) -> bool:
self.__logger.info(
f"HaveMessage: called at {self.__GetTime()}ms")
self.__logger.info(f"HaveMessage: called at {self.__GetTime()}ms")
result = self.__logic.HaveMessage() result = self.__logic.HaveMessage()
if not result: if not result:
self.__logger.warning(
f"HaveMessage: failed at {self.__GetTime()}ms")
self.__logger.warning(f"HaveMessage: failed at {self.__GetTime()}ms")
return result return result


def GetMessage(self) -> Tuple[int, Union[str, bytes]]: def GetMessage(self) -> Tuple[int, Union[str, bytes]]:
self.__logger.info(
f"GetMessage: called at {self.__GetTime()}ms")
self.__logger.info(f"GetMessage: called at {self.__GetTime()}ms")
result = self.__logic.GetMessage() result = self.__logic.GetMessage()
if result[0] == -1: if result[0] == -1:
self.__logger.warning(
f"GetMessage: failed at {self.__GetTime()}ms")
self.__logger.warning(f"GetMessage: failed at {self.__GetTime()}ms")
return result return result


# 等待下一帧 # 等待下一帧


def Wait(self) -> bool: def Wait(self) -> bool:
self.__logger.info(
f"Wait: called at {self.__GetTime()}ms")
self.__logger.info(f"Wait: called at {self.__GetTime()}ms")
if self.__logic.GetCounter() == -1: if self.__logic.GetCounter() == -1:
return False return False
else: else:
@@ -305,7 +298,13 @@ class StudentDebugAPI(IStudentAPI, IGameTimer):
return self.__logic.GetGameInfo() return self.__logic.GetGameInfo()


def HaveView(self, gridX: int, gridY: int) -> bool: def HaveView(self, gridX: int, gridY: int) -> bool:
return self.__logic.HaveView(gridX, gridY, self.GetSelfInfo().x, self.GetSelfInfo().y, self.GetSelfInfo().viewRange)
return self.__logic.HaveView(
gridX,
gridY,
self.GetSelfInfo().x,
self.GetSelfInfo().y,
self.GetSelfInfo().viewRange,
)


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


@@ -316,20 +315,26 @@ class StudentDebugAPI(IStudentAPI, IGameTimer):
for student in self.__logic.GetStudents(): for student in self.__logic.GetStudents():
self.__logger.info("******Student Info******") self.__logger.info("******Student Info******")
self.__logger.info( self.__logger.info(
f"playerID={student.playerID}, GUID={student.guid}, x={student.x}, y={student.y}")
f"playerID={student.playerID}, GUID={student.guid}, x={student.x}, y={student.y}"
)
self.__logger.info( self.__logger.info(
f"speed={student.speed}, view range={student.viewRange}, radius={student.radius}")
f"speed={student.speed}, view range={student.viewRange}, radius={student.radius}"
)
self.__logger.info( self.__logger.info(
f"score={student.score}, facing direction={student.facingDirection}, skill time={student.timeUntilSkillAvailable}")
f"score={student.score}, facing direction={student.facingDirection}, skill time={student.timeUntilSkillAvailable}"
)
studentProp = "" studentProp = ""
for prop in student.prop: for prop in student.prop:
studentProp += prop.name + ", " studentProp += prop.name + ", "
self.__logger.info( self.__logger.info(
f"state={student.playerState.name}, bullet={student.bulletType.name}, prop={studentProp}")
f"state={student.playerState.name}, bullet={student.bulletType.name}, prop={studentProp}"
)
self.__logger.info( self.__logger.info(
f"type={student.studentType.name}, determination={student.determination}, addiction={student.addiction}, danger alert={student.dangerAlert}")
f"type={student.studentType.name}, determination={student.determination}, addiction={student.addiction}, danger alert={student.dangerAlert}"
)
self.__logger.info( self.__logger.info(
f"learning speed={student.learningSpeed}, encourage speed={student.encourageSpeed}, encourage progress={student.encourageProgress}, rouse progress={student.rouseProgress}")
f"learning speed={student.learningSpeed}, encourage speed={student.encourageSpeed}, encourage progress={student.encourageProgress}, rouse progress={student.rouseProgress}"
)
studentBuff = "" studentBuff = ""
for buff in student.buff: for buff in student.buff:
studentBuff += buff.name + ", " studentBuff += buff.name + ", "
@@ -340,18 +345,23 @@ class StudentDebugAPI(IStudentAPI, IGameTimer):
for tricker in self.__logic.GetTrickers(): for tricker in self.__logic.GetTrickers():
self.__logger.info("******Tricker Info******") self.__logger.info("******Tricker Info******")
self.__logger.info( self.__logger.info(
f"playerID={tricker.playerID}, GUID={tricker.guid}, x={tricker.x}, y={tricker.y}")
f"playerID={tricker.playerID}, GUID={tricker.guid}, x={tricker.x}, y={tricker.y}"
)
self.__logger.info( self.__logger.info(
f"speed={tricker.speed}, view range={tricker.viewRange}, radius={tricker.radius}")
f"speed={tricker.speed}, view range={tricker.viewRange}, radius={tricker.radius}"
)
self.__logger.info( self.__logger.info(
f"score={tricker.score}, facing direction={tricker.facingDirection}, skill time={tricker.timeUntilSkillAvailable}")
f"score={tricker.score}, facing direction={tricker.facingDirection}, skill time={tricker.timeUntilSkillAvailable}"
)
trickerProp = "" trickerProp = ""
for prop in tricker.prop: for prop in tricker.prop:
trickerProp += prop.name + ", " trickerProp += prop.name + ", "
self.__logger.info( self.__logger.info(
f"state={tricker.playerState.name}, bullet={tricker.bulletType.name}, prop={trickerProp}")
f"state={tricker.playerState.name}, bullet={tricker.bulletType.name}, prop={trickerProp}"
)
self.__logger.info( self.__logger.info(
f"type={tricker.trickerType.name}, trick desire={tricker.trickDesire}, class volume={tricker.classVolume}")
f"type={tricker.trickerType.name}, trick desire={tricker.trickDesire}, class volume={tricker.classVolume}"
)
trickerBuff = "" trickerBuff = ""
for buff in tricker.buff: for buff in tricker.buff:
trickerBuff += buff.name + ", " trickerBuff += buff.name + ", "
@@ -362,27 +372,34 @@ class StudentDebugAPI(IStudentAPI, IGameTimer):
for prop in self.__logic.GetProps(): for prop in self.__logic.GetProps():
self.__logger.info("******Prop Info******") self.__logger.info("******Prop Info******")
self.__logger.info( self.__logger.info(
f"GUID={prop.guid}, x={prop.x}, y={prop.y}, facing direction={prop.facingDirection}")
f"GUID={prop.guid}, x={prop.x}, y={prop.y}, facing direction={prop.facingDirection}"
)
self.__logger.info("*********************") self.__logger.info("*********************")


def PrintSelfInfo(self) -> None: def PrintSelfInfo(self) -> None:
student = cast(THUAI6.Student, self.__logic.GetSelfInfo()) student = cast(THUAI6.Student, self.__logic.GetSelfInfo())
self.__logger.info("******Student Info******") self.__logger.info("******Student Info******")
self.__logger.info( self.__logger.info(
f"playerID={student.playerID}, GUID={student.guid}, x={student.x}, y={student.y}")
f"playerID={student.playerID}, GUID={student.guid}, x={student.x}, y={student.y}"
)
self.__logger.info( self.__logger.info(
f"speed={student.speed}, view range={student.viewRange}, radius={student.radius}")
f"speed={student.speed}, view range={student.viewRange}, radius={student.radius}"
)
self.__logger.info( self.__logger.info(
f"score={student.score}, facing direction={student.facingDirection}, skill time={student.timeUntilSkillAvailable}")
f"score={student.score}, facing direction={student.facingDirection}, skill time={student.timeUntilSkillAvailable}"
)
studentProp = "" studentProp = ""
for prop in student.prop: for prop in student.prop:
studentProp += prop.name + ", " studentProp += prop.name + ", "
self.__logger.info( self.__logger.info(
f"state={student.playerState.name}, bullet={student.bulletType.name}, prop={studentProp}")
f"state={student.playerState.name}, bullet={student.bulletType.name}, prop={studentProp}"
)
self.__logger.info( self.__logger.info(
f"type={student.studentType.name}, determination={student.determination}, addiction={student.addiction}, danger alert={student.dangerAlert}")
f"type={student.studentType.name}, determination={student.determination}, addiction={student.addiction}, danger alert={student.dangerAlert}"
)
self.__logger.info( self.__logger.info(
f"learning speed={student.learningSpeed}, encourage speed={student.encourageSpeed}, encourage progress={student.encourageProgress}, rouse progress={student.rouseProgress}")
f"learning speed={student.learningSpeed}, encourage speed={student.encourageSpeed}, encourage progress={student.encourageProgress}, rouse progress={student.rouseProgress}"
)
studentBuff = "" studentBuff = ""
for buff in student.buff: for buff in student.buff:
studentBuff += buff.name + ", " studentBuff += buff.name + ", "
@@ -392,53 +409,47 @@ class StudentDebugAPI(IStudentAPI, IGameTimer):
# 人类阵营的特殊函数 # 人类阵营的特殊函数


def Graduate(self) -> Future[bool]: def Graduate(self) -> Future[bool]:
self.__logger.info(
f"Graduate: called at {self.__GetTime()}ms")
self.__logger.info(f"Graduate: called at {self.__GetTime()}ms")


def logGraduate() -> bool: def logGraduate() -> bool:
result = self.__logic.Graduate() result = self.__logic.Graduate()
if not result: if not result:
self.__logger.warning(
f"Graduate: failed at {self.__GetTime()}ms")
self.__logger.warning(f"Graduate: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logGraduate) return self.__pool.submit(logGraduate)


def StartLearning(self) -> Future[bool]: def StartLearning(self) -> Future[bool]:
self.__logger.info(
f"StartLearning: called at {self.__GetTime()}ms")
self.__logger.info(f"StartLearning: called at {self.__GetTime()}ms")


def logStart() -> bool: def logStart() -> bool:
result = self.__logic.StartLearning() result = self.__logic.StartLearning()
if not result: if not result:
self.__logger.warning(
f"StartLearning: failed at {self.__GetTime()}ms")
self.__logger.warning(f"StartLearning: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logStart) return self.__pool.submit(logStart)


def StartEncourageMate(self, mateID: int) -> Future[bool]: def StartEncourageMate(self, mateID: int) -> Future[bool]:
self.__logger.info(
f"StartEncourageMate: called at {self.__GetTime()}ms")
self.__logger.info(f"StartEncourageMate: called at {self.__GetTime()}ms")


def logStartEncourageMate() -> bool: def logStartEncourageMate() -> bool:
result = self.__logic.StartEncourageMate(mateID) result = self.__logic.StartEncourageMate(mateID)
if not result: if not result:
self.__logger.warning( self.__logger.warning(
f"StartEncourageMate: failed at {self.__GetTime()}ms")
f"StartEncourageMate: failed at {self.__GetTime()}ms"
)
return result return result


return self.__pool.submit(logStartEncourageMate) return self.__pool.submit(logStartEncourageMate)


def StartRouseMate(self, mateID: int) -> Future[bool]: def StartRouseMate(self, mateID: int) -> Future[bool]:
self.__logger.info(
f"StartRouseMate: called at {self.__GetTime()}ms")
self.__logger.info(f"StartRouseMate: called at {self.__GetTime()}ms")


def logStartRouseMate() -> bool: def logStartRouseMate() -> bool:
result = self.__logic.StartRouseMate(mateID) result = self.__logic.StartRouseMate(mateID)
if not result: if not result:
self.__logger.warning(
f"StartRouseMate: failed at {self.__GetTime()}ms")
self.__logger.warning(f"StartRouseMate: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logStartRouseMate) return self.__pool.submit(logStartRouseMate)
@@ -449,7 +460,9 @@ class StudentDebugAPI(IStudentAPI, IGameTimer):
# Timer用 # Timer用


def __GetTime(self) -> float: def __GetTime(self) -> float:
return (datetime.datetime.now() - self.__startPoint) / datetime.timedelta(milliseconds=1)
return (datetime.datetime.now() - self.__startPoint) / datetime.timedelta(
milliseconds=1
)


def StartTimer(self) -> None: def StartTimer(self) -> None:
self.__startPoint = datetime.datetime.now() self.__startPoint = datetime.datetime.now()
@@ -464,21 +477,33 @@ class StudentDebugAPI(IStudentAPI, IGameTimer):




class TrickerDebugAPI(ITrickerAPI, IGameTimer): class TrickerDebugAPI(ITrickerAPI, IGameTimer):

def __init__(self, logic: ILogic, file: bool, screen: bool, warnOnly: bool, playerID: int) -> None:
def __init__(
self, logic: ILogic, file: bool, screen: bool, warnOnly: bool, playerID: int
) -> None:
self.__logic = logic self.__logic = logic
self.__pool = ThreadPoolExecutor(20) self.__pool = ThreadPoolExecutor(20)
self.__logger = logging.getLogger("api " + str(playerID)) self.__logger = logging.getLogger("api " + str(playerID))
self.__logger.setLevel(logging.DEBUG) self.__logger.setLevel(logging.DEBUG)
formatter = logging.Formatter( formatter = logging.Formatter(
"[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s", '%H:%M:%S')
"[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s",
"%H:%M:%S",
)
# 确保文件存在 # 确保文件存在
if not os.path.exists(os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/logs"):
os.makedirs(os.path.dirname(os.path.dirname(
os.path.realpath(__file__))) + "/logs")

fileHandler = logging.FileHandler(os.path.dirname(
os.path.dirname(os.path.realpath(__file__))) + "/logs/api-" + str(playerID) + "-log.txt", mode="w+", encoding="utf-8")
if not os.path.exists(
os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/logs"
):
os.makedirs(
os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/logs"
)

fileHandler = logging.FileHandler(
os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
+ "/logs/api-"
+ str(playerID)
+ "-log.txt",
mode="w+",
encoding="utf-8",
)
screenHandler = logging.StreamHandler() screenHandler = logging.StreamHandler()
if file: if file:
fileHandler.setLevel(logging.DEBUG) fileHandler.setLevel(logging.DEBUG)
@@ -496,13 +521,13 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer):


def Move(self, timeInMilliseconds: int, angle: float) -> Future[bool]: def Move(self, timeInMilliseconds: int, angle: float) -> Future[bool]:
self.__logger.info( self.__logger.info(
f"Move: timeInMilliseconds = {timeInMilliseconds}, angle = {angle}, called at {self.__GetTime()}ms")
f"Move: timeInMilliseconds = {timeInMilliseconds}, angle = {angle}, called at {self.__GetTime()}ms"
)


def logMove() -> bool: def logMove() -> bool:
result = self.__logic.Move(timeInMilliseconds, angle) result = self.__logic.Move(timeInMilliseconds, angle)
if not result: if not result:
self.__logger.warning(
f"Move: failed at {self.__GetTime()}ms")
self.__logger.warning(f"Move: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logMove) return self.__pool.submit(logMove)
@@ -524,14 +549,12 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer):
# 道具和技能相关 # 道具和技能相关


def Attack(self, angle: float) -> Future[bool]: def Attack(self, angle: float) -> Future[bool]:
self.__logger.info(
f"Attack: angle = {angle}, called at {self.__GetTime()}ms")
self.__logger.info(f"Attack: angle = {angle}, called at {self.__GetTime()}ms")


def logAttack() -> bool: def logAttack() -> bool:
result = self.__logic.Attack(angle) result = self.__logic.Attack(angle)
if not result: if not result:
self.__logger.warning(
f"Attack: failed at {self.__GetTime()}ms")
self.__logger.warning(f"Attack: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logAttack) return self.__pool.submit(logAttack)
@@ -540,131 +563,119 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer):


def PickProp(self, propType: THUAI6.PropType) -> Future[bool]: def PickProp(self, propType: THUAI6.PropType) -> Future[bool]:
self.__logger.info( self.__logger.info(
f"PickProp: prop = {propType.name}, called at {self.__GetTime()}ms")
f"PickProp: prop = {propType.name}, called at {self.__GetTime()}ms"
)


def logPick() -> bool: def logPick() -> bool:
result = self.__logic.PickProp(propType) result = self.__logic.PickProp(propType)
if not result: if not result:
self.__logger.warning(
f"PickProp: failed at {self.__GetTime()}ms")
self.__logger.warning(f"PickProp: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logPick) return self.__pool.submit(logPick)


def UseProp(self, propType: THUAI6.PropType) -> Future[bool]: def UseProp(self, propType: THUAI6.PropType) -> Future[bool]:
self.__logger.info( self.__logger.info(
f"UseProp: prop = {propType.name}, called at {self.__GetTime()}ms")
f"UseProp: prop = {propType.name}, called at {self.__GetTime()}ms"
)


def logUse() -> bool: def logUse() -> bool:
result = self.__logic.UseProp(propType) result = self.__logic.UseProp(propType)
if not result: if not result:
self.__logger.warning(
f"UseProp: failed at {self.__GetTime()}ms")
self.__logger.warning(f"UseProp: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logUse) return self.__pool.submit(logUse)


def ThrowProp(self, propType: THUAI6.PropType) -> Future[bool]: def ThrowProp(self, propType: THUAI6.PropType) -> Future[bool]:
self.__logger.info( self.__logger.info(
f"ThrowProp: prop = {propType.name}, called at {self.__GetTime()}ms")
f"ThrowProp: prop = {propType.name}, called at {self.__GetTime()}ms"
)


def logThrow() -> bool: def logThrow() -> bool:
result = self.__logic.ThrowProp(propType) result = self.__logic.ThrowProp(propType)
if not result: if not result:
self.__logger.warning(
f"ThrowProp: failed at {self.__GetTime()}ms")
self.__logger.warning(f"ThrowProp: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logThrow) return self.__pool.submit(logThrow)


def UseSkill(self, skillID: int) -> Future[bool]: def UseSkill(self, skillID: int) -> Future[bool]:
self.__logger.info( self.__logger.info(
f"UseSkill: skillID = {skillID}, called at {self.__GetTime()}ms")
f"UseSkill: skillID = {skillID}, called at {self.__GetTime()}ms"
)


def logUse() -> bool: def logUse() -> bool:
result = self.__logic.UseSkill(skillID) result = self.__logic.UseSkill(skillID)
if not result: if not result:
self.__logger.warning(
f"UseSkill: failed at {self.__GetTime()}ms")
self.__logger.warning(f"UseSkill: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logUse) return self.__pool.submit(logUse)


# 与地图交互相关 # 与地图交互相关
def OpenDoor(self) -> Future[bool]: def OpenDoor(self) -> Future[bool]:
self.__logger.info(
f"OpenDoor: called at {self.__GetTime()}ms")
self.__logger.info(f"OpenDoor: called at {self.__GetTime()}ms")


def logOpen() -> bool: def logOpen() -> bool:
result = self.__logic.OpenDoor() result = self.__logic.OpenDoor()
if not result: if not result:
self.__logger.warning(
f"OpenDoor: failed at {self.__GetTime()}ms")
self.__logger.warning(f"OpenDoor: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logOpen) return self.__pool.submit(logOpen)


def CloseDoor(self) -> Future[bool]: def CloseDoor(self) -> Future[bool]:
self.__logger.info(
f"CloseDoor: called at {self.__GetTime()}ms")
self.__logger.info(f"CloseDoor: called at {self.__GetTime()}ms")


def logClose() -> bool: def logClose() -> bool:
result = self.__logic.CloseDoor() result = self.__logic.CloseDoor()
if not result: if not result:
self.__logger.warning(
f"CloseDoor: failed at {self.__GetTime()}ms")
self.__logger.warning(f"CloseDoor: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logClose) return self.__pool.submit(logClose)


def SkipWindow(self) -> Future[bool]: def SkipWindow(self) -> Future[bool]:
self.__logger.info(
f"SkipWindow: called at {self.__GetTime()}ms")
self.__logger.info(f"SkipWindow: called at {self.__GetTime()}ms")


def logSkip() -> bool: def logSkip() -> bool:
result = self.__logic.SkipWindow() result = self.__logic.SkipWindow()
if not result: if not result:
self.__logger.warning(
f"SkipWindow: failed at {self.__GetTime()}ms")
self.__logger.warning(f"SkipWindow: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logSkip) return self.__pool.submit(logSkip)


def StartOpenGate(self) -> Future[bool]: def StartOpenGate(self) -> Future[bool]:
self.__logger.info(
f"StartOpenGate: called at {self.__GetTime()}ms")
self.__logger.info(f"StartOpenGate: called at {self.__GetTime()}ms")


def logStart() -> bool: def logStart() -> bool:
result = self.__logic.StartOpenGate() result = self.__logic.StartOpenGate()
if not result: if not result:
self.__logger.warning(
f"StartOpenGate: failed at {self.__GetTime()}ms")
self.__logger.warning(f"StartOpenGate: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logStart) return self.__pool.submit(logStart)


def StartOpenChest(self) -> Future[bool]: def StartOpenChest(self) -> Future[bool]:
self.__logger.info(
f"StartOpenChest: called at {self.__GetTime()}ms")
self.__logger.info(f"StartOpenChest: called at {self.__GetTime()}ms")


def logStart() -> bool: def logStart() -> bool:
result = self.__logic.StartOpenChest() result = self.__logic.StartOpenChest()
if not result: if not result:
self.__logger.warning(
f"StartOpenChest: failed at {self.__GetTime()}ms")
self.__logger.warning(f"StartOpenChest: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logStart) return self.__pool.submit(logStart)


def EndAllAction(self) -> Future[bool]: def EndAllAction(self) -> Future[bool]:
self.__logger.info(
f"EndAllAction: called at {self.__GetTime()}ms")
self.__logger.info(f"EndAllAction: called at {self.__GetTime()}ms")


def logEnd() -> bool: def logEnd() -> bool:
result = self.__logic.EndAllAction() result = self.__logic.EndAllAction()
if not result: if not result:
self.__logger.warning(
f"EndAllAction: failed at {self.__GetTime()}ms")
self.__logger.warning(f"EndAllAction: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logEnd) return self.__pool.submit(logEnd)
@@ -673,40 +684,35 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer):


def SendMessage(self, toID: int, message: Union[str, bytes]) -> Future[bool]: def SendMessage(self, toID: int, message: Union[str, bytes]) -> Future[bool]:
self.__logger.info( self.__logger.info(
f"SendMessage: toID = {toID}, message = {message}, called at {self.__GetTime()}ms")
f"SendMessage: toID = {toID}, message = {message}, called at {self.__GetTime()}ms"
)


def logSend() -> bool: def logSend() -> bool:
result = self.__logic.SendMessage(toID, message) result = self.__logic.SendMessage(toID, message)
if not result: if not result:
self.__logger.warning(
f"SendMessage: failed at {self.__GetTime()}ms")
self.__logger.warning(f"SendMessage: failed at {self.__GetTime()}ms")
return result return result


return self.__pool.submit(logSend) return self.__pool.submit(logSend)


def HaveMessage(self) -> bool: def HaveMessage(self) -> bool:
self.__logger.info(
f"HaveMessage: called at {self.__GetTime()}ms")
self.__logger.info(f"HaveMessage: called at {self.__GetTime()}ms")
result = self.__logic.HaveMessage() result = self.__logic.HaveMessage()
if not result: if not result:
self.__logger.warning(
f"HaveMessage: failed at {self.__GetTime()}ms")
self.__logger.warning(f"HaveMessage: failed at {self.__GetTime()}ms")
return result return result


def GetMessage(self) -> Tuple[int, Union[str, bytes]]: def GetMessage(self) -> Tuple[int, Union[str, bytes]]:
self.__logger.info(
f"GetMessage: called at {self.__GetTime()}ms")
self.__logger.info(f"GetMessage: called at {self.__GetTime()}ms")
result = self.__logic.GetMessage() result = self.__logic.GetMessage()
if result[0] == -1: if result[0] == -1:
self.__logger.warning(
f"GetMessage: failed at {self.__GetTime()}ms")
self.__logger.warning(f"GetMessage: failed at {self.__GetTime()}ms")
return result return result


# 等待下一帧 # 等待下一帧


def Wait(self) -> bool: def Wait(self) -> bool:
self.__logger.info(
f"Wait: called at {self.__GetTime()}ms")
self.__logger.info(f"Wait: called at {self.__GetTime()}ms")
if self.__logic.GetCounter() == -1: if self.__logic.GetCounter() == -1:
return False return False
else: else:
@@ -760,7 +766,13 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer):
return self.__logic.GetGameInfo() return self.__logic.GetGameInfo()


def HaveView(self, gridX: int, gridY: int) -> bool: def HaveView(self, gridX: int, gridY: int) -> bool:
return self.__logic.HaveView(gridX, gridY, self.GetSelfInfo().x, self.GetSelfInfo().y, self.GetSelfInfo().viewRange)
return self.__logic.HaveView(
gridX,
gridY,
self.GetSelfInfo().x,
self.GetSelfInfo().y,
self.GetSelfInfo().viewRange,
)


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


@@ -771,20 +783,26 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer):
for student in self.__logic.GetStudents(): for student in self.__logic.GetStudents():
self.__logger.info("******Student Info******") self.__logger.info("******Student Info******")
self.__logger.info( self.__logger.info(
f"playerID={student.playerID}, GUID={student.guid}, x={student.x}, y={student.y}")
f"playerID={student.playerID}, GUID={student.guid}, x={student.x}, y={student.y}"
)
self.__logger.info( self.__logger.info(
f"speed={student.speed}, view range={student.viewRange}, radius={student.radius}")
f"speed={student.speed}, view range={student.viewRange}, radius={student.radius}"
)
self.__logger.info( self.__logger.info(
f"score={student.score}, facing direction={student.facingDirection}, skill time={student.timeUntilSkillAvailable}")
f"score={student.score}, facing direction={student.facingDirection}, skill time={student.timeUntilSkillAvailable}"
)
studentProp = "" studentProp = ""
for prop in student.prop: for prop in student.prop:
studentProp += prop.name + ", " studentProp += prop.name + ", "
self.__logger.info( self.__logger.info(
f"state={student.playerState.name}, bullet={student.bulletType.name}, prop={studentProp}")
f"state={student.playerState.name}, bullet={student.bulletType.name}, prop={studentProp}"
)
self.__logger.info( self.__logger.info(
f"type={student.studentType.name}, determination={student.determination}, addiction={student.addiction}, danger alert={student.dangerAlert}")
f"type={student.studentType.name}, determination={student.determination}, addiction={student.addiction}, danger alert={student.dangerAlert}"
)
self.__logger.info( self.__logger.info(
f"learning speed={student.learningSpeed}, encourage speed={student.encourageSpeed}, encourage progress={student.encourageProgress}, rouse progress={student.rouseProgress}")
f"learning speed={student.learningSpeed}, encourage speed={student.encourageSpeed}, encourage progress={student.encourageProgress}, rouse progress={student.rouseProgress}"
)
studentBuff = "" studentBuff = ""
for buff in student.buff: for buff in student.buff:
studentBuff += buff.name + ", " studentBuff += buff.name + ", "
@@ -795,18 +813,23 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer):
for tricker in self.__logic.GetTrickers(): for tricker in self.__logic.GetTrickers():
self.__logger.info("******Tricker Info******") self.__logger.info("******Tricker Info******")
self.__logger.info( self.__logger.info(
f"playerID={tricker.playerID}, GUID={tricker.guid}, x={tricker.x}, y={tricker.y}")
f"playerID={tricker.playerID}, GUID={tricker.guid}, x={tricker.x}, y={tricker.y}"
)
self.__logger.info( self.__logger.info(
f"speed={tricker.speed}, view range={tricker.viewRange}, radius={tricker.radius}")
f"speed={tricker.speed}, view range={tricker.viewRange}, radius={tricker.radius}"
)
self.__logger.info( self.__logger.info(
f"score={tricker.score}, facing direction={tricker.facingDirection}, skill time={tricker.timeUntilSkillAvailable}")
f"score={tricker.score}, facing direction={tricker.facingDirection}, skill time={tricker.timeUntilSkillAvailable}"
)
trickerProp = "" trickerProp = ""
for prop in tricker.prop: for prop in tricker.prop:
trickerProp += prop.name + ", " trickerProp += prop.name + ", "
self.__logger.info( self.__logger.info(
f"state={tricker.playerState.name}, bullet={tricker.bulletType.name}, prop={trickerProp}")
f"state={tricker.playerState.name}, bullet={tricker.bulletType.name}, prop={trickerProp}"
)
self.__logger.info( self.__logger.info(
f"type={tricker.trickerType.name}, trick desire={tricker.trickDesire}, class volume={tricker.classVolume}")
f"type={tricker.trickerType.name}, trick desire={tricker.trickDesire}, class volume={tricker.classVolume}"
)
trickerBuff = "" trickerBuff = ""
for buff in tricker.buff: for buff in tricker.buff:
trickerBuff += buff.name + ", " trickerBuff += buff.name + ", "
@@ -817,25 +840,31 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer):
for prop in self.__logic.GetProps(): for prop in self.__logic.GetProps():
self.__logger.info("******Prop Info******") self.__logger.info("******Prop Info******")
self.__logger.info( self.__logger.info(
f"GUID={prop.guid}, x={prop.x}, y={prop.y}, facing direction={prop.facingDirection}")
f"GUID={prop.guid}, x={prop.x}, y={prop.y}, facing direction={prop.facingDirection}"
)
self.__logger.info("*********************") self.__logger.info("*********************")


def PrintSelfInfo(self) -> None: def PrintSelfInfo(self) -> None:
tricker = cast(THUAI6.Tricker, self.__logic.GetSelfInfo()) tricker = cast(THUAI6.Tricker, self.__logic.GetSelfInfo())
self.__logger.info("******Tricker Info******") self.__logger.info("******Tricker Info******")
self.__logger.info( self.__logger.info(
f"playerID={tricker.playerID}, GUID={tricker.guid}, x={tricker.x}, y={tricker.y}")
f"playerID={tricker.playerID}, GUID={tricker.guid}, x={tricker.x}, y={tricker.y}"
)
self.__logger.info( self.__logger.info(
f"speed={tricker.speed}, view range={tricker.viewRange}, radius={tricker.radius}")
f"speed={tricker.speed}, view range={tricker.viewRange}, radius={tricker.radius}"
)
self.__logger.info( self.__logger.info(
f"score={tricker.score}, facing direction={tricker.facingDirection}, skill time={tricker.timeUntilSkillAvailable}")
f"score={tricker.score}, facing direction={tricker.facingDirection}, skill time={tricker.timeUntilSkillAvailable}"
)
trickerProp = "" trickerProp = ""
for prop in tricker.prop: for prop in tricker.prop:
trickerProp += prop.name + ", " trickerProp += prop.name + ", "
self.__logger.info( self.__logger.info(
f"state={tricker.playerState.name}, bullet={tricker.bulletType.name}, prop={trickerProp}")
f"state={tricker.playerState.name}, bullet={tricker.bulletType.name}, prop={trickerProp}"
)
self.__logger.info( self.__logger.info(
f"type={tricker.trickerType.name}, trick desire={tricker.trickDesire}, class volume={tricker.classVolume}")
f"type={tricker.trickerType.name}, trick desire={tricker.trickDesire}, class volume={tricker.classVolume}"
)
trickerBuff = "" trickerBuff = ""
for buff in tricker.buff: for buff in tricker.buff:
trickerBuff += buff.name + ", " trickerBuff += buff.name + ", "
@@ -850,7 +879,9 @@ class TrickerDebugAPI(ITrickerAPI, IGameTimer):
# Timer用 # Timer用


def __GetTime(self) -> float: def __GetTime(self) -> float:
return (datetime.datetime.now() - self.__startPoint) / datetime.timedelta(milliseconds=1)
return (datetime.datetime.now() - self.__startPoint) / datetime.timedelta(
milliseconds=1
)


def StartTimer(self) -> None: def StartTimer(self) -> None:
self.__startPoint = datetime.datetime.now() self.__startPoint = datetime.datetime.now()


+ 3
- 6
CAPI/python/PyAPI/Interface.py View File

@@ -5,7 +5,6 @@ import PyAPI.structures as THUAI6




class ILogic(metaclass=ABCMeta): class ILogic(metaclass=ABCMeta):

# IAPI统一可用的接口 # IAPI统一可用的接口


@abstractmethod @abstractmethod
@@ -155,12 +154,13 @@ class ILogic(metaclass=ABCMeta):
pass pass


@abstractmethod @abstractmethod
def HaveView(self, gridX: int, gridY: int, selfX: int, selfY: int, viewRange: int) -> bool:
def HaveView(
self, gridX: int, gridY: int, selfX: int, selfY: int, viewRange: int
) -> bool:
pass pass




class IAPI(metaclass=ABCMeta): class IAPI(metaclass=ABCMeta):

# 选手可执行的操作 # 选手可执行的操作
# 指挥本角色进行移动,`timeInMilliseconds` 为移动时间,单位为毫秒;`angleInRadian` 表示移动的方向,单位是弧度,使用极坐标——竖直向下方向为 x 轴,水平向右方向为 y 轴 # 指挥本角色进行移动,`timeInMilliseconds` 为移动时间,单位为毫秒;`angleInRadian` 表示移动的方向,单位是弧度,使用极坐标——竖直向下方向为 x 轴,水平向右方向为 y 轴


@@ -346,7 +346,6 @@ class IAPI(metaclass=ABCMeta):




class IStudentAPI(IAPI, metaclass=ABCMeta): class IStudentAPI(IAPI, metaclass=ABCMeta):

# 人类阵营的特殊函数 # 人类阵营的特殊函数


@abstractmethod @abstractmethod
@@ -371,7 +370,6 @@ class IStudentAPI(IAPI, metaclass=ABCMeta):




class ITrickerAPI(IAPI, metaclass=ABCMeta): class ITrickerAPI(IAPI, metaclass=ABCMeta):

# 屠夫阵营的特殊函数 # 屠夫阵营的特殊函数


@abstractmethod @abstractmethod
@@ -390,7 +388,6 @@ class IAI(metaclass=ABCMeta):




class IGameTimer(metaclass=ABCMeta): class IGameTimer(metaclass=ABCMeta):

# 用于计时的接口 # 用于计时的接口


@abstractmethod @abstractmethod


+ 1
- 0
CAPI/python/PyAPI/State.py View File

@@ -15,6 +15,7 @@ class State:
self.mapInfo = THUAI6.GameMap() self.mapInfo = THUAI6.GameMap()
self.gameInfo = THUAI6.GameInfo() self.gameInfo = THUAI6.GameInfo()
self.guids = [] self.guids = []

teamScore: int teamScore: int
self: Union[THUAI6.Student, THUAI6.Tricker] self: Union[THUAI6.Student, THUAI6.Tricker]




+ 59
- 55
CAPI/python/PyAPI/constants.py View File

@@ -10,18 +10,18 @@ class NoInstance:
class Constants(NoInstance): class Constants(NoInstance):
frameDuration = 50 # 每帧毫秒数 frameDuration = 50 # 每帧毫秒数
numOfGridPerCell = 1000 # 单位坐标数 numOfGridPerCell = 1000 # 单位坐标数
rows = 50 # 地图行数
cols = 50 # 地图列数
rows = 50 # 地图行数
cols = 50 # 地图列数


numOfClassroom = 10 # 教室数量 numOfClassroom = 10 # 教室数量
numOfChest = 8 # 宝箱数量
numOfChest = 8 # 宝箱数量


maxClassroomProgress = 10000000 # 教室最大进度 maxClassroomProgress = 10000000 # 教室最大进度
maxDoorProgress = 10000000 # 开关门最大进度
maxChestProgress = 10000000 # 宝箱最大进度
maxGateProgress = 18000 # 大门最大进度
maxDoorProgress = 10000000 # 开关门最大进度
maxChestProgress = 10000000 # 宝箱最大进度
maxGateProgress = 18000 # 大门最大进度


numOfRequiredClassroomForGate = 7 # 打开大门需要完成的教室数量
numOfRequiredClassroomForGate = 7 # 打开大门需要完成的教室数量
numOfRequiredClassroomForHiddenGate = 3 # 打开隐藏门需要完成的教室数量 numOfRequiredClassroomForHiddenGate = 3 # 打开隐藏门需要完成的教室数量


# 人物属性相关 # 人物属性相关
@@ -52,16 +52,16 @@ class Constants(NoInstance):
# 攻击相关 # 攻击相关


basicApOfTricker = 1500000 basicApOfTricker = 1500000
basicCD = 3000 # 初始子弹冷却
basicCastTime = 500 # 基本前摇时间
basicBackswing = 800 # 基本后摇时间
basicCD = 3000 # 初始子弹冷却
basicCastTime = 500 # 基本前摇时间
basicBackswing = 800 # 基本后摇时间
basicRecoveryFromHit = 3700 # 基本命中攻击恢复时长 basicRecoveryFromHit = 3700 # 基本命中攻击恢复时长
basicStunnedTimeOfStudent = 4300 basicStunnedTimeOfStudent = 4300


basicBulletMoveSpeed = 7400 # 基本子弹移动速度
basicBulletMoveSpeed = 7400 # 基本子弹移动速度
basicRemoteAttackRange = 6000 # 基本远程攻击范围 basicRemoteAttackRange = 6000 # 基本远程攻击范围
basicAttackShortRange = 2200 # 基本近程攻击范围
basicBulletBombRange = 2000 # 基本子弹爆炸范围
basicAttackShortRange = 2200 # 基本近程攻击范围
basicBulletBombRange = 2000 # 基本子弹爆炸范围


# 道具相关 # 道具相关


@@ -96,10 +96,10 @@ class Assassin:
concealment = 1.5 * Constants.basicConcealment concealment = 1.5 * Constants.basicConcealment
alertnessRadius = (int)(1.3 * Constants.basicTrickerAlertnessRadius) alertnessRadius = (int)(1.3 * Constants.basicTrickerAlertnessRadius)
viewRange = (int)(1.2 * Constants.basicTrickerViewRange) viewRange = (int)(1.2 * Constants.basicTrickerViewRange)
speedOfOpeningOrLocking = (int)(
1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfOpeningOrLocking = (int)(1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfClimbingThroughWindows = (int)( speedOfClimbingThroughWindows = (int)(
1.0 * Constants.basicTrickerSpeedOfClimbingThroughWindows)
1.0 * Constants.basicTrickerSpeedOfClimbingThroughWindows
)
speedOfOpenChest = (int)(1.0 * Constants.basicSpeedOfOpenChest) speedOfOpenChest = (int)(1.0 * Constants.basicSpeedOfOpenChest)




@@ -108,10 +108,10 @@ class Klee:
concealment = 1.0 * Constants.basicConcealment concealment = 1.0 * Constants.basicConcealment
alertnessRadius = (int)(1.0 * Constants.basicTrickerAlertnessRadius) alertnessRadius = (int)(1.0 * Constants.basicTrickerAlertnessRadius)
viewRange = (int)(1.0 * Constants.basicTrickerViewRange) viewRange = (int)(1.0 * Constants.basicTrickerViewRange)
speedOfOpeningOrLocking = (int)(
1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfOpeningOrLocking = (int)(1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfClimbingThroughWindows = (int)( speedOfClimbingThroughWindows = (int)(
1.0 * Constants.basicTrickerSpeedOfClimbingThroughWindows)
1.0 * Constants.basicTrickerSpeedOfClimbingThroughWindows
)
speedOfOpenChest = (int)(1.1 * Constants.basicSpeedOfOpenChest) speedOfOpenChest = (int)(1.1 * Constants.basicSpeedOfOpenChest)




@@ -120,10 +120,10 @@ class ANoisyPerson:
concealment = 0.8 * Constants.basicConcealment concealment = 0.8 * Constants.basicConcealment
alertnessRadius = (int)(0.9 * Constants.basicTrickerAlertnessRadius) alertnessRadius = (int)(0.9 * Constants.basicTrickerAlertnessRadius)
viewRange = (int)(1.0 * Constants.basicTrickerViewRange) viewRange = (int)(1.0 * Constants.basicTrickerViewRange)
speedOfOpeningOrLocking = (int)(
1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfOpeningOrLocking = (int)(1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfClimbingThroughWindows = (int)( speedOfClimbingThroughWindows = (int)(
1.1 * Constants.basicTrickerSpeedOfClimbingThroughWindows)
1.1 * Constants.basicTrickerSpeedOfClimbingThroughWindows
)
speedOfOpenChest = (int)(1.1 * Constants.basicSpeedOfOpenChest) speedOfOpenChest = (int)(1.1 * Constants.basicSpeedOfOpenChest)




@@ -132,10 +132,10 @@ class Idol:
concealment = 0.75 * Constants.basicConcealment concealment = 0.75 * Constants.basicConcealment
alertnessRadius = (int)(1.0 * Constants.basicTrickerAlertnessRadius) alertnessRadius = (int)(1.0 * Constants.basicTrickerAlertnessRadius)
viewRange = (int)(1.1 * Constants.basicTrickerViewRange) viewRange = (int)(1.1 * Constants.basicTrickerViewRange)
speedOfOpeningOrLocking = (int)(
1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfOpeningOrLocking = (int)(1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfClimbingThroughWindows = (int)( speedOfClimbingThroughWindows = (int)(
1.0 * Constants.basicTrickerSpeedOfClimbingThroughWindows)
1.0 * Constants.basicTrickerSpeedOfClimbingThroughWindows
)
speedOfOpenChest = (int)(1.0 * Constants.basicSpeedOfOpenChest) speedOfOpenChest = (int)(1.0 * Constants.basicSpeedOfOpenChest)




@@ -148,10 +148,10 @@ class Athlete:
concealment = 0.9 * Constants.basicConcealment concealment = 0.9 * Constants.basicConcealment
alertnessRadius = (int)(1.0 * Constants.basicStudentAlertnessRadius) alertnessRadius = (int)(1.0 * Constants.basicStudentAlertnessRadius)
viewRange = (int)(1.1 * Constants.basicStudentViewRange) viewRange = (int)(1.1 * Constants.basicStudentViewRange)
speedOfOpeningOrLocking = (int)(
1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfOpeningOrLocking = (int)(1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfClimbingThroughWindows = (int)( speedOfClimbingThroughWindows = (int)(
1.2 * Constants.basicStudentSpeedOfClimbingThroughWindows)
1.2 * Constants.basicStudentSpeedOfClimbingThroughWindows
)
speedOfOpenChest = (int)(1.0 * Constants.basicSpeedOfOpenChest) speedOfOpenChest = (int)(1.0 * Constants.basicSpeedOfOpenChest)




@@ -164,10 +164,10 @@ class Teacher:
concealment = 0.5 * Constants.basicConcealment concealment = 0.5 * Constants.basicConcealment
alertnessRadius = (int)(0.5 * Constants.basicStudentAlertnessRadius) alertnessRadius = (int)(0.5 * Constants.basicStudentAlertnessRadius)
viewRange = (int)(0.9 * Constants.basicStudentViewRange) viewRange = (int)(0.9 * Constants.basicStudentViewRange)
speedOfOpeningOrLocking = (int)(
1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfOpeningOrLocking = (int)(1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfClimbingThroughWindows = (int)( speedOfClimbingThroughWindows = (int)(
0.5 * Constants.basicStudentSpeedOfClimbingThroughWindows)
0.5 * Constants.basicStudentSpeedOfClimbingThroughWindows
)
speedOfOpenChest = (int)(1.0 * Constants.basicSpeedOfOpenChest) speedOfOpenChest = (int)(1.0 * Constants.basicSpeedOfOpenChest)




@@ -180,10 +180,10 @@ class StraightAStudent:
concealment = 0.9 * Constants.basicConcealment concealment = 0.9 * Constants.basicConcealment
alertnessRadius = (int)(0.9 * Constants.basicStudentAlertnessRadius) alertnessRadius = (int)(0.9 * Constants.basicStudentAlertnessRadius)
viewRange = (int)(0.9 * Constants.basicStudentViewRange) viewRange = (int)(0.9 * Constants.basicStudentViewRange)
speedOfOpeningOrLocking = (int)(
1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfOpeningOrLocking = (int)(1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfClimbingThroughWindows = (int)( speedOfClimbingThroughWindows = (int)(
0.83333 * Constants.basicStudentSpeedOfClimbingThroughWindows)
0.83333 * Constants.basicStudentSpeedOfClimbingThroughWindows
)
speedOfOpenChest = (int)(1.0 * Constants.basicSpeedOfOpenChest) speedOfOpenChest = (int)(1.0 * Constants.basicSpeedOfOpenChest)




@@ -196,10 +196,10 @@ class Robot:
concealment = 1.0 * Constants.basicConcealment concealment = 1.0 * Constants.basicConcealment
alertnessRadius = (int)(1.0 * Constants.basicStudentAlertnessRadius) alertnessRadius = (int)(1.0 * Constants.basicStudentAlertnessRadius)
viewRange = (int)(1.0 * Constants.basicStudentViewRange) viewRange = (int)(1.0 * Constants.basicStudentViewRange)
speedOfOpeningOrLocking = (int)(
1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfOpeningOrLocking = (int)(1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfClimbingThroughWindows = (int)( speedOfClimbingThroughWindows = (int)(
0.0016 * Constants.basicStudentSpeedOfClimbingThroughWindows)
0.0016 * Constants.basicStudentSpeedOfClimbingThroughWindows
)
speedOfOpenChest = (int)(1.0 * Constants.basicSpeedOfOpenChest) speedOfOpenChest = (int)(1.0 * Constants.basicSpeedOfOpenChest)




@@ -212,10 +212,10 @@ class TechOtaku:
concealment = 1.0 * Constants.basicConcealment concealment = 1.0 * Constants.basicConcealment
alertnessRadius = (int)(1.0 * Constants.basicStudentAlertnessRadius) alertnessRadius = (int)(1.0 * Constants.basicStudentAlertnessRadius)
viewRange = (int)(0.9 * Constants.basicStudentViewRange) viewRange = (int)(0.9 * Constants.basicStudentViewRange)
speedOfOpeningOrLocking = (int)(
1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfOpeningOrLocking = (int)(1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfClimbingThroughWindows = (int)( speedOfClimbingThroughWindows = (int)(
0.75 * Constants.basicStudentSpeedOfClimbingThroughWindows)
0.75 * Constants.basicStudentSpeedOfClimbingThroughWindows
)
speedOfOpenChest = (int)(1.0 * Constants.basicSpeedOfOpenChest) speedOfOpenChest = (int)(1.0 * Constants.basicSpeedOfOpenChest)




@@ -228,10 +228,10 @@ class Sunshine:
concealment = 1.0 * Constants.basicConcealment concealment = 1.0 * Constants.basicConcealment
alertnessRadius = (int)(1.0 * Constants.basicStudentAlertnessRadius) alertnessRadius = (int)(1.0 * Constants.basicStudentAlertnessRadius)
viewRange = (int)(1.0 * Constants.basicStudentViewRange) viewRange = (int)(1.0 * Constants.basicStudentViewRange)
speedOfOpeningOrLocking = (int)(
0.7 * Constants.basicSpeedOfOpeningOrLocking)
speedOfOpeningOrLocking = (int)(0.7 * Constants.basicSpeedOfOpeningOrLocking)
speedOfClimbingThroughWindows = (int)( speedOfClimbingThroughWindows = (int)(
1.0 * Constants.basicStudentSpeedOfClimbingThroughWindows)
1.0 * Constants.basicStudentSpeedOfClimbingThroughWindows
)
speedOfOpenChest = (int)(0.9 * Constants.basicSpeedOfOpenChest) speedOfOpenChest = (int)(0.9 * Constants.basicSpeedOfOpenChest)




@@ -299,6 +299,7 @@ class SummonGolem:
skillCD = (int)(1.0 * Constants.commonSkillCD) skillCD = (int)(1.0 * Constants.commonSkillCD)
durationTime = (int)(0.0 * Constants.commonSkillTime) durationTime = (int)(0.0 * Constants.commonSkillTime)



class CommonAttackOfTricker: class CommonAttackOfTricker:
BulletBombRange = 0 BulletBombRange = 0
BulletAttackRange = Constants.basicAttackShortRange BulletAttackRange = Constants.basicAttackShortRange
@@ -310,34 +311,37 @@ class CommonAttackOfTricker:
RecoveryFromHit = Constants.basicRecoveryFromHit RecoveryFromHit = Constants.basicRecoveryFromHit
cd = Constants.basicBackswing cd = Constants.basicBackswing
maxBulletNum = 1 maxBulletNum = 1


class FlyingKnife: class FlyingKnife:
BulletBombRange = 0 BulletBombRange = 0
BulletAttackRange = Constants.basicRemoteAttackRange * 13 BulletAttackRange = Constants.basicRemoteAttackRange * 13
ap = Constants.basicApOfTricker* 4 / 5
Speed = Constants.basicBulletMoveSpeed* 25 / 10
ap = Constants.basicApOfTricker * 4 / 5
Speed = Constants.basicBulletMoveSpeed * 25 / 10
IsRemoteAttack = True IsRemoteAttack = True
CastTime = Constants.basicCastTime * 4 / 5 CastTime = Constants.basicCastTime * 4 / 5
Backswing =0
RecoveryFromHit =0
Backswing = 0
RecoveryFromHit = 0
cd = Constants.basicBackswing / 2 cd = Constants.basicBackswing / 2
maxBulletNum = 1 maxBulletNum = 1


class BombBomb: class BombBomb:
BulletBombRange = Constants.basicBulletBombRange BulletBombRange = Constants.basicBulletBombRange
BulletAttackRange = Constants.basicAttackShortRange BulletAttackRange = Constants.basicAttackShortRange
ap = Constants.basicApOfTricker * 6 / 5 ap = Constants.basicApOfTricker * 6 / 5
Speed = Constants.basicBulletMoveSpeed* 30 / 37
Speed = Constants.basicBulletMoveSpeed * 30 / 37
IsRemoteAttack = False IsRemoteAttack = False
CastTime = BulletAttackRange * 1000 / Speed CastTime = BulletAttackRange * 1000 / Speed
Backswing =Constants.basicRecoveryFromHit
RecoveryFromHit =Constants.basicRecoveryFromHit
Backswing = Constants.basicRecoveryFromHit
RecoveryFromHit = Constants.basicRecoveryFromHit
cd = Constants.basicCD cd = Constants.basicCD
maxBulletNum = 1 maxBulletNum = 1


class JumpyDumpty: class JumpyDumpty:
BulletBombRange = Constants.basicBulletBombRange / 2 BulletBombRange = Constants.basicBulletBombRange / 2
BulletAttackRange = Constants.basicRemoteAttackRange * 2 BulletAttackRange = Constants.basicRemoteAttackRange * 2
ap = (int)(Constants.basicApOfTricker* 0.6)
Speed = Constants.basicBulletMoveSpeed* 43 / 37
ap = (int)(Constants.basicApOfTricker * 0.6)
Speed = Constants.basicBulletMoveSpeed * 43 / 37
IsRemoteAttack = False IsRemoteAttack = False

+ 225
- 79
CAPI/python/PyAPI/logic.py View File

@@ -20,7 +20,6 @@ from PyAPI.Interface import ILogic, IGameTimer


class Logic(ILogic): class Logic(ILogic):
def __init__(self, playerID: int, playerType: THUAI6.PlayerType) -> None: def __init__(self, playerID: int, playerType: THUAI6.PlayerType) -> None:

# ID # ID
self.__playerID: int = playerID self.__playerID: int = playerID


@@ -103,7 +102,12 @@ class Logic(ILogic):


def GetPlaceType(self, x: int, y: int) -> THUAI6.PlaceType: def GetPlaceType(self, x: int, y: int) -> THUAI6.PlaceType:
with self.__mtxState: with self.__mtxState:
if x < 0 or x >= len(self.__currentState.gameMap) or y < 0 or y >= len(self.__currentState.gameMap[0]):
if (
x < 0
or x >= len(self.__currentState.gameMap)
or y < 0
or y >= len(self.__currentState.gameMap[0])
):
self.__logger.warning("Invalid position") self.__logger.warning("Invalid position")
return THUAI6.PlaceType.NullPlaceType return THUAI6.PlaceType.NullPlaceType
self.__logger.debug("Called GetPlaceType") self.__logger.debug("Called GetPlaceType")
@@ -149,7 +153,9 @@ class Logic(ILogic):
with self.__mtxState: with self.__mtxState:
self.__logger.debug("Called GetHiddenGateState") self.__logger.debug("Called GetHiddenGateState")
if (x, y) in self.__currentState.mapInfo.hiddenGateState: if (x, y) in self.__currentState.mapInfo.hiddenGateState:
return copy.deepcopy(self.__currentState.mapInfo.hiddenGateState[(x, y)])
return copy.deepcopy(
self.__currentState.mapInfo.hiddenGateState[(x, y)]
)
else: else:
self.__logger.warning("HiddenGate not found") self.__logger.warning("HiddenGate not found")
return THUAI6.HiddenGateState.Null return THUAI6.HiddenGateState.Null
@@ -262,9 +268,13 @@ class Logic(ILogic):
self.__logger.debug("Called EndAllAction") self.__logger.debug("Called EndAllAction")
return self.__comm.EndAllAction(self.__playerID) return self.__comm.EndAllAction(self.__playerID)


def HaveView(self, gridX: int, gridY: int, selfX: int, selfY: int, viewRange: int) -> bool:
def HaveView(
self, gridX: int, gridY: int, selfX: int, selfY: int, viewRange: int
) -> bool:
with self.__mtxState: with self.__mtxState:
return AssistFunction.HaveView(viewRange, selfX, selfY, gridX, gridY, self.__currentState.gameMap)
return AssistFunction.HaveView(
viewRange, selfX, selfY, gridX, gridY, self.__currentState.gameMap
)


# Logic内部逻辑 # Logic内部逻辑
def __TryConnection(self) -> bool: def __TryConnection(self) -> bool:
@@ -281,8 +291,7 @@ class Logic(ILogic):
# 读取消息,无消息时此处阻塞 # 读取消息,无消息时此处阻塞
clientMsg = self.__comm.GetMessage2Client() clientMsg = self.__comm.GetMessage2Client()
self.__logger.debug("Get message from server!") self.__logger.debug("Get message from server!")
self.__gameState = Proto2THUAI6.gameStateDict[
clientMsg.game_state]
self.__gameState = Proto2THUAI6.gameStateDict[clientMsg.game_state]


if self.__gameState == THUAI6.GameState.GameStart: if self.__gameState == THUAI6.GameState.GameStart:
# 读取玩家的GUID # 读取玩家的GUID
@@ -294,8 +303,7 @@ class Logic(ILogic):
for row in obj.map_message.row: for row in obj.map_message.row:
col: List[THUAI6.PlaceType] = [] col: List[THUAI6.PlaceType] = []
for place in row.col: for place in row.col:
col.append(
Proto2THUAI6.placeTypeDict[place])
col.append(Proto2THUAI6.placeTypeDict[place])
gameMap.append(col) gameMap.append(col)
self.__currentState.gameMap = gameMap self.__currentState.gameMap = gameMap
self.__bufferState.gameMap = gameMap self.__bufferState.gameMap = gameMap
@@ -330,127 +338,238 @@ class Logic(ILogic):
if item.WhichOneof("message_of_obj") == "student_message": if item.WhichOneof("message_of_obj") == "student_message":
if item.student_message.player_id == self.__playerID: if item.student_message.player_id == self.__playerID:
self.__bufferState.self = Proto2THUAI6.Protobuf2THUAI6Student( self.__bufferState.self = Proto2THUAI6.Protobuf2THUAI6Student(
item.student_message)
self.__bufferState.students.append(
self.__bufferState.self)
item.student_message
)
self.__bufferState.students.append(self.__bufferState.self)
else: else:
self.__bufferState.students.append( self.__bufferState.students.append(
Proto2THUAI6.Protobuf2THUAI6Student(item.student_message))
Proto2THUAI6.Protobuf2THUAI6Student(item.student_message)
)
self.__logger.debug("Add Student!") self.__logger.debug("Add Student!")
else: else:
for item in message.obj_message: for item in message.obj_message:
if item.WhichOneof("message_of_obj") == "tricker_message": if item.WhichOneof("message_of_obj") == "tricker_message":
if item.tricker_message.player_id == self.__playerID: if item.tricker_message.player_id == self.__playerID:
self.__bufferState.self = Proto2THUAI6.Protobuf2THUAI6Tricker( self.__bufferState.self = Proto2THUAI6.Protobuf2THUAI6Tricker(
item.tricker_message)
self.__bufferState.trickers.append(
self.__bufferState.self)
item.tricker_message
)
self.__bufferState.trickers.append(self.__bufferState.self)
else: else:
self.__bufferState.trickers.append( self.__bufferState.trickers.append(
Proto2THUAI6.Protobuf2THUAI6Tricker(item.tricker_message))
Proto2THUAI6.Protobuf2THUAI6Tricker(item.tricker_message)
)
self.__logger.debug("Add Tricker!") self.__logger.debug("Add Tricker!")


def __LoadBufferCase(self, item: Message2Clients.MessageOfObj) -> None: def __LoadBufferCase(self, item: Message2Clients.MessageOfObj) -> None:
if self.__playerType == THUAI6.PlayerType.StudentPlayer and item.WhichOneof("message_of_obj") == "tricker_message":
if (
self.__playerType == THUAI6.PlayerType.StudentPlayer
and item.WhichOneof("message_of_obj") == "tricker_message"
):
if MessageType.TRICKER_INVISIBLE in item.tricker_message.buff: if MessageType.TRICKER_INVISIBLE in item.tricker_message.buff:
return return
if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.tricker_message.x, item.tricker_message.y, self.__bufferState.gameMap):
if AssistFunction.HaveView(
self.__bufferState.self.viewRange,
self.__bufferState.self.x,
self.__bufferState.self.y,
item.tricker_message.x,
item.tricker_message.y,
self.__bufferState.gameMap,
):
self.__bufferState.trickers.append( self.__bufferState.trickers.append(
Proto2THUAI6.Protobuf2THUAI6Tricker(item.tricker_message))
Proto2THUAI6.Protobuf2THUAI6Tricker(item.tricker_message)
)
self.__logger.debug("Add Tricker!") self.__logger.debug("Add Tricker!")
elif self.__playerType == THUAI6.PlayerType.TrickerPlayer and item.WhichOneof("message_of_obj") == "student_message":
elif (
self.__playerType == THUAI6.PlayerType.TrickerPlayer
and item.WhichOneof("message_of_obj") == "student_message"
):
if THUAI6.TrickerBuffType.Clairaudience in self.__bufferState.self.buff: if THUAI6.TrickerBuffType.Clairaudience in self.__bufferState.self.buff:
self.__bufferState.students.append( self.__bufferState.students.append(
Proto2THUAI6.Protobuf2THUAI6Student(item.student_message))
Proto2THUAI6.Protobuf2THUAI6Student(item.student_message)
)
self.__logger.debug("Add Student!") self.__logger.debug("Add Student!")
return return
if MessageType.STUDENT_INVISIBLE in item.student_message.buff: if MessageType.STUDENT_INVISIBLE in item.student_message.buff:
return return
if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.student_message.x, item.student_message.y, self.__bufferState.gameMap):
if AssistFunction.HaveView(
self.__bufferState.self.viewRange,
self.__bufferState.self.x,
self.__bufferState.self.y,
item.student_message.x,
item.student_message.y,
self.__bufferState.gameMap,
):
self.__bufferState.students.append( self.__bufferState.students.append(
Proto2THUAI6.Protobuf2THUAI6Student(item.student_message))
Proto2THUAI6.Protobuf2THUAI6Student(item.student_message)
)
self.__logger.debug("Add Student!") self.__logger.debug("Add Student!")
elif item.WhichOneof("message_of_obj") == "prop_message": elif item.WhichOneof("message_of_obj") == "prop_message":
if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.prop_message.x, item.prop_message.y, self.__bufferState.gameMap):
if AssistFunction.HaveView(
self.__bufferState.self.viewRange,
self.__bufferState.self.x,
self.__bufferState.self.y,
item.prop_message.x,
item.prop_message.y,
self.__bufferState.gameMap,
):
self.__bufferState.props.append( self.__bufferState.props.append(
Proto2THUAI6.Protobuf2THUAI6Prop(item.prop_message))
Proto2THUAI6.Protobuf2THUAI6Prop(item.prop_message)
)
self.__logger.debug("Add Prop!") self.__logger.debug("Add Prop!")
elif item.WhichOneof("message_of_obj") == "bullet_message": elif item.WhichOneof("message_of_obj") == "bullet_message":
if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.bullet_message.x, item.bullet_message.y, self.__bufferState.gameMap):
if AssistFunction.HaveView(
self.__bufferState.self.viewRange,
self.__bufferState.self.x,
self.__bufferState.self.y,
item.bullet_message.x,
item.bullet_message.y,
self.__bufferState.gameMap,
):
self.__bufferState.bullets.append( self.__bufferState.bullets.append(
Proto2THUAI6.Protobuf2THUAI6Bullet(item.bullet_message))
Proto2THUAI6.Protobuf2THUAI6Bullet(item.bullet_message)
)
self.__logger.debug("Add Bullet!") self.__logger.debug("Add Bullet!")
elif item.WhichOneof("message_of_obj") == "classroom_message": elif item.WhichOneof("message_of_obj") == "classroom_message":
if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.classroom_message.x, item.classroom_message.y, self.__bufferState.gameMap):
pos = (AssistFunction.GridToCell(
item.classroom_message.x), AssistFunction.GridToCell(item.classroom_message.y))
if AssistFunction.HaveView(
self.__bufferState.self.viewRange,
self.__bufferState.self.x,
self.__bufferState.self.y,
item.classroom_message.x,
item.classroom_message.y,
self.__bufferState.gameMap,
):
pos = (
AssistFunction.GridToCell(item.classroom_message.x),
AssistFunction.GridToCell(item.classroom_message.y),
)
if pos not in self.__bufferState.mapInfo.classroomState: if pos not in self.__bufferState.mapInfo.classroomState:
self.__bufferState.mapInfo.classroomState[pos] = item.classroom_message.progress
self.__bufferState.mapInfo.classroomState[
pos
] = item.classroom_message.progress
self.__logger.debug("Add Classroom!") self.__logger.debug("Add Classroom!")
else: else:
self.__bufferState.mapInfo.classroomState[pos] = item.classroom_message.progress
self.__bufferState.mapInfo.classroomState[
pos
] = item.classroom_message.progress
self.__logger.debug("Update Classroom!") self.__logger.debug("Update Classroom!")
elif item.WhichOneof("message_of_obj") == "chest_message": elif item.WhichOneof("message_of_obj") == "chest_message":
if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.chest_message.x, item.chest_message.y, self.__bufferState.gameMap):
pos = (AssistFunction.GridToCell(
item.chest_message.x), AssistFunction.GridToCell(item.chest_message.y))
if AssistFunction.HaveView(
self.__bufferState.self.viewRange,
self.__bufferState.self.x,
self.__bufferState.self.y,
item.chest_message.x,
item.chest_message.y,
self.__bufferState.gameMap,
):
pos = (
AssistFunction.GridToCell(item.chest_message.x),
AssistFunction.GridToCell(item.chest_message.y),
)
if pos not in self.__bufferState.mapInfo.chestState: if pos not in self.__bufferState.mapInfo.chestState:
self.__bufferState.mapInfo.chestState[pos] = item.chest_message.progress
self.__logger.debug(
f"Add Chest at {pos[0]}, {pos[1]}")
self.__bufferState.mapInfo.chestState[
pos
] = item.chest_message.progress
self.__logger.debug(f"Add Chest at {pos[0]}, {pos[1]}")
else: else:
self.__bufferState.mapInfo.chestState[pos] = item.chest_message.progress
self.__logger.debug(
f"Update Chest at {pos[0]}, {pos[1]}")
self.__bufferState.mapInfo.chestState[
pos
] = item.chest_message.progress
self.__logger.debug(f"Update Chest at {pos[0]}, {pos[1]}")
elif item.WhichOneof("message_of_obj") == "door_message": elif item.WhichOneof("message_of_obj") == "door_message":
if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.door_message.x, item.door_message.y, self.__bufferState.gameMap):
pos = (AssistFunction.GridToCell(
item.door_message.x), AssistFunction.GridToCell(item.door_message.y))
if AssistFunction.HaveView(
self.__bufferState.self.viewRange,
self.__bufferState.self.x,
self.__bufferState.self.y,
item.door_message.x,
item.door_message.y,
self.__bufferState.gameMap,
):
pos = (
AssistFunction.GridToCell(item.door_message.x),
AssistFunction.GridToCell(item.door_message.y),
)
if pos not in self.__bufferState.mapInfo.doorState: if pos not in self.__bufferState.mapInfo.doorState:
self.__bufferState.mapInfo.doorState[pos] = item.door_message.is_open
self.__bufferState.mapInfo.doorProgress[pos] = item.door_message.progress
self.__bufferState.mapInfo.doorState[
pos
] = item.door_message.is_open
self.__bufferState.mapInfo.doorProgress[
pos
] = item.door_message.progress
self.__logger.debug("Add Door!") self.__logger.debug("Add Door!")
else: else:
self.__bufferState.mapInfo.doorState[pos] = item.door_message.is_open
self.__bufferState.mapInfo.doorProgress[pos] = item.door_message.progress
self.__bufferState.mapInfo.doorState[
pos
] = item.door_message.is_open
self.__bufferState.mapInfo.doorProgress[
pos
] = item.door_message.progress
self.__logger.debug("Update Door!") self.__logger.debug("Update Door!")
elif item.WhichOneof("message_of_obj") == "hidden_gate_message": elif item.WhichOneof("message_of_obj") == "hidden_gate_message":
if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.hidden_gate_message.x, item.hidden_gate_message.y, self.__bufferState.gameMap):
pos = (AssistFunction.GridToCell(
item.hidden_gate_message.x), AssistFunction.GridToCell(item.hidden_gate_message.y))
if AssistFunction.HaveView(
self.__bufferState.self.viewRange,
self.__bufferState.self.x,
self.__bufferState.self.y,
item.hidden_gate_message.x,
item.hidden_gate_message.y,
self.__bufferState.gameMap,
):
pos = (
AssistFunction.GridToCell(item.hidden_gate_message.x),
AssistFunction.GridToCell(item.hidden_gate_message.y),
)
if pos not in self.__bufferState.mapInfo.hiddenGateState: if pos not in self.__bufferState.mapInfo.hiddenGateState:
self.__bufferState.mapInfo.hiddenGateState[pos] = Proto2THUAI6.Bool2HiddenGateState(
item.hidden_gate_message.opened)
self.__bufferState.mapInfo.hiddenGateState[
pos
] = Proto2THUAI6.Bool2HiddenGateState(
item.hidden_gate_message.opened
)
self.__logger.debug("Add HiddenGate!") self.__logger.debug("Add HiddenGate!")
else: else:
self.__bufferState.mapInfo.hiddenGateState[pos] = Proto2THUAI6.Bool2HiddenGateState(
item.hidden_gate_message.opened)
self.__bufferState.mapInfo.hiddenGateState[
pos
] = Proto2THUAI6.Bool2HiddenGateState(
item.hidden_gate_message.opened
)
self.__logger.debug("Update HiddenGate!") self.__logger.debug("Update HiddenGate!")
elif item.WhichOneof("message_of_obj") == "gate_message": elif item.WhichOneof("message_of_obj") == "gate_message":
if AssistFunction.HaveView(self.__bufferState.self.viewRange, self.__bufferState.self.x, self.__bufferState.self.y, item.gate_message.x, item.gate_message.y, self.__bufferState.gameMap):
pos = (AssistFunction.GridToCell(
item.gate_message.x), AssistFunction.GridToCell(item.gate_message.y))
if AssistFunction.HaveView(
self.__bufferState.self.viewRange,
self.__bufferState.self.x,
self.__bufferState.self.y,
item.gate_message.x,
item.gate_message.y,
self.__bufferState.gameMap,
):
pos = (
AssistFunction.GridToCell(item.gate_message.x),
AssistFunction.GridToCell(item.gate_message.y),
)
if pos not in self.__bufferState.mapInfo.gateState: if pos not in self.__bufferState.mapInfo.gateState:
self.__bufferState.mapInfo.gateState[pos] = item.gate_message.progress
self.__bufferState.mapInfo.gateState[
pos
] = item.gate_message.progress
self.__logger.debug("Add Gate!") self.__logger.debug("Add Gate!")
else: else:
self.__bufferState.mapInfo.gateState[pos] = item.gate_message.progress
self.__bufferState.mapInfo.gateState[
pos
] = item.gate_message.progress
self.__logger.debug("Update Gate!") self.__logger.debug("Update Gate!")
elif item.WhichOneof("message_of_obj") == "news_message": elif item.WhichOneof("message_of_obj") == "news_message":
if item.news_message.to_id == self.__playerID: if item.news_message.to_id == self.__playerID:
if item.news_message.WhichOneof("news") == "text_message": if item.news_message.WhichOneof("news") == "text_message":
self.__messageQueue.put( self.__messageQueue.put(
(item.news_message.from_id, item.news_message.text_message))
(item.news_message.from_id, item.news_message.text_message)
)
self.__logger.debug("Add News!") self.__logger.debug("Add News!")
elif item.news_message.WhichOneof("news") == "binary_message": elif item.news_message.WhichOneof("news") == "binary_message":
self.__messageQueue.put( self.__messageQueue.put(
(item.news_message.from_id, item.news_message.binary_message))
(item.news_message.from_id, item.news_message.binary_message)
)
self.__logger.debug("Add News!") self.__logger.debug("Add News!")
else: else:
self.__logger.error("Unknown News!") self.__logger.error("Unknown News!")
else: else:
self.__logger.debug(
"Unknown Message!")
self.__logger.debug("Unknown Message!")


def __LoadBuffer(self, message: Message2Clients.MessageToClient) -> None: def __LoadBuffer(self, message: Message2Clients.MessageToClient) -> None:
with self.__cvBuffer: with self.__cvBuffer:
@@ -470,14 +589,18 @@ class Logic(ILogic):
self.__bufferState.guids.append(obj.tricker_message.guid) self.__bufferState.guids.append(obj.tricker_message.guid)


self.__bufferState.gameInfo = Proto2THUAI6.Protobuf2THUAI6GameInfo( self.__bufferState.gameInfo = Proto2THUAI6.Protobuf2THUAI6GameInfo(
message.all_message)
message.all_message
)


self.__LoadBufferSelf(message) self.__LoadBufferSelf(message)
for item in message.obj_message: for item in message.obj_message:
self.__LoadBufferCase(item) self.__LoadBufferCase(item)
if Setting.asynchronous(): if Setting.asynchronous():
with self.__mtxState: with self.__mtxState:
self.__currentState, self.__bufferState = self.__bufferState, self.__currentState
self.__currentState, self.__bufferState = (
self.__bufferState,
self.__currentState,
)
self.__counterState = self.__counterBuffer self.__counterState = self.__counterBuffer
self.__logger.info("Update state!") self.__logger.info("Update state!")
self.__freshed = True self.__freshed = True
@@ -496,7 +619,10 @@ class Logic(ILogic):
with self.__cvBuffer: with self.__cvBuffer:
self.__cvBuffer.wait_for(lambda: self.__bufferUpdated) self.__cvBuffer.wait_for(lambda: self.__bufferUpdated)
with self.__mtxState: with self.__mtxState:
self.__bufferState, self.__currentState = self.__currentState, self.__bufferState
self.__bufferState, self.__currentState = (
self.__currentState,
self.__bufferState,
)
self.__counterState = self.__counterBuffer self.__counterState = self.__counterBuffer
self.__bufferUpdated = False self.__bufferUpdated = False
self.__logger.info("Update state!") self.__logger.info("Update state!")
@@ -506,12 +632,21 @@ class Logic(ILogic):
with self.__cvBuffer: with self.__cvBuffer:
self.__cvBuffer.wait_for(lambda: self.__freshed) self.__cvBuffer.wait_for(lambda: self.__freshed)


def Main(self, createAI: Callable, IP: str, port: str, file: bool, screen: bool, warnOnly: bool) -> None:

def Main(
self,
createAI: Callable,
IP: str,
port: str,
file: bool,
screen: bool,
warnOnly: bool,
) -> None:
# 建立日志组件 # 建立日志组件
self.__logger.setLevel(logging.DEBUG) self.__logger.setLevel(logging.DEBUG)
formatter = logging.Formatter( formatter = logging.Formatter(
"[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s", '%H:%M:%S')
"[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s",
"%H:%M:%S",
)
# 确保文件存在 # 确保文件存在
# if not os.path.exists(os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/logs"): # if not os.path.exists(os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/logs"):
# os.makedirs(os.path.dirname(os.path.dirname( # os.makedirs(os.path.dirname(os.path.dirname(
@@ -519,13 +654,21 @@ class Logic(ILogic):


if platform.system().lower() == "windows": if platform.system().lower() == "windows":
os.system( os.system(
f"mkdir \"{os.path.dirname(os.path.dirname(os.path.realpath(__file__)))}\\logs\"")
f'mkdir "{os.path.dirname(os.path.dirname(os.path.realpath(__file__)))}\\logs"'
)
else: else:
os.system( os.system(
f"mkdir -p \"{os.path.dirname(os.path.dirname(os.path.realpath(__file__)))}/logs\"")

fileHandler = logging.FileHandler(os.path.dirname(
os.path.dirname(os.path.realpath(__file__))) + "/logs/logic" + str(self.__playerID) + "-log.txt", "w+", encoding="utf-8")
f'mkdir -p "{os.path.dirname(os.path.dirname(os.path.realpath(__file__)))}/logs"'
)

fileHandler = logging.FileHandler(
os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
+ "/logs/logic"
+ str(self.__playerID)
+ "-log.txt",
"w+",
encoding="utf-8",
)
screenHandler = logging.StreamHandler() screenHandler = logging.StreamHandler()
if file: if file:
fileHandler.setLevel(logging.DEBUG) fileHandler.setLevel(logging.DEBUG)
@@ -555,13 +698,15 @@ class Logic(ILogic):
self.__timer = StudentAPI(self) self.__timer = StudentAPI(self)
else: else:
self.__timer = StudentDebugAPI( self.__timer = StudentDebugAPI(
self, file, screen, warnOnly, self.__playerID)
self, file, screen, warnOnly, self.__playerID
)
elif self.__playerType == THUAI6.PlayerType.TrickerPlayer: elif self.__playerType == THUAI6.PlayerType.TrickerPlayer:
if not file and not screen: if not file and not screen:
self.__timer = TrickerAPI(self) self.__timer = TrickerAPI(self)
else: else:
self.__timer = TrickerDebugAPI( self.__timer = TrickerDebugAPI(
self, file, screen, warnOnly, self.__playerID)
self, file, screen, warnOnly, self.__playerID
)


# 构建AI线程 # 构建AI线程
def AIThread(): def AIThread():
@@ -583,7 +728,8 @@ class Logic(ILogic):


if self.__TryConnection(): if self.__TryConnection():
self.__logger.info( self.__logger.info(
"Connect to the server successfully, AI thread will be started.")
"Connect to the server successfully, AI thread will be started."
)
self.__threadAI = threading.Thread(target=AIThread) self.__threadAI = threading.Thread(target=AIThread)
self.__threadAI.start() self.__threadAI.start()
self.__ProcessMessage() self.__ProcessMessage()


+ 47
- 16
CAPI/python/PyAPI/main.py View File

@@ -1,8 +1,8 @@
import os import os
import sys import sys

sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
sys.path.append(os.path.dirname(os.path.dirname(
os.path.realpath(__file__))) + '/proto')
sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + "/proto")


from PyAPI.Interface import IAI from PyAPI.Interface import IAI
from PyAPI.AI import AI from PyAPI.AI import AI
@@ -42,19 +42,50 @@ def THUAI6Main(argv: List[str], AIBuilder: Callable) -> None:
screen: bool = True screen: bool = True
warnOnly: bool = False warnOnly: bool = False
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="THUAI6 Python Interface Commandline Parameter Introduction")
parser.add_argument("-I", type=str, required=True,
help="Server`s IP 127.0.0.1 in default", dest="sIP", default="127.0.0.1")
parser.add_argument("-P", type=str, required=True,
help="Server`s Port 8888 in default", dest="sPort", default="8888")
parser.add_argument("-p", type=int, required=True,
help="Player`s ID", dest="pID", choices=[0, 1, 2, 3, 4])
parser.add_argument("-d", action='store_true',
help="Set this flag to save the debug log to ./logs folder", dest="file")
parser.add_argument("-o", action='store_true',
help="Set this flag to print the debug log to the screen", dest="screen")
parser.add_argument("-w", action='store_true',
help="Set this flag to only print warning on the screen", dest="warnOnly")
description="THUAI6 Python Interface Commandline Parameter Introduction"
)
parser.add_argument(
"-I",
type=str,
required=True,
help="Server`s IP 127.0.0.1 in default",
dest="sIP",
default="127.0.0.1",
)
parser.add_argument(
"-P",
type=str,
required=True,
help="Server`s Port 8888 in default",
dest="sPort",
default="8888",
)
parser.add_argument(
"-p",
type=int,
required=True,
help="Player`s ID",
dest="pID",
choices=[0, 1, 2, 3, 4],
)
parser.add_argument(
"-d",
action="store_true",
help="Set this flag to save the debug log to ./logs folder",
dest="file",
)
parser.add_argument(
"-o",
action="store_true",
help="Set this flag to print the debug log to the screen",
dest="screen",
)
parser.add_argument(
"-w",
action="store_true",
help="Set this flag to only print warning on the screen",
dest="warnOnly",
)
args = parser.parse_args() args = parser.parse_args()
pID = args.pID pID = args.pID
sIP = args.sIP sIP = args.sIP
@@ -79,5 +110,5 @@ def CreateAI(pID: int) -> IAI:
return AI(pID) return AI(pID)




if __name__ == '__main__':
if __name__ == "__main__":
THUAI6Main(sys.argv, CreateAI) THUAI6Main(sys.argv, CreateAI)

+ 115
- 52
CAPI/python/PyAPI/utils.py View File

@@ -15,7 +15,6 @@ class NoInstance:




class AssistFunction(NoInstance): class AssistFunction(NoInstance):

@staticmethod @staticmethod
def CellToGrid(cell: int) -> int: def CellToGrid(cell: int) -> int:
return cell * numOfGridPerCell + numOfGridPerCell // 2 return cell * numOfGridPerCell + numOfGridPerCell // 2
@@ -25,14 +24,19 @@ class AssistFunction(NoInstance):
return grid // numOfGridPerCell return grid // numOfGridPerCell


@staticmethod @staticmethod
def HaveView(viewRange: int, x: int, y: int, newX: int, newY: int, map: List[List[THUAI6.PlaceType]]) -> bool:
def HaveView(
viewRange: int,
x: int,
y: int,
newX: int,
newY: int,
map: List[List[THUAI6.PlaceType]],
) -> bool:
deltaX: int = newX - x deltaX: int = newX - x
deltaY: int = newY - y deltaY: int = newY - y
distance: float = deltaX**2 + deltaY**2 distance: float = deltaX**2 + deltaY**2
myPlace = map[AssistFunction.GridToCell(
x)][AssistFunction.GridToCell(y)]
newPlace = map[AssistFunction.GridToCell(
newX)][AssistFunction.GridToCell(newY)]
myPlace = map[AssistFunction.GridToCell(x)][AssistFunction.GridToCell(y)]
newPlace = map[AssistFunction.GridToCell(newX)][AssistFunction.GridToCell(newY)]
if myPlace != THUAI6.PlaceType.Grass and newPlace == THUAI6.PlaceType.Grass: if myPlace != THUAI6.PlaceType.Grass and newPlace == THUAI6.PlaceType.Grass:
return False return False
if distance <= viewRange * viewRange: if distance <= viewRange * viewRange:
@@ -47,7 +51,12 @@ class AssistFunction(NoInstance):
for i in range(divide): for i in range(divide):
selfX += dx selfX += dx
selfY += dy selfY += dy
if map[AssistFunction.GridToCell(int(selfX))][AssistFunction.GridToCell(int(selfY))] != THUAI6.PlaceType.Grass:
if (
map[AssistFunction.GridToCell(int(selfX))][
AssistFunction.GridToCell(int(selfY))
]
!= THUAI6.PlaceType.Grass
):
return False return False
else: else:
return True return True
@@ -55,7 +64,12 @@ class AssistFunction(NoInstance):
for i in range(divide): for i in range(divide):
selfX += dx selfX += dx
selfY += dy selfY += dy
if map[AssistFunction.GridToCell(int(selfX))][AssistFunction.GridToCell(int(selfY))] == THUAI6.PlaceType.Wall:
if (
map[AssistFunction.GridToCell(int(selfX))][
AssistFunction.GridToCell(int(selfY))
]
== THUAI6.PlaceType.Wall
):
return False return False
else: else:
return True return True
@@ -76,12 +90,14 @@ class Proto2THUAI6(NoInstance):
MessageType.DOOR3: THUAI6.PlaceType.Door3, MessageType.DOOR3: THUAI6.PlaceType.Door3,
MessageType.DOOR5: THUAI6.PlaceType.Door5, MessageType.DOOR5: THUAI6.PlaceType.Door5,
MessageType.DOOR6: THUAI6.PlaceType.Door6, MessageType.DOOR6: THUAI6.PlaceType.Door6,
MessageType.CHEST: THUAI6.PlaceType.Chest, }
MessageType.CHEST: THUAI6.PlaceType.Chest,
}


shapeTypeDict: Final[dict] = { shapeTypeDict: Final[dict] = {
MessageType.NULL_SHAPE_TYPE: THUAI6.ShapeType.NullShapeType, MessageType.NULL_SHAPE_TYPE: THUAI6.ShapeType.NullShapeType,
MessageType.SQUARE: THUAI6.ShapeType.Square, MessageType.SQUARE: THUAI6.ShapeType.Square,
MessageType.CIRCLE: THUAI6.ShapeType.Circle}
MessageType.CIRCLE: THUAI6.ShapeType.Circle,
}


propTypeDict: Final[dict] = { propTypeDict: Final[dict] = {
MessageType.NULL_PROP_TYPE: THUAI6.PropType.NullPropType, MessageType.NULL_PROP_TYPE: THUAI6.PropType.NullPropType,
@@ -92,12 +108,14 @@ class Proto2THUAI6(NoInstance):
MessageType.ADD_HP_OR_AP: THUAI6.PropType.AddHpOrAp, MessageType.ADD_HP_OR_AP: THUAI6.PropType.AddHpOrAp,
MessageType.ADD_LIFE_OR_CLAIRAUDIENCE: THUAI6.PropType.AddLifeOrClairaudience, MessageType.ADD_LIFE_OR_CLAIRAUDIENCE: THUAI6.PropType.AddLifeOrClairaudience,
MessageType.SHIELD_OR_SPEAR: THUAI6.PropType.ShieldOrSpear, MessageType.SHIELD_OR_SPEAR: THUAI6.PropType.ShieldOrSpear,
MessageType.RECOVERY_FROM_DIZZINESS: THUAI6.PropType.RecoveryFromDizziness, }
MessageType.RECOVERY_FROM_DIZZINESS: THUAI6.PropType.RecoveryFromDizziness,
}


playerTypeDict: Final[dict] = { playerTypeDict: Final[dict] = {
MessageType.NULL_PLAYER_TYPE: THUAI6.PlayerType.NullPlayerType, MessageType.NULL_PLAYER_TYPE: THUAI6.PlayerType.NullPlayerType,
MessageType.STUDENT_PLAYER: THUAI6.PlayerType.StudentPlayer, MessageType.STUDENT_PLAYER: THUAI6.PlayerType.StudentPlayer,
MessageType.TRICKER_PLAYER: THUAI6.PlayerType.TrickerPlayer, }
MessageType.TRICKER_PLAYER: THUAI6.PlayerType.TrickerPlayer,
}


studentTypeDict: Final[dict] = { studentTypeDict: Final[dict] = {
MessageType.NULL_STUDENT_TYPE: THUAI6.StudentType.NullStudentType, MessageType.NULL_STUDENT_TYPE: THUAI6.StudentType.NullStudentType,
@@ -106,21 +124,24 @@ class Proto2THUAI6(NoInstance):
MessageType.STRAIGHT_A_STUDENT: THUAI6.StudentType.StraightAStudent, MessageType.STRAIGHT_A_STUDENT: THUAI6.StudentType.StraightAStudent,
MessageType.ROBOT: THUAI6.StudentType.Robot, MessageType.ROBOT: THUAI6.StudentType.Robot,
MessageType.TECH_OTAKU: THUAI6.StudentType.TechOtaku, MessageType.TECH_OTAKU: THUAI6.StudentType.TechOtaku,
MessageType.SUNSHINE: THUAI6.StudentType.Sunshine, }
MessageType.SUNSHINE: THUAI6.StudentType.Sunshine,
}


trickerTypeDict: Final[dict] = { trickerTypeDict: Final[dict] = {
MessageType.NULL_TRICKER_TYPE: THUAI6.TrickerType.NullTrickerType, MessageType.NULL_TRICKER_TYPE: THUAI6.TrickerType.NullTrickerType,
MessageType.ASSASSIN: THUAI6.TrickerType.Assassin, MessageType.ASSASSIN: THUAI6.TrickerType.Assassin,
MessageType.KLEE: THUAI6.TrickerType.Klee, MessageType.KLEE: THUAI6.TrickerType.Klee,
MessageType.A_NOISY_PERSON: THUAI6.TrickerType.ANoisyPerson, MessageType.A_NOISY_PERSON: THUAI6.TrickerType.ANoisyPerson,
MessageType.IDOL: THUAI6.TrickerType.Idol, }
MessageType.IDOL: THUAI6.TrickerType.Idol,
}


studentBuffTypeDict: Final[dict] = { studentBuffTypeDict: Final[dict] = {
MessageType.NULL_SBUFF_TYPE: THUAI6.StudentBuffType.NullStudentBuffType, MessageType.NULL_SBUFF_TYPE: THUAI6.StudentBuffType.NullStudentBuffType,
MessageType.STUDENT_ADD_SPEED: THUAI6.StudentBuffType.AddSpeed, MessageType.STUDENT_ADD_SPEED: THUAI6.StudentBuffType.AddSpeed,
MessageType.ADD_LIFE: THUAI6.StudentBuffType.AddLife, MessageType.ADD_LIFE: THUAI6.StudentBuffType.AddLife,
MessageType.SHIELD: THUAI6.StudentBuffType.Shield, MessageType.SHIELD: THUAI6.StudentBuffType.Shield,
MessageType.STUDENT_INVISIBLE: THUAI6.StudentBuffType.Invisible, }
MessageType.STUDENT_INVISIBLE: THUAI6.StudentBuffType.Invisible,
}


trickerBuffTypeDict: Final[dict] = { trickerBuffTypeDict: Final[dict] = {
MessageType.NULL_TBUFF_TYPE: THUAI6.TrickerBuffType.NullTrickerBuffType, MessageType.NULL_TBUFF_TYPE: THUAI6.TrickerBuffType.NullTrickerBuffType,
@@ -128,7 +149,8 @@ class Proto2THUAI6(NoInstance):
MessageType.SPEAR: THUAI6.TrickerBuffType.Spear, MessageType.SPEAR: THUAI6.TrickerBuffType.Spear,
MessageType.ADD_AP: THUAI6.TrickerBuffType.AddAp, MessageType.ADD_AP: THUAI6.TrickerBuffType.AddAp,
MessageType.CLAIRAUDIENCE: THUAI6.TrickerBuffType.Clairaudience, MessageType.CLAIRAUDIENCE: THUAI6.TrickerBuffType.Clairaudience,
MessageType.TRICKER_INVISIBLE: THUAI6.TrickerBuffType.Invisible, }
MessageType.TRICKER_INVISIBLE: THUAI6.TrickerBuffType.Invisible,
}


playerStateDict: Final[dict] = { playerStateDict: Final[dict] = {
MessageType.NULL_STATUS: THUAI6.PlayerState.NullState, MessageType.NULL_STATUS: THUAI6.PlayerState.NullState,
@@ -149,13 +171,15 @@ class Proto2THUAI6(NoInstance):
MessageType.CLIMBING: THUAI6.PlayerState.Climbing, MessageType.CLIMBING: THUAI6.PlayerState.Climbing,
MessageType.OPENING_A_CHEST: THUAI6.PlayerState.OpeningAChest, MessageType.OPENING_A_CHEST: THUAI6.PlayerState.OpeningAChest,
MessageType.USING_SPECIAL_SKILL: THUAI6.PlayerState.UsingSpecialSkill, MessageType.USING_SPECIAL_SKILL: THUAI6.PlayerState.UsingSpecialSkill,
MessageType.OPENING_A_GATE: THUAI6.PlayerState.OpeningAGate, }
MessageType.OPENING_A_GATE: THUAI6.PlayerState.OpeningAGate,
}


gameStateDict: Final[dict] = { gameStateDict: Final[dict] = {
MessageType.NULL_GAME_STATE: THUAI6.GameState.NullGameState, MessageType.NULL_GAME_STATE: THUAI6.GameState.NullGameState,
MessageType.GAME_START: THUAI6.GameState.GameStart, MessageType.GAME_START: THUAI6.GameState.GameStart,
MessageType.GAME_RUNNING: THUAI6.GameState.GameRunning, MessageType.GAME_RUNNING: THUAI6.GameState.GameRunning,
MessageType.GAME_END: THUAI6.GameState.GameEnd}
MessageType.GAME_END: THUAI6.GameState.GameEnd,
}


bulletTypeDict: Final[dict] = { bulletTypeDict: Final[dict] = {
MessageType.NULL_BULLET_TYPE: THUAI6.BulletType.NullBulletType, MessageType.NULL_BULLET_TYPE: THUAI6.BulletType.NullBulletType,
@@ -163,11 +187,14 @@ class Proto2THUAI6(NoInstance):
MessageType.BOMB_BOMB: THUAI6.BulletType.BombBomb, MessageType.BOMB_BOMB: THUAI6.BulletType.BombBomb,
MessageType.COMMON_ATTACK_OF_TRICKER: THUAI6.BulletType.CommonAttackOfTricker, MessageType.COMMON_ATTACK_OF_TRICKER: THUAI6.BulletType.CommonAttackOfTricker,
MessageType.JUMPY_DUMPTY: THUAI6.BulletType.JumpyDumpty, MessageType.JUMPY_DUMPTY: THUAI6.BulletType.JumpyDumpty,
MessageType.ATOM_BOMB: THUAI6.BulletType.AtomBomb, }
MessageType.ATOM_BOMB: THUAI6.BulletType.AtomBomb,
}


# 用于将Proto的对象转为THUAI6的对象 # 用于将Proto的对象转为THUAI6的对象
@ staticmethod
def Protobuf2THUAI6Tricker(trickerMsg: Message2Clients.MessageOfTricker) -> THUAI6.Tricker:
@staticmethod
def Protobuf2THUAI6Tricker(
trickerMsg: Message2Clients.MessageOfTricker,
) -> THUAI6.Tricker:
tricker = THUAI6.Tricker() tricker = THUAI6.Tricker()
tricker.x = trickerMsg.x tricker.x = trickerMsg.x
tricker.y = trickerMsg.y tricker.y = trickerMsg.y
@@ -192,8 +219,10 @@ class Proto2THUAI6(NoInstance):
tricker.playerType = THUAI6.PlayerType.TrickerPlayer tricker.playerType = THUAI6.PlayerType.TrickerPlayer
return tricker return tricker


@ staticmethod
def Protobuf2THUAI6Student(studentMsg: Message2Clients.MessageOfStudent) -> THUAI6.Student:
@staticmethod
def Protobuf2THUAI6Student(
studentMsg: Message2Clients.MessageOfStudent,
) -> THUAI6.Student:
student = THUAI6.Student() student = THUAI6.Student()
student.x = studentMsg.x student.x = studentMsg.x
student.y = studentMsg.y student.y = studentMsg.y
@@ -223,7 +252,7 @@ class Proto2THUAI6(NoInstance):
student.playerType = THUAI6.PlayerType.StudentPlayer student.playerType = THUAI6.PlayerType.StudentPlayer
return student return student


@ staticmethod
@staticmethod
def Protobuf2THUAI6Prop(propMsg: Message2Clients.MessageOfProp) -> THUAI6.Prop: def Protobuf2THUAI6Prop(propMsg: Message2Clients.MessageOfProp) -> THUAI6.Prop:
prop = THUAI6.Prop() prop = THUAI6.Prop()
prop.x = propMsg.x prop.x = propMsg.x
@@ -233,7 +262,7 @@ class Proto2THUAI6(NoInstance):
prop.facingDirection = propMsg.facing_direction prop.facingDirection = propMsg.facing_direction
return prop return prop


@ staticmethod
@staticmethod
def Protobuf2THUAI6GameInfo(allMsg: Message2Clients.MessageOfAll): def Protobuf2THUAI6GameInfo(allMsg: Message2Clients.MessageOfAll):
gameInfo = THUAI6.GameInfo() gameInfo = THUAI6.GameInfo()
gameInfo.gameTime = allMsg.game_time gameInfo.gameTime = allMsg.game_time
@@ -244,8 +273,10 @@ class Proto2THUAI6(NoInstance):
gameInfo.trickerScore = allMsg.tricker_score gameInfo.trickerScore = allMsg.tricker_score
return gameInfo return gameInfo


@ staticmethod
def Protobuf2THUAI6Bullet(bulletMsg: Message2Clients.MessageOfBullet) -> THUAI6.Bullet:
@staticmethod
def Protobuf2THUAI6Bullet(
bulletMsg: Message2Clients.MessageOfBullet,
) -> THUAI6.Bullet:
bullet = THUAI6.Bullet() bullet = THUAI6.Bullet()
bullet.x = bulletMsg.x bullet.x = bulletMsg.x
bullet.y = bulletMsg.y bullet.y = bulletMsg.y
@@ -256,8 +287,10 @@ class Proto2THUAI6(NoInstance):
bullet.bombRange = bulletMsg.bomb_range bullet.bombRange = bulletMsg.bomb_range
return bullet return bullet


@ staticmethod
def Protobuf2THUAI6BombedBullet(bulletMsg: Message2Clients.MessageOfBombedBullet) -> THUAI6.BombedBullet:
@staticmethod
def Protobuf2THUAI6BombedBullet(
bulletMsg: Message2Clients.MessageOfBombedBullet,
) -> THUAI6.BombedBullet:
bullet = THUAI6.BombedBullet() bullet = THUAI6.BombedBullet()
bullet.x = bulletMsg.x bullet.x = bulletMsg.x
bullet.y = bulletMsg.y bullet.y = bulletMsg.y
@@ -267,7 +300,7 @@ class Proto2THUAI6(NoInstance):
bullet.bombRange = bulletMsg.bomb_range bullet.bombRange = bulletMsg.bomb_range
return bullet return bullet


@ staticmethod
@staticmethod
def Bool2HiddenGateState(gateMsg: bool) -> THUAI6.HiddenGateState: def Bool2HiddenGateState(gateMsg: bool) -> THUAI6.HiddenGateState:
if gateMsg: if gateMsg:
return THUAI6.HiddenGateState.Opened return THUAI6.HiddenGateState.Opened
@@ -288,12 +321,14 @@ class THUAI62Proto(NoInstance):
THUAI6.PlaceType.Door5: MessageType.DOOR5, THUAI6.PlaceType.Door5: MessageType.DOOR5,
THUAI6.PlaceType.Door6: MessageType.DOOR6, THUAI6.PlaceType.Door6: MessageType.DOOR6,
THUAI6.PlaceType.Chest: MessageType.CHEST, THUAI6.PlaceType.Chest: MessageType.CHEST,
THUAI6.PlaceType.Window: MessageType.WINDOW, }
THUAI6.PlaceType.Window: MessageType.WINDOW,
}


playerTypeDict: Final[dict] = { playerTypeDict: Final[dict] = {
THUAI6.PlayerType.NullPlayerType: MessageType.NULL_PLAYER_TYPE, THUAI6.PlayerType.NullPlayerType: MessageType.NULL_PLAYER_TYPE,
THUAI6.PlayerType.StudentPlayer: MessageType.STUDENT_PLAYER, THUAI6.PlayerType.StudentPlayer: MessageType.STUDENT_PLAYER,
THUAI6.PlayerType.TrickerPlayer: MessageType.TRICKER_PLAYER}
THUAI6.PlayerType.TrickerPlayer: MessageType.TRICKER_PLAYER,
}


studentTypeDict: Final[dict] = { studentTypeDict: Final[dict] = {
THUAI6.StudentType.NullStudentType: MessageType.NULL_STUDENT_TYPE, THUAI6.StudentType.NullStudentType: MessageType.NULL_STUDENT_TYPE,
@@ -302,14 +337,16 @@ class THUAI62Proto(NoInstance):
THUAI6.StudentType.StraightAStudent: MessageType.STRAIGHT_A_STUDENT, THUAI6.StudentType.StraightAStudent: MessageType.STRAIGHT_A_STUDENT,
THUAI6.StudentType.Robot: MessageType.ROBOT, THUAI6.StudentType.Robot: MessageType.ROBOT,
THUAI6.StudentType.TechOtaku: MessageType.TECH_OTAKU, THUAI6.StudentType.TechOtaku: MessageType.TECH_OTAKU,
THUAI6.StudentType.Sunshine: MessageType.SUNSHINE, }
THUAI6.StudentType.Sunshine: MessageType.SUNSHINE,
}


trickerTypeDict: Final[dict] = { trickerTypeDict: Final[dict] = {
THUAI6.TrickerType.NullTrickerType: MessageType.NULL_TRICKER_TYPE, THUAI6.TrickerType.NullTrickerType: MessageType.NULL_TRICKER_TYPE,
THUAI6.TrickerType.Assassin: MessageType.ASSASSIN, THUAI6.TrickerType.Assassin: MessageType.ASSASSIN,
THUAI6.TrickerType.Klee: MessageType.KLEE, THUAI6.TrickerType.Klee: MessageType.KLEE,
THUAI6.TrickerType.ANoisyPerson: MessageType.A_NOISY_PERSON, THUAI6.TrickerType.ANoisyPerson: MessageType.A_NOISY_PERSON,
THUAI6.TrickerType.Idol: MessageType.IDOL, }
THUAI6.TrickerType.Idol: MessageType.IDOL,
}


propTypeDict: Final[dict] = { propTypeDict: Final[dict] = {
THUAI6.PropType.NullPropType: MessageType.NULL_PROP_TYPE, THUAI6.PropType.NullPropType: MessageType.NULL_PROP_TYPE,
@@ -319,44 +356,70 @@ class THUAI62Proto(NoInstance):
THUAI6.PropType.AddHpOrAp: MessageType.ADD_HP_OR_AP, THUAI6.PropType.AddHpOrAp: MessageType.ADD_HP_OR_AP,
THUAI6.PropType.AddLifeOrClairaudience: MessageType.ADD_LIFE_OR_CLAIRAUDIENCE, THUAI6.PropType.AddLifeOrClairaudience: MessageType.ADD_LIFE_OR_CLAIRAUDIENCE,
THUAI6.PropType.AddSpeed: MessageType.ADD_SPEED, THUAI6.PropType.AddSpeed: MessageType.ADD_SPEED,
THUAI6.PropType.ShieldOrSpear: MessageType.SHIELD_OR_SPEAR, }
THUAI6.PropType.ShieldOrSpear: MessageType.SHIELD_OR_SPEAR,
}


# 用于将THUAI6的对象转为Proto的对象 # 用于将THUAI6的对象转为Proto的对象


@ staticmethod
def THUAI62ProtobufPlayer(playerID: int, playerType: THUAI6.PlayerType, studentType: THUAI6.StudentType, trickerType: THUAI6.TrickerType) -> Message2Server.PlayerMsg:
@staticmethod
def THUAI62ProtobufPlayer(
playerID: int,
playerType: THUAI6.PlayerType,
studentType: THUAI6.StudentType,
trickerType: THUAI6.TrickerType,
) -> Message2Server.PlayerMsg:
if playerType == THUAI6.PlayerType.StudentPlayer: if playerType == THUAI6.PlayerType.StudentPlayer:
return Message2Server.PlayerMsg(player_id=playerID, player_type=MessageType.STUDENT_PLAYER, student_type=THUAI62Proto.studentTypeDict[studentType])
return Message2Server.PlayerMsg(
player_id=playerID,
player_type=MessageType.STUDENT_PLAYER,
student_type=THUAI62Proto.studentTypeDict[studentType],
)
else: else:
return Message2Server.PlayerMsg(player_id=playerID, player_type=MessageType.TRICKER_PLAYER, tricker_type=THUAI62Proto.trickerTypeDict[trickerType])
return Message2Server.PlayerMsg(
player_id=playerID,
player_type=MessageType.TRICKER_PLAYER,
tricker_type=THUAI62Proto.trickerTypeDict[trickerType],
)


@ staticmethod
@staticmethod
def THUAI62ProtobufID(playerID: int) -> Message2Server.IDMsg: def THUAI62ProtobufID(playerID: int) -> Message2Server.IDMsg:
return Message2Server.IDMsg(player_id=playerID) return Message2Server.IDMsg(player_id=playerID)


@ staticmethod
@staticmethod
def THUAI62ProtobufMove(time: int, angle: float, id: int) -> Message2Server.MoveMsg: def THUAI62ProtobufMove(time: int, angle: float, id: int) -> Message2Server.MoveMsg:
return Message2Server.MoveMsg(player_id=id, angle=angle, time_in_milliseconds=time)
return Message2Server.MoveMsg(
player_id=id, angle=angle, time_in_milliseconds=time
)


@ staticmethod
def THUAI62ProtobufTreatAndRescue(playerID: int, mateID: int) -> Message2Server.TreatAndRescueMsg:
@staticmethod
def THUAI62ProtobufTreatAndRescue(
playerID: int, mateID: int
) -> Message2Server.TreatAndRescueMsg:
return Message2Server.TreatAndRescueMsg(player_id=playerID, to_player_id=mateID) return Message2Server.TreatAndRescueMsg(player_id=playerID, to_player_id=mateID)


@ staticmethod
@staticmethod
def THUAI62ProtobufProp(prop: THUAI6.PropType, id: int) -> Message2Server.PropMsg: def THUAI62ProtobufProp(prop: THUAI6.PropType, id: int) -> Message2Server.PropMsg:
return Message2Server.PropMsg(player_id=id, prop_type=THUAI62Proto.propTypeDict[prop])
return Message2Server.PropMsg(
player_id=id, prop_type=THUAI62Proto.propTypeDict[prop]
)


@ staticmethod
def THUAI62ProtobufSend(msg: Union[str, bytes], toID: int, id: int) -> Message2Server.SendMsg:
@staticmethod
def THUAI62ProtobufSend(
msg: Union[str, bytes], toID: int, id: int
) -> Message2Server.SendMsg:
if isinstance(msg, str): if isinstance(msg, str):
return Message2Server.SendMsg(player_id=id, to_player_id=toID, text_message=msg)
return Message2Server.SendMsg(
player_id=id, to_player_id=toID, text_message=msg
)
elif isinstance(msg, bytes): elif isinstance(msg, bytes):
return Message2Server.SendMsg(player_id=id, to_player_id=toID, binary_message=msg)
return Message2Server.SendMsg(
player_id=id, to_player_id=toID, binary_message=msg
)


@ staticmethod
@staticmethod
def THUAI62ProtobufAttack(angle: float, id: int) -> Message2Server.AttackMsg: def THUAI62ProtobufAttack(angle: float, id: int) -> Message2Server.AttackMsg:
return Message2Server.AttackMsg(player_id=id, angle=angle) return Message2Server.AttackMsg(player_id=id, angle=angle)


@ staticmethod
@staticmethod
def THUAI62ProtobufSkill(skillID: int, id: int) -> Message2Server.SkillMsg: def THUAI62ProtobufSkill(skillID: int, id: int) -> Message2Server.SkillMsg:
return Message2Server.SkillMsg(player_id=id, skill_id=skillID) return Message2Server.SkillMsg(player_id=id, skill_id=skillID)

Loading…
Cancel
Save