| @@ -4,7 +4,7 @@ | |||
| ## Visual Studio使用说明 | |||
| 比赛**只保证!!!支持**VS2022,选手使用其他版本后果自负(实际上应该不能编译)。 | |||
| 比赛**只保证!!!支持**VS2022最新版本,选手使用其他版本后果自负(实际上应该不能编译)。 | |||
| ### 生成模式的设置 | |||
| @@ -246,7 +246,7 @@ for (auto itr = begin(arr); itr != end(arr); ++itr) | |||
| ## Python接口必看 | |||
| 比赛**只保证!!**支持Python3.9,不保证支持其他版本 | |||
| 比赛中的Python接口大多使用异步接口,即返回一个类似于 `Future[bool]` 的值。为了获取实际的值,需要调用 `result()` 方法。 | |||
| @@ -10,4 +10,4 @@ python -m grpc_tools.protoc -I.\CAPI\proto\ --python_out=.\CAPI\python\proto --p | |||
| python -m grpc_tools.protoc -I.\CAPI\proto\ --python_out=.\CAPI\python\proto --pyi_out=.\CAPI\python\proto Message2Server.proto | |||
| python -m grpc_tools.protoc -I.\CAPI\proto\ --python_out=.\CAPI\python\proto --pyi_out=.\CAPI\python\proto --grpc_python_out=.\CAPI\python\proto Services.proto | |||
| pause | |||
| pause | |||
| @@ -3,4 +3,5 @@ | |||
| start .\CAPI\cpp\x64\Debug\API.exe -I 127.0.0.1 -P 8888 -p 0 -o -d | |||
| start .\CAPI\cpp\x64\Debug\API.exe -I 127.0.0.1 -P 8888 -p 1 -o -d | |||
| start .\CAPI\cpp\x64\Debug\API.exe -I 127.0.0.1 -P 8888 -p 2 -o -d | |||
| start .\CAPI\cpp\x64\Debug\API.exe -I 127.0.0.1 -P 8888 -p 3 -o -d | |||
| start .\CAPI\cpp\x64\Debug\API.exe -I 127.0.0.1 -P 8888 -p 3 -o -d | |||
| start .\CAPI\cpp\x64\Debug\API.exe -I 127.0.0.1 -P 8888 -p 4 -o -d | |||
| @@ -4,5 +4,3 @@ | |||
| start cmd /k win64\Client.exe --port 8888 --characterID 114514 --type 0 --occupation 1 --ip 127.0.0.1 --cl | |||
| :: characterID > 2023时是观战Client,否则是正常Client | |||
| @@ -3,4 +3,5 @@ | |||
| start python .\CAPI\python\PyAPI\main.py -I 127.0.0.1 -P 8888 -p 0 -d -o | |||
| start python .\CAPI\python\PyAPI\main.py -I 127.0.0.1 -P 8888 -p 1 -d -o | |||
| start python .\CAPI\python\PyAPI\main.py -I 127.0.0.1 -P 8888 -p 2 -d -o | |||
| start python .\CAPI\python\PyAPI\main.py -I 127.0.0.1 -P 8888 -p 3 -d -o | |||
| start python .\CAPI\python\PyAPI\main.py -I 127.0.0.1 -P 8888 -p 3 -d -o | |||
| start python .\CAPI\python\PyAPI\main.py -I 127.0.0.1 -P 8888 -p 4 -d -o | |||
| @@ -2,4 +2,4 @@ | |||
| .\win64\Server.exe --port 8888 --studentCount 1 --trickerCount 1 --gameTimeInSecond 600 --fileName video | |||
| pause | |||
| pause | |||
| @@ -2,4 +2,4 @@ | |||
| .\win64\Debug\Server.exe --port 8888 --studentCount 4 --trickerCount 1 --gameTimeInSecond 600 | |||
| pause | |||
| pause | |||
| @@ -13,17 +13,21 @@ public: | |||
| virtual void play(ITrickerAPI& api) = 0; | |||
| }; | |||
| using CreateAIFunc = std::unique_ptr<IAI> (*)(); | |||
| using CreateAIFunc = std::unique_ptr<IAI> (*)(int64_t playerID); | |||
| class AI : public IAI | |||
| { | |||
| public: | |||
| AI() : | |||
| IAI() | |||
| AI(int64_t pID) : | |||
| IAI(), | |||
| playerID(pID) | |||
| { | |||
| } | |||
| void play(IStudentAPI& api) override; | |||
| void play(ITrickerAPI& api) override; | |||
| private: | |||
| int64_t playerID; | |||
| }; | |||
| #endif | |||
| @@ -1,24 +1,45 @@ | |||
| #include <vector> | |||
| #include <thread> | |||
| #include <array> | |||
| #include "AI.h" | |||
| #include "constants.h" | |||
| // 为假则play()期间确保游戏状态不更新,为真则只保证游戏状态在调用相关方法时不更新 | |||
| extern const bool asynchronous = false; | |||
| // 选手必须定义该变量来选择自己的阵营 | |||
| extern const THUAI6::PlayerType playerType = THUAI6::PlayerType::TrickerPlayer; | |||
| // 选手需要依次将player0到player4的职业在这里定义 | |||
| // 选手需要将两个都定义,本份代码中不选择的阵营任意定义即可 | |||
| extern const THUAI6::TrickerType trickerType = THUAI6::TrickerType::Assassin; | |||
| extern const std::array<THUAI6::StudentType, 4> studentType = { | |||
| THUAI6::StudentType::Athlete, | |||
| THUAI6::StudentType::Teacher, | |||
| THUAI6::StudentType::StraightAStudent, | |||
| THUAI6::StudentType::Sunshine}; | |||
| extern const THUAI6::StudentType studentType = THUAI6::StudentType::Athlete; | |||
| extern const THUAI6::TrickerType trickerType = THUAI6::TrickerType::Assassin; | |||
| // 选手只需写一个即可,为了调试方便写了两个的话也不会有影响 | |||
| //可以在AI.cpp内部声明变量与函数 | |||
| void AI::play(IStudentAPI& api) | |||
| { | |||
| auto self = api.GetSelfInfo(); | |||
| // 公共操作 | |||
| if (this->playerID == 0) | |||
| { | |||
| // 玩家0执行操作 | |||
| } | |||
| else if (this->playerID == 1) | |||
| { | |||
| // 玩家1执行操作 | |||
| } | |||
| else if (this->playerID == 2) | |||
| { | |||
| // 玩家2执行操作 | |||
| } | |||
| else if (this->playerID == 3) | |||
| { | |||
| // 玩家3执行操作 | |||
| } | |||
| //当然可以写成if (this->playerID == 2||this->playerID == 3)之类的操作 | |||
| // 公共操作 | |||
| } | |||
| void AI::play(ITrickerAPI& api) | |||
| @@ -863,7 +863,7 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool f | |||
| cvAI.wait(lock, [this]() | |||
| { return AIStart; }); | |||
| } | |||
| auto ai = createAI(); | |||
| auto ai = createAI(playerID); | |||
| while (AILoop) | |||
| { | |||
| @@ -2,6 +2,7 @@ | |||
| #include "logic.h" | |||
| #include "structures.h" | |||
| #include <tclap/CmdLine.h> | |||
| #include <array> | |||
| #ifdef _MSC_VER | |||
| #pragma warning(disable : 4996) | |||
| @@ -15,9 +16,8 @@ int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder) | |||
| bool file = false; | |||
| bool print = false; | |||
| bool warnOnly = false; | |||
| extern const THUAI6::PlayerType playerType; | |||
| extern const THUAI6::TrickerType trickerType; | |||
| extern const THUAI6::StudentType studentType; | |||
| extern const std::array<THUAI6::StudentType, 4> studentType; | |||
| // { | |||
| // file = true; | |||
| // print = true; | |||
| @@ -71,7 +71,12 @@ int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder) | |||
| } | |||
| try | |||
| { | |||
| Logic logic(playerType, pID, trickerType, studentType); | |||
| THUAI6::PlayerType playerType; | |||
| if (pID == 4) | |||
| playerType = THUAI6::PlayerType::TrickerPlayer; | |||
| else | |||
| playerType = THUAI6::PlayerType::StudentPlayer; | |||
| Logic logic(playerType, pID, trickerType, studentType[pID]); | |||
| logic.Main(AIBuilder, sIP, sPort, file, print, warnOnly); | |||
| } | |||
| catch (const std::exception& e) | |||
| @@ -81,9 +86,9 @@ int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder) | |||
| return 0; | |||
| } | |||
| std::unique_ptr<IAI> CreateAI() | |||
| std::unique_ptr<IAI> CreateAI(int64_t pID) | |||
| { | |||
| return std::make_unique<AI>(); | |||
| return std::make_unique<AI>(pID); | |||
| } | |||
| int main(int argc, char* argv[]) | |||
| @@ -16,14 +16,18 @@ | |||
| #include <google/protobuf/port_def.inc> | |||
| PROTOBUF_PRAGMA_INIT_SEG | |||
| namespace _pb = ::PROTOBUF_NAMESPACE_ID; | |||
| namespace _pbi = _pb::internal; | |||
| namespace protobuf | |||
| { | |||
| } // namespace protobuf | |||
| static const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* file_level_enum_descriptors_MessageType_2eproto[11]; | |||
| static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_MessageType_2eproto = nullptr; | |||
| static const ::_pb::EnumDescriptor* file_level_enum_descriptors_MessageType_2eproto[11]; | |||
| static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_MessageType_2eproto = nullptr; | |||
| const uint32_t TableStruct_MessageType_2eproto::offsets[1] = {}; | |||
| static constexpr ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema* schemas = nullptr; | |||
| static constexpr ::PROTOBUF_NAMESPACE_ID::Message* const* file_default_instances = nullptr; | |||
| static constexpr ::_pbi::MigrationSchema* schemas = nullptr; | |||
| static constexpr ::_pb::Message* const* file_default_instances = nullptr; | |||
| const char descriptor_table_protodef_MessageType_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = | |||
| "\n\021MessageType.proto\022\010protobuf*\202\001\n\nBullet" | |||
| @@ -82,13 +86,13 @@ const ::_pbi::DescriptorTable descriptor_table_MessageType_2eproto = { | |||
| file_level_enum_descriptors_MessageType_2eproto, | |||
| file_level_service_descriptors_MessageType_2eproto, | |||
| }; | |||
| PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_MessageType_2eproto_getter() | |||
| PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_MessageType_2eproto_getter() | |||
| { | |||
| return &descriptor_table_MessageType_2eproto; | |||
| } | |||
| // Force running AddDescriptors() at dynamic initialization time. | |||
| PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_MessageType_2eproto(&descriptor_table_MessageType_2eproto); | |||
| PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_MessageType_2eproto(&descriptor_table_MessageType_2eproto); | |||
| namespace protobuf | |||
| { | |||
| const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* BulletType_descriptor() | |||
| @@ -8,12 +8,12 @@ | |||
| #include <string> | |||
| #include <google/protobuf/port_def.inc> | |||
| #if PROTOBUF_VERSION < 3019000 | |||
| #if PROTOBUF_VERSION < 3021000 | |||
| #error This file was generated by a newer version of protoc which is | |||
| #error incompatible with your Protocol Buffer headers. Please update | |||
| #error your headers. | |||
| #endif | |||
| #if 3019004 < PROTOBUF_MIN_PROTOC_VERSION | |||
| #if 3021005 < PROTOBUF_MIN_PROTOC_VERSION | |||
| #error This file was generated by an older version of protoc which is | |||
| #error incompatible with your Protocol Buffer headers. Please | |||
| #error regenerate this file with a newer version of protoc. | |||
| @@ -23,7 +23,6 @@ | |||
| #include <google/protobuf/io/coded_stream.h> | |||
| #include <google/protobuf/arena.h> | |||
| #include <google/protobuf/arenastring.h> | |||
| #include <google/protobuf/generated_message_table_driven.h> | |||
| #include <google/protobuf/generated_message_util.h> | |||
| #include <google/protobuf/metadata_lite.h> | |||
| #include <google/protobuf/generated_message_reflection.h> | |||
| @@ -43,11 +42,6 @@ PROTOBUF_NAMESPACE_CLOSE | |||
| // Internal implementation detail -- do not use these members. | |||
| struct TableStruct_MessageType_2eproto | |||
| { | |||
| static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); | |||
| static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); | |||
| static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1] PROTOBUF_SECTION_VARIABLE(protodesc_cold); | |||
| static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; | |||
| static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; | |||
| static const uint32_t offsets[]; | |||
| }; | |||
| extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_MessageType_2eproto; | |||
| @@ -16,14 +16,18 @@ | |||
| #include <google/protobuf/port_def.inc> | |||
| PROTOBUF_PRAGMA_INIT_SEG | |||
| namespace _pb = ::PROTOBUF_NAMESPACE_ID; | |||
| namespace _pbi = _pb::internal; | |||
| namespace protobuf | |||
| { | |||
| } // namespace protobuf | |||
| static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_Services_2eproto = nullptr; | |||
| static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_Services_2eproto = nullptr; | |||
| static constexpr ::_pb::EnumDescriptor const** file_level_enum_descriptors_Services_2eproto = nullptr; | |||
| static constexpr ::_pb::ServiceDescriptor const** file_level_service_descriptors_Services_2eproto = nullptr; | |||
| const uint32_t TableStruct_Services_2eproto::offsets[1] = {}; | |||
| static constexpr ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema* schemas = nullptr; | |||
| static constexpr ::PROTOBUF_NAMESPACE_ID::Message* const* file_default_instances = nullptr; | |||
| static constexpr ::_pbi::MigrationSchema* schemas = nullptr; | |||
| static constexpr ::_pb::Message* const* file_default_instances = nullptr; | |||
| const char descriptor_table_protodef_Services_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = | |||
| "\n\016Services.proto\022\010protobuf\032\025Message2Clie" | |||
| @@ -54,12 +58,12 @@ const char descriptor_table_protodef_Services_2eproto[] PROTOBUF_SECTION_VARIABL | |||
| "tOpenChest\022\017.protobuf.IDMsg\032\021.protobuf.B" | |||
| "oolRes\0222\n\014EndAllAction\022\017.protobuf.IDMsg\032" | |||
| "\021.protobuf.BoolResb\006proto3"; | |||
| static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* const descriptor_table_Services_2eproto_deps[2] = { | |||
| static const ::_pbi::DescriptorTable* const descriptor_table_Services_2eproto_deps[2] = { | |||
| &::descriptor_table_Message2Clients_2eproto, | |||
| &::descriptor_table_Message2Server_2eproto, | |||
| }; | |||
| static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_Services_2eproto_once; | |||
| const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Services_2eproto = { | |||
| static ::_pbi::once_flag descriptor_table_Services_2eproto_once; | |||
| const ::_pbi::DescriptorTable descriptor_table_Services_2eproto = { | |||
| false, | |||
| false, | |||
| 1106, | |||
| @@ -76,13 +80,13 @@ const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Servic | |||
| file_level_enum_descriptors_Services_2eproto, | |||
| file_level_service_descriptors_Services_2eproto, | |||
| }; | |||
| PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_Services_2eproto_getter() | |||
| PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_Services_2eproto_getter() | |||
| { | |||
| return &descriptor_table_Services_2eproto; | |||
| } | |||
| // Force running AddDescriptors() at dynamic initialization time. | |||
| PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_Services_2eproto(&descriptor_table_Services_2eproto); | |||
| PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_Services_2eproto(&descriptor_table_Services_2eproto); | |||
| namespace protobuf | |||
| { | |||
| @@ -8,12 +8,12 @@ | |||
| #include <string> | |||
| #include <google/protobuf/port_def.inc> | |||
| #if PROTOBUF_VERSION < 3019000 | |||
| #if PROTOBUF_VERSION < 3021000 | |||
| #error This file was generated by a newer version of protoc which is | |||
| #error incompatible with your Protocol Buffer headers. Please update | |||
| #error your headers. | |||
| #endif | |||
| #if 3019004 < PROTOBUF_MIN_PROTOC_VERSION | |||
| #if 3021005 < PROTOBUF_MIN_PROTOC_VERSION | |||
| #error This file was generated by an older version of protoc which is | |||
| #error incompatible with your Protocol Buffer headers. Please | |||
| #error regenerate this file with a newer version of protoc. | |||
| @@ -23,7 +23,6 @@ | |||
| #include <google/protobuf/io/coded_stream.h> | |||
| #include <google/protobuf/arena.h> | |||
| #include <google/protobuf/arenastring.h> | |||
| #include <google/protobuf/generated_message_table_driven.h> | |||
| #include <google/protobuf/generated_message_util.h> | |||
| #include <google/protobuf/metadata_lite.h> | |||
| #include <google/protobuf/generated_message_reflection.h> | |||
| @@ -44,11 +43,6 @@ PROTOBUF_NAMESPACE_CLOSE | |||
| // Internal implementation detail -- do not use these members. | |||
| struct TableStruct_Services_2eproto | |||
| { | |||
| static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); | |||
| static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); | |||
| static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1] PROTOBUF_SECTION_VARIABLE(protodesc_cold); | |||
| static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; | |||
| static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; | |||
| static const uint32_t offsets[]; | |||
| }; | |||
| extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Services_2eproto; | |||
| @@ -1,6 +1,6 @@ | |||
| import PyAPI.structures as THUAI6 | |||
| from PyAPI.Interface import IStudentAPI, ITrickerAPI, IAI | |||
| from typing import Union, Final, cast | |||
| from typing import Union, Final, cast, List | |||
| from PyAPI.constants import Constants | |||
| import queue | |||
| @@ -13,15 +13,10 @@ class Setting: | |||
| def asynchronous() -> bool: | |||
| return True | |||
| # 选手必须修改该函数的返回值来选择自己的阵营 | |||
| # 选手需要依次将player0到player4的职业都定义 | |||
| @staticmethod | |||
| def playerType() -> THUAI6.PlayerType: | |||
| return THUAI6.PlayerType.StudentPlayer | |||
| # 选手需要将两个都定义,本份代码中不选择的阵营任意定义即可 | |||
| @staticmethod | |||
| def studentType() -> THUAI6.StudentType: | |||
| return THUAI6.StudentType.Athlete | |||
| def studentType() -> List[THUAI6.StudentType]: | |||
| return [THUAI6.StudentType.Athlete, THUAI6.StudentType.Teacher, THUAI6.StudentType.StraightAStudent, THUAI6.StudentType.Sunshine] | |||
| @staticmethod | |||
| def trickerType() -> THUAI6.TrickerType: | |||
| @@ -44,10 +39,25 @@ class AssistFunction: | |||
| class AI(IAI): | |||
| # 选手在这里实现自己的逻辑,要求和上面选择的阵营保持一致 | |||
| def __init__(self, pID: int): | |||
| self.__playerID = pID | |||
| def StudentPlay(self, api: IStudentAPI) -> None: | |||
| selfInfo = api.GetSelfInfo() | |||
| api.PrintSelfInfo() | |||
| #公共操作 | |||
| if self.__playerID == 0: | |||
| # 玩家0执行操作 | |||
| return | |||
| elif self.__playerID == 1: | |||
| # 玩家1执行操作 | |||
| return | |||
| elif self.__playerID == 2: | |||
| # 玩家2执行操作 | |||
| return | |||
| elif self.__playerID == 3: | |||
| # 玩家3执行操作 | |||
| return | |||
| #可以写成if self.__playerID<2之类的写法 | |||
| #公共操作 | |||
| return | |||
| def TrickerPlay(self, api: ITrickerAPI) -> None: | |||
| @@ -198,11 +198,15 @@ class Communication: | |||
| self.__haveNewMessage = False | |||
| return self.__message2Client | |||
| def AddPlayer(self, playerID: int) -> None: | |||
| def AddPlayer(self, playerID: int, playerType: THUAI6.PlayerType) -> None: | |||
| def tMessage(): | |||
| try: | |||
| if playerType == THUAI6.PlayerType.StudentPlayer: | |||
| studentType = Setting.studentType()[playerID] | |||
| else: | |||
| studentType = THUAI6.StudentType.NullStudentType | |||
| playerMsg = THUAI62Proto.THUAI62ProtobufPlayer( | |||
| playerID, Setting.playerType(), Setting.studentType(), Setting.trickerType()) | |||
| playerID, playerType, studentType, Setting.trickerType()) | |||
| for msg in self.__THUAI6Stub.AddPlayer(playerMsg): | |||
| with self.__cvMessage: | |||
| self.__haveNewMessage = True | |||
| @@ -18,12 +18,14 @@ from PyAPI.Interface import ILogic, IGameTimer | |||
| class Logic(ILogic): | |||
| def __init__(self, playerID: int) -> None: | |||
| def __init__(self, playerID: int, playerType: THUAI6.PlayerType) -> None: | |||
| # ID | |||
| self.__playerID: int = playerID | |||
| self.__playerGUIDs: List[int] = [] | |||
| self.__playerType: THUAI6.PlayerType = playerType | |||
| # 通信 | |||
| self.__comm: Communication | |||
| @@ -268,7 +270,7 @@ class Logic(ILogic): | |||
| def __ProcessMessage(self) -> None: | |||
| def messageThread(): | |||
| self.__logger.info("Message thread start!") | |||
| self.__comm.AddPlayer(self.__playerID) | |||
| self.__comm.AddPlayer(self.__playerID, self.__playerType) | |||
| self.__logger.info("Join the player!") | |||
| while self.__gameState != THUAI6.GameState.GameEnd: | |||
| @@ -344,7 +346,7 @@ class Logic(ILogic): | |||
| self.__logger.debug("Buffer cleared!") | |||
| self.__bufferState.gameInfo = Proto2THUAI6.Protobuf2THUAI6GameInfo( | |||
| message.all_message) | |||
| if Setting.playerType() == THUAI6.PlayerType.StudentPlayer: | |||
| if self.__playerType == THUAI6.PlayerType.StudentPlayer: | |||
| for item in message.obj_message: | |||
| if item.WhichOneof("message_of_obj") == "student_message": | |||
| if item.student_message.player_id == self.__playerID: | |||
| @@ -590,20 +592,20 @@ class Logic(ILogic): | |||
| self.__logger.info("asynchronous: %s", Setting.asynchronous()) | |||
| self.__logger.info("server: %s:%s", IP, port) | |||
| self.__logger.info("playerID: %s", self.__playerID) | |||
| self.__logger.info("player type: %s", Setting.playerType().name) | |||
| self.__logger.info("player type: %s", self.__playerType.name) | |||
| self.__logger.info("****************************") | |||
| # 建立通信组件 | |||
| self.__comm = Communication(IP, port) | |||
| # 构造timer | |||
| if Setting.playerType() == THUAI6.PlayerType.StudentPlayer: | |||
| if self.__playerType == THUAI6.PlayerType.StudentPlayer: | |||
| if not file and not screen: | |||
| self.__timer = StudentAPI(self) | |||
| else: | |||
| self.__timer = StudentDebugAPI( | |||
| self, file, screen, warnOnly, self.__playerID) | |||
| elif Setting.playerType() == THUAI6.PlayerType.TrickerPlayer: | |||
| elif self.__playerType == THUAI6.PlayerType.TrickerPlayer: | |||
| if not file and not screen: | |||
| self.__timer = TrickerAPI(self) | |||
| else: | |||
| @@ -615,7 +617,7 @@ class Logic(ILogic): | |||
| with self.__cvAI: | |||
| self.__cvAI.wait_for(lambda: self.__AIStart) | |||
| ai = createAI() | |||
| ai = createAI(self.__playerID) | |||
| while self.__AILoop: | |||
| if Setting.asynchronous(): | |||
| self.__Wait() | |||
| @@ -9,6 +9,7 @@ from PyAPI.AI import AI | |||
| from PyAPI.logic import Logic | |||
| from typing import List, Callable | |||
| import argparse | |||
| import PyAPI.structures as THUAI6 | |||
| def THUAI6Main(argv: List[str], AIBuilder: Callable) -> None: | |||
| @@ -39,12 +40,17 @@ def THUAI6Main(argv: List[str], AIBuilder: Callable) -> None: | |||
| file = args.file | |||
| screen = args.screen | |||
| warnOnly = args.warnOnly | |||
| logic = Logic(pID) | |||
| playerType = THUAI6.PlayerType.NullPlayerType | |||
| if pID == 4: | |||
| playerType = THUAI6.PlayerType.TrickerPlayer | |||
| else: | |||
| playerType = THUAI6.PlayerType.StudentPlayer | |||
| logic = Logic(pID, playerType) | |||
| logic.Main(AIBuilder, sIP, sPort, file, screen, warnOnly) | |||
| def CreateAI() -> IAI: | |||
| return AI() | |||
| def CreateAI(pID: int) -> IAI: | |||
| return AI(pID) | |||
| if __name__ == '__main__': | |||
| @@ -1,6 +1,7 @@ | |||
| #!/usr/bin/env bash | |||
| python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 0 -d -o & | |||
| # python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 1 -d & | |||
| # python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 2 -d & | |||
| # python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 3 -d & | |||
| python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 1 -d & | |||
| python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 2 -d & | |||
| python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 3 -d & | |||
| python PyAPI/main.py -I 172.22.32.1 -P 8888 -p 4 -d & | |||
| @@ -7,26 +7,15 @@ | |||
| - Windows:先查看`.\win\CAPI\cpp\`文件夹下是否有`lib`文件夹,没有则https://cloud.tsinghua.edu.cn/d/6972138f641d4e81a446/ 下载并复制粘贴 | |||
| - Linux:首先自行安装`gRPC`,具体方法可以参考官方教程https://grpc.io/docs/languages/cpp/quickstart/。 | |||
| - 然后在`CAPI\cpp\API\src\AI.cpp`中编写代码 | |||
| - 应当编译2次以上,以生成不同的API.exe, | |||
| - 为了编译不同PlayerID的代码,我们可以 | |||
| - 复制若干次AI.cpp | |||
| - 利用constexpr | |||
|  | |||
| - 对于图中写法,编译前记得更改playerId | |||
| - 也可以利用#if、#endif | |||
| - Windows:然后用Visual Studio打开`CAPI\cpp\CAPI.sln`编译,注意使用Debug模式 | |||
| - Linux:用`cmake`,对`CAPI\cpp\CMakeLists.txt`进行编译 | |||
| - 每次编译后都在\THUAI6-毕业吧少女\win\CAPI\cpp\x64\Debug中将API.exe重命名并在`RunCpp.cmd`中对应修改地址参数,Linux环境类似 | |||
|  | |||
| - Windows:最后使用`RunCpp.cmd`执行比赛代码 | |||
| - Linux:最后使用`RunCpp.sh`执行比赛代码 | |||
| ## Python接口使用说明 | |||
| - 首先在Python环境下运行`GeneratePythonProto.cmd`,以安装必要的包、并生成对应的grpc python文件 | |||
| - 复制若干个`CAPI\python\PyAPI`文件夹 | |||
| - 然后在`CAPI\python\PyAPI0\AI.py`、`CAPI\python\PyAPI1\AI.py`等中编写对应代码并在`RunPython.cmd`中对应修改地址参数,Linux环境类似 | |||
|  | |||
| - 然后在`CAPI\python\PyAPI\AI.py`中编写代码 | |||
| - Windows:最后通过运行`RunPython.cmd`执行比赛代码 | |||
| - Linux:通过运行`RunPython.sh`执行比赛代码 | |||