diff --git a/CAPI/Tool_tutorial.md b/CAPI/Tool_tutorial.md index 8e57020..5209b2a 100644 --- a/CAPI/Tool_tutorial.md +++ b/CAPI/Tool_tutorial.md @@ -4,13 +4,25 @@ ## Visual Studio使用说明 -选手开始编写代码之前,要先编译好服务器(logic)。具体方法是进入logic文件夹,分别编译`logic.sln`和client文件夹里的`client.sln`,然后就可以开始编写自己的代码。需要注意,选手需要分别在Debug和Release模式下编译,然后才可以分别运行`gameServer_dbg.cmd`和`gameServer_rls.cmd` +比赛**只保证!!!支持**VS2022最新版本,选手使用其他版本后果自负(实际上应该不能编译)。 -## Python使用说明 +### 生成模式的设置 -选手编写Python代码之前需要安装必要的Python包,具体方法为:Windows下运行(需要在有Python环境的情况下运行)`generate_proto.cmd`,Linux下运行`generate_proto.sh`,然后可以开始进行代码编写。 +菜单栏下方一行 -## cmd脚本的参数修改 +![image-20230416010705076](src/image-20230416010705076.png) + +可以更改生成模式为`Debug`或`Release` + +### 命令行参数的设置 + +左上方菜单栏 `调试->调试属性` + +![image-20230416010816392](src/image-20230416010816392.png) + +在命令参数一栏中加入命令行参数进行调试 + +### cmd脚本的参数修改 右键点击`.cmd`或`.bat`文件之后,选择编辑就可以开始修改文件。通过在一行的开头加上`::`,可以注释掉该行。 @@ -234,7 +246,7 @@ for (auto itr = begin(arr); itr != end(arr); ++itr) ## Python接口必看 - +比赛**只保证!!**支持Python3.9,不保证支持其他版本 比赛中的Python接口大多使用异步接口,即返回一个类似于 `Future[bool]` 的值。为了获取实际的值,需要调用 `result()` 方法。 @@ -695,7 +707,7 @@ int main() ##### 概览 -`shared_ptr` 可以说是最常用的智能指针了。它的用法最为灵活,内部实现方式是**引用计数**。即,它会记录有多少个 `shared_ptr` 正在指向某个资源,并当指向该资源的智能指针数为零时,调用相应的释放函数(默认为 `delete` 操作符)释放该资源。 +`shared_ptr` 的用法最为灵活,内部实现方式是**引用计数**。即,它会记录有多少个 `shared_ptr` 正在指向某个资源,并当指向该资源的智能指针数为零时,调用相应的释放函数(默认为 `delete` 操作符)释放该资源。不过也需要注意,使用 `std::shared_ptr` 会比传统的指针带来额外的引用计数的开销,因此只有当后面将会介绍的 `std::unique_ptr` 无法满足要求时方可考虑 `std::shared_ptr`。 像 `new` 会在自由存储区动态获取一块内存并返回其一样,如果要动态分配一块内存并得到其智能指针,可以使用 `std::make_shared` 模板,例如: @@ -923,7 +935,7 @@ else #### `std::unique_ptr` -`std::unique_ptr` 顾名思义,独有的指针,即资源只能同时为一个 `unique_ptr` 所占有。它部分涉及到 `xvalue` 、右值引用与移动语义的问题,在此不做过多展开。 +`std::unique_ptr` 顾名思义,独有的指针,即资源只能同时为一个 `unique_ptr` 所占有,是基于 RAII 的思想设计的智能指针,并且相比于原始指针并不会带来任何额外开销,是智能指针的首选。它部分涉及到对象的生命期、右值引用与移动语义的问题,在此不做过多展开。 @@ -931,5 +943,4 @@ else + [cppreference_shared_ptr](https://zh.cppreference.com/w/cpp/memory/shared_ptr) + [cppreference_weak_ptr](https://zh.cppreference.com/w/cpp/memory/weak_ptr) - -+ [cppreference_unique_ptr](https://zh.cppreference.com/w/cpp/memory/unique_ptr) \ No newline at end of file ++ [cppreference_unique_ptr](https://zh.cppreference.com/w/cpp/memory/unique_ptr) diff --git a/CAPI/cmd/GeneratePythonProto.cmd b/CAPI/cmd/GeneratePythonProto.cmd new file mode 100644 index 0000000..34b1fd7 --- /dev/null +++ b/CAPI/cmd/GeneratePythonProto.cmd @@ -0,0 +1,13 @@ +@echo off + +python -m pip install -r .\CAPI\python\requirements.txt + +MKDIR .\CAPI\python\proto +echo generating python grpc files... + +python -m grpc_tools.protoc -I.\CAPI\proto\ --python_out=.\CAPI\python\proto --pyi_out=.\CAPI\python\proto MessageType.proto +python -m grpc_tools.protoc -I.\CAPI\proto\ --python_out=.\CAPI\python\proto --pyi_out=.\CAPI\python\proto Message2Clients.proto +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 diff --git a/CAPI/cmd/RunCpp.cmd b/CAPI/cmd/RunCpp.cmd new file mode 100644 index 0000000..ff4a482 --- /dev/null +++ b/CAPI/cmd/RunCpp.cmd @@ -0,0 +1,7 @@ +@echo off + +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 4 -o -d diff --git a/CAPI/cmd/RunGUIClient.cmd b/CAPI/cmd/RunGUIClient.cmd new file mode 100644 index 0000000..80006da --- /dev/null +++ b/CAPI/cmd/RunGUIClient.cmd @@ -0,0 +1,6 @@ +@echo off + +:: 添加 --cl 参数,程序运行时将自动识别命令行参数,并自动连接server +start cmd /k win64\Client.exe --port 8888 --characterID 114514 --type 0 --occupation 1 --ip 127.0.0.1 --cl + +:: characterID > 2023时是观战Client,否则是正常Client diff --git a/CAPI/cmd/RunPython.cmd b/CAPI/cmd/RunPython.cmd new file mode 100644 index 0000000..2ddd94d --- /dev/null +++ b/CAPI/cmd/RunPython.cmd @@ -0,0 +1,7 @@ +@echo off + +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 4 -d -o diff --git a/CAPI/cmd/RunServer.cmd b/CAPI/cmd/RunServer.cmd new file mode 100644 index 0000000..aa5213e --- /dev/null +++ b/CAPI/cmd/RunServer.cmd @@ -0,0 +1,5 @@ +@echo off + +.\win64\Server.exe --port 8888 --studentCount 1 --trickerCount 1 --gameTimeInSecond 600 --fileName video + +pause diff --git a/CAPI/cmd/RunServerForDebug.cmd b/CAPI/cmd/RunServerForDebug.cmd new file mode 100644 index 0000000..fa188c9 --- /dev/null +++ b/CAPI/cmd/RunServerForDebug.cmd @@ -0,0 +1,5 @@ +@echo off + +.\win64\Debug\Server.exe --port 8888 --studentCount 4 --trickerCount 1 --gameTimeInSecond 600 + +pause diff --git a/CAPI/cpp/API/include/AI.h b/CAPI/cpp/API/include/AI.h index d87de1e..cb6b373 100644 --- a/CAPI/cpp/API/include/AI.h +++ b/CAPI/cpp/API/include/AI.h @@ -13,17 +13,21 @@ public: virtual void play(ITrickerAPI& api) = 0; }; -using CreateAIFunc = std::unique_ptr (*)(); +using CreateAIFunc = std::unique_ptr (*)(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 diff --git a/CAPI/cpp/API/include/constants.h b/CAPI/cpp/API/include/constants.h index 34867b2..1bf0cd6 100644 --- a/CAPI/cpp/API/include/constants.h +++ b/CAPI/cpp/API/include/constants.h @@ -8,6 +8,7 @@ namespace Constants { + SCCI int frameDuration = 50; // 每帧毫秒数 // 地图相关 SCCI int numOfGridPerCell = 1000; // 单位坐标数 SCCI int rows = 50; // 地图行数 @@ -28,8 +29,8 @@ namespace Constants SCCI int basicEncourageSpeed = 100; SCCI int basicFixSpeed = 123; SCCI int basicSpeedOfOpeningOrLocking = 4000; - SCCI int basicStudentSpeedOfClimbingThroughWindows = 611; - SCCI int basicTrickerSpeedOfClimbingThroughWindows = 1270; + SCCI int basicStudentSpeedOfClimbingThroughWindows = 1222; + SCCI int basicTrickerSpeedOfClimbingThroughWindows = 2540; SCCI int basicSpeedOfOpenChest = 1000; SCCI int basicHp = 3000000; @@ -37,8 +38,8 @@ namespace Constants SCCI int basicEncouragementDegree = 1500000; SCCI int basicTimeOfRouse = 1000; - SCCI int basicStudentSpeed = 1270; - SCCI int basicTrickerSpeed = 1504; + SCCI int basicStudentSpeed = 3000; + SCCI int basicTrickerSpeed = 3600; SCCI double basicConcealment = 1; SCCI int basicStudentAlertnessRadius = 15 * numOfGridPerCell; @@ -58,10 +59,10 @@ namespace Constants SCCI int basicRecoveryFromHit = 3700; // 基本命中攻击恢复时长 SCCI int basicStunnedTimeOfStudent = 4300; - SCCI int basicBulletMoveSpeed = 3700; // 基本子弹移动速度 - SCCI double basicRemoteAttackRange = 3000; // 基本远程攻击范围 - SCCI double basicAttackShortRange = 1100; // 基本近程攻击范围 - SCCI double basicBulletBombRange = 1000; // 基本子弹爆炸范围 + SCCI int basicBulletMoveSpeed = 7400; // 基本子弹移动速度 + SCCI double basicRemoteAttackRange = 6000; // 基本远程攻击范围 + SCCI double basicAttackShortRange = 2200; // 基本近程攻击范围 + SCCI double basicBulletBombRange = 2000; // 基本子弹爆炸范围 // 道具相关 @@ -269,7 +270,7 @@ namespace Constants struct ShowTime { - SCCI int skillCD = commonSkillCD * 3; + SCCI int skillCD = commonSkillCD * 8 / 3; SCCI int durationTime = commonSkillTime * 1; }; diff --git a/CAPI/cpp/API/include/structures.h b/CAPI/cpp/API/include/structures.h index d92a5d2..ccda444 100644 --- a/CAPI/cpp/API/include/structures.h +++ b/CAPI/cpp/API/include/structures.h @@ -137,7 +137,7 @@ namespace THUAI6 Swinging = 11, Attacking = 12, Locking = 13, - Rummaging = 14, + // Rummaging = 14, Climbing = 15, OpeningAChest = 16, UsingSpecialSkill = 17, @@ -314,7 +314,7 @@ namespace THUAI6 {PlayerState::Swinging, "Swinging"}, {PlayerState::Attacking, "Attacking"}, {PlayerState::Locking, "Locking"}, - {PlayerState::Rummaging, "Rummaging"}, + // {PlayerState::Rummaging, "Rummaging"}, {PlayerState::Climbing, "Climbing"}, {PlayerState::OpeningAChest, "OpeningAChest"}, {PlayerState::UsingSpecialSkill, "UsingSpecialSkill"}, diff --git a/CAPI/cpp/API/include/utils.hpp b/CAPI/cpp/API/include/utils.hpp index e4f9260..1044b74 100644 --- a/CAPI/cpp/API/include/utils.hpp +++ b/CAPI/cpp/API/include/utils.hpp @@ -162,7 +162,7 @@ namespace Proto2THUAI6 {protobuf::PlayerState::SWINGING, THUAI6::PlayerState::Swinging}, {protobuf::PlayerState::ATTACKING, THUAI6::PlayerState::Attacking}, {protobuf::PlayerState::LOCKING, THUAI6::PlayerState::Locking}, - {protobuf::PlayerState::RUMMAGING, THUAI6::PlayerState::Rummaging}, + // {protobuf::PlayerState::RUMMAGING, THUAI6::PlayerState::Rummaging}, {protobuf::PlayerState::CLIMBING, THUAI6::PlayerState::Climbing}, {protobuf::PlayerState::OPENING_A_CHEST, THUAI6::PlayerState::OpeningAChest}, {protobuf::PlayerState::USING_SPECIAL_SKILL, THUAI6::PlayerState::UsingSpecialSkill}, diff --git a/CAPI/cpp/API/src/AI.cpp b/CAPI/cpp/API/src/AI.cpp index 5e94723..5843e64 100644 --- a/CAPI/cpp/API/src/AI.cpp +++ b/CAPI/cpp/API/src/AI.cpp @@ -1,31 +1,49 @@ #include #include +#include #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 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) { - api.PrintTricker(); + // 公共操作 + 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) { - if (api.HaveMessage()) - { - auto msg = api.GetMessage(); - api.Print("Message from " + std::to_string(msg.first) + ": " + msg.second); - } + auto self = api.GetSelfInfo(); + api.PrintSelfInfo(); } diff --git a/CAPI/cpp/API/src/logic.cpp b/CAPI/cpp/API/src/logic.cpp index abb4440..40c5b24 100644 --- a/CAPI/cpp/API/src/logic.cpp +++ b/CAPI/cpp/API/src/logic.cpp @@ -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) { diff --git a/CAPI/cpp/API/src/main.cpp b/CAPI/cpp/API/src/main.cpp index 037a842..ee0ecb6 100644 --- a/CAPI/cpp/API/src/main.cpp +++ b/CAPI/cpp/API/src/main.cpp @@ -2,6 +2,7 @@ #include "logic.h" #include "structures.h" #include +#include #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 studentType; // { // file = true; // print = true; @@ -71,7 +71,16 @@ int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder) } try { - Logic logic(playerType, pID, trickerType, studentType); + THUAI6::PlayerType playerType; + THUAI6::StudentType stuType = THUAI6::StudentType::NullStudentType; + if (pID == 4) + playerType = THUAI6::PlayerType::TrickerPlayer; + else + { + playerType = THUAI6::PlayerType::StudentPlayer; + stuType = studentType[pID]; + } + Logic logic(playerType, pID, trickerType, stuType); logic.Main(AIBuilder, sIP, sPort, file, print, warnOnly); } catch (const std::exception& e) @@ -81,9 +90,9 @@ int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder) return 0; } -std::unique_ptr CreateAI() +std::unique_ptr CreateAI(int64_t pID) { - return std::make_unique(); + return std::make_unique(pID); } int main(int argc, char* argv[]) diff --git a/CAPI/cpp/spdlog/LICENSE b/CAPI/cpp/spdlog/LICENSE new file mode 100644 index 0000000..d4eb308 --- /dev/null +++ b/CAPI/cpp/spdlog/LICENSE @@ -0,0 +1,25 @@ +The MIT License (MIT) + +Copyright (c) 2016 Gabi Melman. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +-- NOTE: Third party dependency used by this software -- +This software depends on the fmt lib (MIT License), +and users must comply to its license: https://github.com/fmtlib/fmt/blob/master/LICENSE.rst diff --git a/CAPI/python/PyAPI/AI.py b/CAPI/python/PyAPI/AI.py index a503018..5c742f6 100644 --- a/CAPI/python/PyAPI/AI.py +++ b/CAPI/python/PyAPI/AI.py @@ -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: @@ -43,112 +38,29 @@ class AssistFunction: return grid // numOfGridPerCell -path = [] -cur = 0 -fixedclass = [] - - class AI(IAI): - # 选手在这里实现自己的逻辑,要求和上面选择的阵营保持一致 - def StudentPlay(self, api: IStudentAPI) -> None: - # global fixedclass - # selfInfo = api.GetSelfInfo() - # available = [THUAI6.PlaceType.Land, - # THUAI6.PlaceType.Grass, THUAI6.PlaceType.Door3, THUAI6.PlaceType.Door6, THUAI6.PlaceType.Door5, THUAI6.PlaceType.Gate] - - # def bfs(x, y): - # if api.GetPlaceType(x, y) not in available: - # return [] - - # def GetSuccessors(x, y): - # successors = [] - # if x > 0 and api.GetPlaceType(x - 1, y) in available: - # successors.append((x - 1, y)) - # if x < 49 and api.GetPlaceType(x + 1, y) in available: - # successors.append((x + 1, y)) - # if y > 0 and api.GetPlaceType(x, y - 1) in available: - # successors.append((x, y - 1)) - # if y < 49 and api.GetPlaceType(x, y + 1) in available: - # successors.append((x, y + 1)) - # return successors - # selfX = AssistFunction.GridToCell(api.GetSelfInfo().x) - # selfY = AssistFunction.GridToCell(api.GetSelfInfo().y) - # frontier = queue.Queue() - # frontier.put((selfX, selfY, [])) - # visited = [] - # while not frontier.empty(): - # currentX, currentY, path = frontier.get() - # if currentX == x and currentY == y: - # return path - # for nextX, nextY in GetSuccessors(currentX, currentY): - # if (nextX, nextY) not in visited: - # visited.append((nextX, nextY)) - # frontier.put((nextX, nextY, path + [(nextX, nextY)])) - # return [] + def __init__(self, pID: int): + self.__playerID = pID - # def GoTo(x, y): - # global path, cur - # if path != [] and cur < len(path): - # selfX = api.GetSelfInfo().x - # selfY = api.GetSelfInfo().y - # nextX, nextY = path[cur] - # nextX = AssistFunction.CellToGrid(nextX) - # nextY = AssistFunction.CellToGrid(nextY) - # if selfX < nextX - 100: - # api.MoveDown(10) - # time.sleep(0.01) - # return - # if selfX > nextX + 100: - # api.MoveUp(10) - # time.sleep(0.01) - # return - # if selfY < nextY - 100: - # api.MoveRight(10) - # time.sleep(0.01) - # return - # if selfY > nextY + 100: - # api.MoveLeft(10) - # time.sleep(0.01) - # return - # cur += 1 - # return - # else: - # path = bfs(x, y) - # cur = 0 - # return - - # if (AssistFunction.GridToCell(api.GetSelfInfo().x), AssistFunction.GridToCell(api.GetSelfInfo().y)) == (6, 6) and api.GetGateProgress(5, 6) < 18000: - # api.StartOpenGate() - # return - - # if (AssistFunction.GridToCell(api.GetSelfInfo().x), AssistFunction.GridToCell(api.GetSelfInfo().y)) == (6, 6) and api.GetGateProgress(5, 6) >= 18000: - # api.Graduate() - # return - - # if len(fixedclass) == 7: - # GoTo(6, 6) - # return - - # if api.GetPlaceType(AssistFunction.GridToCell(api.GetSelfInfo().x) + 1, AssistFunction.GridToCell(api.GetSelfInfo().y)) == THUAI6.PlaceType.ClassRoom: - # api.Print("Trying to fix!") - # if api.GetClassroomProgress(AssistFunction.GridToCell(api.GetSelfInfo().x) + 1, AssistFunction.GridToCell(api.GetSelfInfo().y)) < 103000: - # api.StartLearning() - # return - # else: - # if (AssistFunction.GridToCell(api.GetSelfInfo().x) + 1, AssistFunction.GridToCell(api.GetSelfInfo().y)) not in fixedclass: - # fixedclass.append( - # (AssistFunction.GridToCell(api.GetSelfInfo().x) + 1, AssistFunction.GridToCell(api.GetSelfInfo().y))) - - # for i in range(50): - # for j in range(50): - # if api.GetPlaceType(i, j) == THUAI6.PlaceType.ClassRoom and (i, j) not in fixedclass: - # if api.GetPlaceType(i - 1, j) in available: - # GoTo(i - 1, j) - # return - api.PrintTricker() + def StudentPlay(self, api: IStudentAPI) -> None: + #公共操作 + 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: - api.UseSkill(0) - api.UseSkill(1) + selfInfo = api.GetSelfInfo() api.PrintSelfInfo() return diff --git a/CAPI/python/PyAPI/Communication.py b/CAPI/python/PyAPI/Communication.py index adeea1f..e3b5960 100644 --- a/CAPI/python/PyAPI/Communication.py +++ b/CAPI/python/PyAPI/Communication.py @@ -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 diff --git a/CAPI/python/PyAPI/constants.py b/CAPI/python/PyAPI/constants.py index dea67a2..9426e73 100644 --- a/CAPI/python/PyAPI/constants.py +++ b/CAPI/python/PyAPI/constants.py @@ -8,6 +8,7 @@ class NoInstance: class Constants(NoInstance): + frameDuration = 50 # 每帧毫秒数 numOfGridPerCell = 1000 # 单位坐标数 rows = 50 # 地图行数 cols = 50 # 地图列数 @@ -27,8 +28,8 @@ class Constants(NoInstance): basicEncourageSpeed = 100 basicLearnSpeed = 123 basicSpeedOfOpeningOrLocking = 4000 - basicStudentSpeedOfClimbingThroughWindows = 611 - basicTrickerSpeedOfClimbingThroughWindows = 1270 + basicStudentSpeedOfClimbingThroughWindows = 1222 + basicTrickerSpeedOfClimbingThroughWindows = 2540 basicSpeedOfOpenChest = 1000 basicHp = 3000000 @@ -36,8 +37,8 @@ class Constants(NoInstance): basicEncouragementDegree = 1500000 basicTimeOfRouse = 1000 - basicStudentSpeed = 1270 - basicTrickerSpeed = 1504 + basicStudentSpeed = 3000 + basicTrickerSpeed = 3600 basicConcealment = 1.0 basicStudentAlertnessRadius = 15 * numOfGridPerCell @@ -57,10 +58,10 @@ class Constants(NoInstance): basicRecoveryFromHit = 3700 # 基本命中攻击恢复时长 basicStunnedTimeOfStudent = 4300 - basicBulletmoveSpeed = 3700 # 基本子弹移动速度 - basicRemoteAttackRange = 3000 # 基本远程攻击范围 - basicAttackShortRange = 1100 # 基本近程攻击范围 - basicBulletBombRange = 1000 # 基本子弹爆炸范围 + basicBulletmoveSpeed = 7400 # 基本子弹移动速度 + basicRemoteAttackRange = 6000 # 基本远程攻击范围 + basicAttackShortRange = 2200 # 基本近程攻击范围 + basicBulletBombRange = 2000 # 基本子弹爆炸范围 # 道具相关 @@ -84,10 +85,10 @@ class Constants(NoInstance): addedTimeOfSpeedWhenInspire = 1.6 timeOfAddingSpeedWhenInspire = 6000 - addHpWhenEncourage = basicHp / 4; + addHpWhenEncourage = basicHp / 4 - checkIntervalWhenShowTime = 200; - addAddictionPer100msWhenShowTime = 300; + checkIntervalWhenShowTime = 200 + addAddictionPer100msWhenShowTime = 300 class Assassin: @@ -270,7 +271,7 @@ class Howl: class ShowTime: - skillCD = (int)(3.0 * Constants.commonSkillCD) + skillCD = (int)(8 * Constants.commonSkillCD / 3) durationTime = (int)(1.0 * Constants.commonSkillTime) diff --git a/CAPI/python/PyAPI/logic.py b/CAPI/python/PyAPI/logic.py index 1db66a7..5dce4cc 100644 --- a/CAPI/python/PyAPI/logic.py +++ b/CAPI/python/PyAPI/logic.py @@ -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() diff --git a/CAPI/python/PyAPI/main.py b/CAPI/python/PyAPI/main.py index 5622a3b..d915634 100644 --- a/CAPI/python/PyAPI/main.py +++ b/CAPI/python/PyAPI/main.py @@ -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__': diff --git a/CAPI/python/PyAPI/structures.py b/CAPI/python/PyAPI/structures.py index 012f7ab..939f452 100644 --- a/CAPI/python/PyAPI/structures.py +++ b/CAPI/python/PyAPI/structures.py @@ -113,7 +113,7 @@ class PlayerState(Enum): Swinging = 11 Attacking = 12 Locking = 13 - Rummaging = 14 + # Rummaging = 14 Climbing = 15 OpeningAChest = 16 UsingSpecialSkill = 17 diff --git a/CAPI/python/PyAPI/utils.py b/CAPI/python/PyAPI/utils.py index 2e1c181..e286212 100644 --- a/CAPI/python/PyAPI/utils.py +++ b/CAPI/python/PyAPI/utils.py @@ -145,7 +145,7 @@ class Proto2THUAI6(NoInstance): MessageType.SWINGING: THUAI6.PlayerState.Swinging, MessageType.ATTACKING: THUAI6.PlayerState.Attacking, MessageType.LOCKING: THUAI6.PlayerState.Locking, - MessageType.RUMMAGING: THUAI6.PlayerState.Rummaging, + # MessageType.RUMMAGING: THUAI6.PlayerState.Rummaging, MessageType.CLIMBING: THUAI6.PlayerState.Climbing, MessageType.OPENING_A_CHEST: THUAI6.PlayerState.OpeningAChest, MessageType.USING_SPECIAL_SKILL: THUAI6.PlayerState.UsingSpecialSkill, diff --git a/CAPI/python/run.sh b/CAPI/python/run.sh index ec08c25..ae82681 100755 --- a/CAPI/python/run.sh +++ b/CAPI/python/run.sh @@ -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 & \ No newline at end of file +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 & \ No newline at end of file diff --git a/CAPI/shell/GenerateCppProto.sh b/CAPI/shell/GenerateCppProto.sh new file mode 100644 index 0000000..f48d826 --- /dev/null +++ b/CAPI/shell/GenerateCppProto.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +./CAPI/proto/cpp_output.sh \ No newline at end of file diff --git a/CAPI/shell/GeneratePythonProto.sh b/CAPI/shell/GeneratePythonProto.sh new file mode 100644 index 0000000..2ad6be0 --- /dev/null +++ b/CAPI/shell/GeneratePythonProto.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +python -m pip install -r ./CAPI/python/requirements.txt + +mkdir -p proto + +python -m grpc_tools.protoc -I./CAPI/proto/ --python_out=./CAPI/python/proto --pyi_out=./CAPI/python/proto MessageType.proto +python -m grpc_tools.protoc -I./CAPI/proto/ --python_out=./CAPI/python/proto --pyi_out=./CAPI/python/proto Message2Clients.proto +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 + + diff --git a/CAPI/shell/RunCpp.sh b/CAPI/shell/RunCpp.sh new file mode 100644 index 0000000..911466a --- /dev/null +++ b/CAPI/shell/RunCpp.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +./CAPI/cpp/build/capi -I 127.0.0.1 -P 8888 -p 0 -d -o & +./CAPI/cpp/build/capi -I 127.0.0.1 -P 8888 -p 1 -d -o & +./CAPI/cpp/build/capi -I 127.0.0.1 -P 8888 -p 2 -d -o & +./CAPI/cpp/build/capi -I 127.0.0.1 -P 8888 -p 3 -d -o & \ No newline at end of file diff --git a/CAPI/shell/RunPython.sh b/CAPI/shell/RunPython.sh new file mode 100644 index 0000000..ead4676 --- /dev/null +++ b/CAPI/shell/RunPython.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +python ./CAPI/python/PyAPI/main.py -I 127.0.0.1 -P 8888 -p 0 -d -o & +python ./CAPI/python/PyAPI/main.py -I 127.0.0.1 -P 8888 -p 1 -d -o & +python ./CAPI/python/PyAPI/main.py -I 127.0.0.1 -P 8888 -p 2 -d -o & +python ./CAPI/python/PyAPI/main.py -I 127.0.0.1 -P 8888 -p 3 -d -o & \ No newline at end of file diff --git a/CAPI/shell/RunServer.sh b/CAPI/shell/RunServer.sh new file mode 100644 index 0000000..b15dad0 --- /dev/null +++ b/CAPI/shell/RunServer.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +./linux64/Server --port 8888 --studentCount 4 --trickerCount 1 --gameTimeInSecond 600 \ No newline at end of file diff --git a/CAPI/shell/RunServerForDebug.sh b/CAPI/shell/RunServerForDebug.sh new file mode 100644 index 0000000..5d044ef --- /dev/null +++ b/CAPI/shell/RunServerForDebug.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +./linux64/Debug/Server --port 8888 --studentCount 4 --trickerCount 1 --gameTimeInSecond 600 \ No newline at end of file diff --git a/CAPI/src/image-20230416010705076.png b/CAPI/src/image-20230416010705076.png new file mode 100644 index 0000000..62208f8 Binary files /dev/null and b/CAPI/src/image-20230416010705076.png differ diff --git a/CAPI/src/image-20230416010816392.png b/CAPI/src/image-20230416010816392.png new file mode 100644 index 0000000..6b59542 Binary files /dev/null and b/CAPI/src/image-20230416010816392.png differ diff --git a/Q&A.md b/Q&A.md new file mode 100644 index 0000000..3693e10 --- /dev/null +++ b/Q&A.md @@ -0,0 +1,64 @@ +# Q&A +[TOC] + +## 常见简单问题 + +Q: Windows找不到文件:\CAPI\cpp\x64\Debug\APl.exe? + +A: +应该是还没有编译,打开CAPI\cpp目录,在里面打开CAPI.sln,然后点击生成,对代码进行编译 + + +Q: 怎么修改.cmd参数? + +A: +见选手包中的使用文档部分 + + +Q: 怎么开始游戏? + +A: +需要确保学生阵营和捣蛋鬼阵营的人数都达到Server.cmd中设定的值。人数不足也可以打开WPF,参考使用文档,修改RunGUIClient.cmd的参数,然后运行RunGUIClient.cmd,这样可以通过WPF运行部分客户端,来达到人数限制。 + + +Q: Mac怎么用? + +A: +安装Windows虚拟机 + +## C++ + +Q:显示API项目已卸载 +![Nocplus](.\resource\Nocplus.png) + +A:可能是没有安装C++ + +Q:CAPI.sln编译不通过 +![std_find_trivial](.\resource\std_find_trivial.jpg) + +A: +出现_std_find_trivial_1的报错就是没更新到VS2022, +对于VS2022依旧报错_std_find_trivial_1的,先考虑是否版本过旧 +![项目属性](.\resource\项目属性.png) +确保上图项目属性中平台工具集在V143及以上,C++17标准 + +## Python + +### grpc版本更新失败 + +Q:运行GeneratePythonProto.cmd报错 +![grpcUpdate](.\resource\Q&A_grpc.png) + +A: +- 可能措施1. +首先保证Python版本在3.9及以上 +- 可能措施2. 更换为国内镜像源 +在终端输入 + `pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple` +- 可能措施3. 更新pip +`python -m pip install --upgrade pip` (pip 版本最好为23.1) + +## 比赛相关 +Q:职业数值会修改吗? + +A:初赛结束会调数值及机制,增加新角色 \ No newline at end of file diff --git a/dependency/Dockerfile/Dockerfile b/dependency/Dockerfile/Dockerfile_cpp similarity index 63% rename from dependency/Dockerfile/Dockerfile rename to dependency/Dockerfile/Dockerfile_cpp index 6553c13..a4f178a 100644 --- a/dependency/Dockerfile/Dockerfile +++ b/dependency/Dockerfile/Dockerfile_cpp @@ -8,31 +8,37 @@ RUN apt-get update && apt-get install --no-install-recommends -y gcc g++ make wg RUN git clone -b v1.46.3 --depth 1 --shallow-submodules https://gitee.com/mirrors/grpc.git RUN wget -P . https://cloud.tsinghua.edu.cn/f/1f2713efd9e44255abd6/?dl=1 RUN mv 'index.html?dl=1' third_party.tar.gz -RUN cd grpc +WORKDIR /usr/local/grpc RUN rm -rf third_party RUN mv ../third_party.tar.gz . RUN tar -zxvf third_party.tar.gz RUN mkdir -p cmake/build -RUN pushd cmake/build +WORKDIR /usr/local/grpc/cmake/build RUN cmake -DgRPC_INSTALL=ON \ -DgRPC_BUILD_TESTS=OFF \ ../.. RUN make -j$(nproc) RUN make install -RUN popd #安装protobuf -RUN cd /usr/local +WORKDIR /usr/local RUN git clone https://gitee.com/mirrors/protobuf_source.git ./protobuf -RUN cd protobuf -RUN git checkout 3.22.1 -RUN ./autogen.sh +WORKDIR /usr/local/protobuf +RUN git checkout 3.20.x +RUN ./autogen.sh RUN ./configure RUN make -j$(nproc) RUN make install RUN ldconfig +#RUN git submodule update --init --recursive +#RUN cmake . +#RUN cmake --build . --parallel 10 +#RUN make install -COPY ./CAPI /usr/local/PlayerCode -RUN cd /usr/local/PlayerCode/CAPI -RUN cmake CMakeLists.txt +COPY ./CAPI /usr/local/PlayerCode/CAPI +COPY ./dependency /usr/local/PlayerCode/dependency +WORKDIR /usr/local/PlayerCode/dependency/proto +RUN ./cpp_output.sh +WORKDIR /usr/local/PlayerCode/CAPI/cpp +RUN cmake ./CMakeLists.txt RUN make diff --git a/dependency/shell/publish.cmd b/dependency/shell/publish.cmd new file mode 100644 index 0000000..d81d05c --- /dev/null +++ b/dependency/shell/publish.cmd @@ -0,0 +1,8 @@ +@ECHO OFF +CD %~dp0 +dotnet publish "../../Logic/Server/Server.csproj" -c Release -r linux-x64 --self-contained true +dotnet publish "../../Logic/Server/Server.csproj" -c Release -r win-x64 --self-contained true +dotnet publish "../../Logic/Server/Server.csproj" -c Debug -r win-x64 --self-contained true +dotnet publish "../../Logic/Server/Server.csproj" -c Debug -r linux-x64 --self-contained true +dotnet publish "../../Logic/Client/Client.csproj" -c Release -r win-x64 --self-contained true +PAUSE diff --git a/dependency/shell/publish.sh b/dependency/shell/publish.sh new file mode 100644 index 0000000..2a8c775 --- /dev/null +++ b/dependency/shell/publish.sh @@ -0,0 +1,38 @@ +#! /bin/bash +workdir=/d/伤风/软件部/MyTHUAI6/THUAI6/logic +targetdir=/d/伤风/软件部/THUAI6-毕业吧少女 + +mkdir -p ${targetdir} + +pushd ${targetdir} +mkdir -p win/win64 +mkdir -p linux/linux64/ +mkdir -p win/win64/Debug/ +mkdir -p linux/linux64/Debug/ +popd + +pushd ${workdir} + +pushd Server/bin/Release/net6.0/linux-x64/publish +rm *.pdb +cp -rf * ${targetdir}/linux/linux64/ +popd + +pushd Server/bin/Debug/net6.0/linux-x64/publish +cp -rf * ${targetdir}/linux/linux64/Debug/ +popd + +pushd Server/bin/Debug/net6.0/win-x64/publish +cp -rf * ${targetdir}/win/win64/Debug/ +popd + +pushd Server/bin/Release/net6.0/win-x64/publish +rm *.pdb +cp -rf * ${targetdir}/win/win64/ +popd + +pushd Client/bin/Release/net6.0-windows/win-x64/publish +rm *.pdb +cp -rf * ${targetdir}/win/win64/ + +popd diff --git a/installer/Installer/Installer.csproj b/installer/Installer/Installer.csproj index b92fc30..53d5639 100644 --- a/installer/Installer/Installer.csproj +++ b/installer/Installer/Installer.csproj @@ -9,6 +9,7 @@ + diff --git a/installer/Installer/MainWindow.xaml b/installer/Installer/MainWindow.xaml index 48625cc..4e74b10 100644 --- a/installer/Installer/MainWindow.xaml +++ b/installer/Installer/MainWindow.xaml @@ -38,17 +38,19 @@