# 使用文档

本文档仅供Windows选手参考，Linux，macOS选手仿照本文档即可。
[TOC]

## 不应当使用Windows特性的库，不建议使用.h结尾的库，建议使用标准库
- 不要使用conio.h，Windows.h

## 请注意下载器不更新AI.py,AI.cpp和脚本
- [最新版AI.cpp云盘](https://cloud.tsinghua.edu.cn/lib/54b4eb7b-956e-474c-b932-7b1ac29a9267/file/AI.cpp) 和[AI.py云盘](https://cloud.tsinghua.edu.cn/lib/54b4eb7b-956e-474c-b932-7b1ac29a9267/file/AI.py)

## C++接口使用说明

- 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`中编写代码
  - 选手不应当修改`AI.cpp`中原来有的代码，除了`void AI::play(IStudentAPI& api)`和`void AI::play(ITrickerAPI& api)`,及修改asynchronous的返回值
  - 每帧执行一次`AI::play(IStudentAPI& api)`或`AI::play(ITrickerAPI& api)`（除非执行该函数超过一帧50ms），获取的信息都是这一帧的开始的状态
  - 选手可以在`AI.cpp`内`void AI::play`外新增函数和变量
- Windows：然后用Visual Studio打开`CAPI\cpp\CAPI.sln`编译，注意使用Debug模式
  - Linux：用`cmake`，对`CAPI\cpp\CMakeLists.txt`进行编译
- Windows：最后使用`RunCpp.cmd`执行比赛代码
  - Linux：最后使用`RunCpp.sh`执行比赛代码

## Python接口使用说明

- 首先在Python环境下运行`GeneratePythonProto.cmd`，以安装必要的包、并生成对应的grpc python文件
- 然后在`CAPI\python\PyAPI\AI.py`中编写代码
  - 选手不应当修改`AI.py`中原来有的代码，除了`StudentPlay(self, api: IStudentAPI)`和`TrickerPlay(self, api: ITrickerAPI)`,及修改asynchronous的返回值
  - 每帧执行一次`AI::play(IStudentAPI& api)`或`AI::play(ITrickerAPI& api)`（除非执行该函数超过一帧50ms），获取的信息都是这一帧的开始的状态
  - 选手可以在`AI.py`内新增函数和变量
- Windows：最后通过运行`RunPython.cmd`执行比赛代码
  - Linux：通过运行`RunPython.sh`执行比赛代码

## cmd脚本的参数修改
右键点击`.cmd`或`.bat`文件之后，选择编辑就可以开始修改文件。通过在一行的开头加上`::`，可以注释掉该行。

## 游戏基本启动方式（For Debug）

1. 首先启动Server：`RunServerForDebug.cmd`
2. 再启动Client：Python使用`RunPython.cmd`，C++使用`RunCpp.cmd`
3. Windows环境下可以启动WPF客户端`RunGUIClient.cmd`观看比赛
- 下面逐一解释其中参数

### 启动服务器（RunServer）

启动服务器：`RunServer.cmd`，其内部参数可自主设定

Server脚本中参数格式一般如下：

```shell
--ip 0.0.0.0 --port 8888 --studentCount 4 --trickerCount 1 --gameTimeInSecond 600 --fileName video --mapResource ".\map\map1_final.txt"
```

`--ip`是服务器ipv4地址

- 在不同电脑间体验游戏时需要修改`--ip`这一参数，默认值为0.0.0.0
- 对于windows选手，在连接同一wifi（如Tsinghua-Secure）的情况下，打开终端输入`ipconfig`，找到IPv4地址即可

`--port`是服务器端口

- 自己规定，默认值为8888

`--studentCount`为本局学生个数

- 取值为0，1，2，3，4，默认值为4

`--trickerCount`为本局捣蛋鬼个数

- 取值为0，1，默认值为1

`--gameTimeInSecond`为本局最大游戏时长

- 可自主设定，默认值为600（秒）

`--fileName`为回放文件的保存名称

`--mapResource`为地图文件存放的相对（该脚本）路径
- 不写则为默认地图

### 启动Client(RunPython或RunCpp)

`RunCpp.cmd`或`RunPython.cmd`的脚本参数格式如下：

```shell
start .\CAPI\cpp\x64\Debug\API.exe -I 127.0.0.1 -P 8888 -p 0 -o -d -w
```
或者
```shell
start python .\CAPI\python\PyAPI\main.py -I 127.0.0.1 -P 8888 -p 0 -d -o -w
```

`start .\CAPI\cpp\x64\Debug\API.exe`或者`start python .\CAPI\python\PyAPI\main.py`为运行该目录下的程序（C++）/代码（python）
- 可以用不同的代码编译不同的exe(**也可以不**)，需要自己更改以上路径，对于Python，需要copy整个PyAPI,具体如下图
  ![RunCppCmd](https://raw.githubusercontent.com/shangfengh/THUAI6/new/resource/RunCppCmd.png)
  ![RunPython](https://raw.githubusercontent.com/shangfengh/THUAI6/new/resource/RunPython.png)
- 比赛最终要提交5份代码（可以5份一样的，现在的AI.cpp/AI.py支持一份代码对不同的PlayerID执行不同操作）

`-I`为服务器IP，一般本地为`127.0.0.1`，联机的话是服务器的IP

`-P`为服务器端口，一般为8888

`-p`为玩家id，一般学生为0~3，捣蛋鬼为4
- 请注意学生序号要从0开始，如果学生数量为n，不应当出现id大于等于n的学生

`-d`为保存Debug日志文件（在`/logs/`下）

`-o`为将日志输出到屏幕上

`-w`只在开启`-o`的情况下生效，此时屏幕上只输出警告或报错（而日志文件依然完整保存）。

### 启动WPF客户端（RunClient）

通过`RunGUIClient.cmd`，可以打开WPF客户端，其内部参数可自主设定，设定方式：右键-打开更多选项-编辑

```shell
--port 8888 --characterID 4 --type 2 --occupation 1
```

`--ip`是服务器ipv4地址

- 默认值为127.0.0.1，其余内容与Server相同，在不同电脑间连接时ip应相同

`-port`是服务器端口

- 默认值为8888，其余内容与Server相同，在不同电脑间连接时port应相同

`--characterID`为玩家id

- 学生取值为0，1，2，3，捣蛋鬼取值为4，characterID > 2023则是观战模式
- 请注意学生序号要从0开始，如果学生数量为n，不应当出现id大于等于n的学生
- 应当使`RunGUIClient.cmd`与 `RunPython.cmd`（或`RunCpp.cmd`）中学生、捣蛋鬼数量之和符合`RunServer.cmd`的要求
- 如果不启动`RunPython.cmd`（或`RunCpp.cmd`），则`RunGUIClient.cmd`中学生、捣蛋鬼数量应当符合`RunServer.cmd`的要求

`--type`为玩家类型

- 学生取值为1，捣蛋鬼取值为2

`--occupation`为职业选择，参考下表

#### 职业对应表：

* 学生

  | 参数 | 职业类型                        |
  | ---- | ------------------------------- |
  | 1    | Athlete                         |
  | 2    | Teacher                         |
  | 3    | StraightAStudent                |
  | 4    | Robot                           |
  | 5    | TechOtaku                       |
  | 6    | Sunshine                        |

* 捣蛋鬼

  | 参数 | 职业类型     |
  | ---- | ------------ |
  | 1    | Assassin     |
  | 2    | Klee         |
  | 3    | ANoisyPerson |
  | 4    | Idol         |

#### 观看回放文件

通过WPF客户端，还可以观看比赛回放。在`RunGUIClient.cmd`中，将参数改为

```shell
start cmd /k win64\Client.exe --cl --playbackFile .\video.thuaipb --playbackSpeed 2
```

即可观看回放文件。其中`--playbackFile`后面的参数为回放文件的路径，`--playbackSpeed`后面的参数为回放速度，取值为1~10，1为正常速度，10为最快速度。


## WPF简易调试界面

![client](https://raw.githubusercontent.com/eesast/THUAI6/dev/resource/clientsmaller.png)

### 界面介绍

* 固定方块：红色方块代表墙，绿色方块代表草，灰色方块代表窗户，黄色带锁标志的方块代表门，浅橙红色代表隐藏校门

* 动态方块：蓝色方块代表大门，橙色方块代表箱子，粉色方块代表教室，上面的数字均代表进度

* 物件：橙色圆代表捣蛋鬼，紫色圆代表学生，且上面的编号对应学生的ID，灰色表示Robot，它的编号表示所属的TechOtaku

* 道具对应表如下

  | 道具类型               | UI  |
  | ---------------------- | --- |
  | Key3                   | 🔑3  |
  | Key5                   | 🔑5  |
  | Key6                   | 🔑6  |
  | AddSpeed               | ⛸   |
  | AddLifeOrClairaudience | 🏅   |
  | AddHpOrAp              | ♥   |
  | ShieldOrSpear:         | 🛡   |
  | RecoveryFromDizziness  | 🕶   |

* UI：左侧为UI，表示游戏内各类信息

### 实机体验之键鼠操作

仅当以玩家身份启动`RunGUIClient.cmd`时可以使用

| 键位         | 效果                                           |
| ------------ | ---------------------------------------------- |
| W/NumPad8    | （Both）向上移动                               |
| S/NumPad2    | （Both）向下移动                               |
| D/NumPad6    | （Both）向右移动                               |
| A/NumPad4    | （Both）向左移动                               |
| J            | （Tri）攻击，方向向上                          |
| 鼠标双击某点 | （Tri）攻击，方向与从Tricker指向该点的向量相同 |
| K            | （Stu）开始学习                                |
| R            | （Stu）开始唤醒（陷入沉迷状态的同伴）          |
| T            | （Stu）开始勉励（学习毅力下降的同伴）          |
| G            | （Stu）发出毕业请求                            |
| H            | （Stu）申请毕业（或称为开校门）                |
| O            | （Both）开（教学楼）门                         |
| P            | （Both）关（教学楼）门                         |
| U            | （Both）翻窗                                   |
| I            | （Both）翻箱子                                 |
| E            | （Both）结束当前行动，回到Idle状态             |
| F            | （Both）随机捡起一个在周围的道具               |
| C            | （Both）随机扔下一个已经持有的道具             |
| V            | （Both）随机使用一个已经持有的道具             |
| B            | （Both）使用0号技能                            |
| N            | （Both）使用1号技能                            |
| M            | （Both）使用2号技能                            |
