Skip to content

C++ AI SDK 文档

1. 选手提交说明

选手必须的填写函数

play

当选手回合开始后,会执行一次 play 函数。选手需要在该函数中操控 client 完成一回合的决策、行动

NOTE:完成所有的决策和操作后调用finish结束回合。

void play(AI_Client& client);

参数:

  • clientAI_Client&,参与游戏的 AI 类,在其中处理了数据的发送与接收。

选手可以填写的函数

选手可以填写以下函数,用于处理回合外,自己的陷阱被触发时的处理部分。这两个函数会在回合外,接收到陷阱触发/摧毁消息时被自动调用。

NOTE: 由于陷阱被触发后立刻摧毁,所以可以只填写一个。

void _trigger_trap(std::string trap, Pos pos);
void _destroy_trap(std::string trap, Pos pos);

参数:

  • trap:被触发的陷阱类型
  • pos:被触发的位置

提交说明

使用如下指令,将ai_client.cpp, ai_client.h, main.cpp, Makefile, mapconf2.map, 文件夹jsoncpp,和所需的其他文件一同打包交至saiblo。你可以修改Makefile中对应的部分,以使用以下指令更方便的完成打包操作(我们在Makefile中给出了样例ai的打包命令示例):

make ai.zip

2. AI_Client

代表游戏中的一个 AI,提供各种行动和信息查询接口。

2.1 构造函数


AI_Client::AI_Client(char* map_config_path);
AI_Client::AI_Client(const AI_Client& another_client);
  1. 由地图文件构造:map_config_pathchar*,地图文件的路径,默认网站评测时是sdk文件夹下的mapconf2.map,本地评测时默认是逻辑源码文件夹下的mapconf2.map。
  2. 拷贝构造。

2.2 pos和node的转换


PosNode的定义见下。

pos2node

Node& AI_Client::pos2node(const Pos& p);

参数:

返回值:Node&,坐标 p 对应的地图节点。当坐标p不合法时,抛出runtime_error

node2pos

Pos AI_Client::node2pos(const Node& n);

参数:

返回值:Pos,节点 n 对应的坐标。

2.3 查询函数


get_state

int get_state() const;

返回值: 当前的回合数

get_escape_pos

Pos AI_Client::get_escape_pos() const;

返回值:Pos,最终逃生点的坐标。

get_spawn_pos

Pos AI_Client::get_spawn_pos(int num) const;

参数:

  • numint,待查玩家的 ID(0/1/2/3).

返回值:Pos,ID 为 num 的玩家的出生点坐标。

get_player_pos

Pos AI_Client::get_player_pos() const;

返回值:Pos,玩家当前的坐标。

get_others_pos

Pos AI_Client::get_others_pos(int id) const;

参数:

  • idint,待查玩家的 ID.

返回值:Pos,ID 为 id 的玩家的当前坐标。

:当前玩家的坐标请使用 get_player_pos 获取。

get_player_hp

int AI_Client::get_player_hp() const;

返回值:int,玩家当前的血量。

get_others_hp

int AI_Client::get_others_hp(int id) const;

参数:

  • idint,待查玩家的 ID.

返回值:int,ID 为 id 的玩家的当前血量。

:当前玩家的血量请使用 get_player_hp 获取。

get_neighbors

std::vector<Pos> AI_Client::get_neighbors(const Pos &p, bool consider_elevator);

参数:

  • pconst Pos&,待查点的坐标。
  • consider_elevatorbool,电梯连通性,true 表示考虑上下层相连,默认false.

返回值:std::vector<Pos>,与坐标 p 相邻节点的坐标列表。

:仅返回可达点的坐标,即相邻且未被缩圈的点。

find_shortest_path

std::vector<Pos> AI_Client::find_shortest_path(const Pos &s, const Pos &t);

参数:

返回值:std::vector<Pos>,起点 s 到终点 t 的一条最短路径,列表中的坐标按从 st 顺序排列。

复杂度:线性。

:若 st 不连通,则返回空 std::vector.

get_check_cd

int AI_Client::get_check_cd() const;

返回值:int,探查行动的技能冷却剩余回合数。

get_tools

Tool AI_Client::get_tools() const;

返回值:Tool,玩家持有的道具。Tool的定义见下。

get_keys

std::vector<int> AI_Client::get_keys() const;

返回值:std::vector<int>,玩家持有的钥匙列表。

get_others_keys

std::vector<int> AI_Client::get_others_keys(int id) const;

参数:

  • idint,待查玩家的 ID.

返回值:std::vector<int>,ID 为 id 的玩家持有的钥匙列表。

:当前玩家持有的钥匙请使用 get_keys 获取。

get_id

int AI_Client::get_id() const;

返回值:int,当前玩家的 ID.

judge_if_can_pick

std::pair<bool, std::vector<std::string>> judge_if_can_pick(const Node& n);

参数:

返回值:std::pair<bool, std::vector<std::string>>>,若该节点上有物品可拾取,则 .firsttrue.second 表示物品信息,包含:

  • "Materials":物资点。
  • "Box":玩家死亡后的掉落物。
  • 两个都无则vector为空

2.4 进行操作


move

bool AI_Client::move(const Pos& tar);

参数:

  • tarconst Pos&,目标位置的坐标,玩家移动一步,到达 tar.

返回值:bool,若操作合法,则返回 true.

attack

bool AI_Client::attack(const Pos& pos, int playerid);

参数:

  • posconst Pos&,攻击的目标位置。
  • playeridint,对 pos 处 ID 为 playerid 的玩家发动攻击。

返回值:bool,若操作合法,则返回 true.

inspect_materials

bool AI_Client::inspect_materials(const std::string& type);

拾取物资点中的物资。

参数:

  • typeconst std::string&,要拾取物品的种类,合法取值为ToolType中的字符串:

返回值:若拾取成功,则返回 true.

inspect_box

bool inspect_box();

拾取掉落物。

返回值:操作是否合法。

place_trap

bool AI_Client::place_trap(const std::string& type);""

参数:

  • typeconst std::string&,在当前位置放置一个 type 类型的陷阱,type 取值范围为:
  • "LandMine":地雷
  • "Sticky":粘弹(ToolType.Slime)

返回值:bool,若操作合法,则返回 true.

use_kit

bool AI_Client::use_kit();

使用一个医疗包。

返回值:bool,若操作合法,则返回 true.

detect

bool AI_Client::detect(const Pos& tar);

参数:

  • tarconst Pos&,要探查的坐标(合法的坐标与自己所在的坐标相邻,且不可跨层)。

返回值:bool,若发现陷阱,则将其摧毁,并返回 true。但如果该点处的陷阱是自己的,则不将其摧毁,但返回true。若未发现陷阱,则返回false

:若操作非法,则无任何效果,并抛出runtime_error异常。

get_key

bool AI_Client::get_key();

与当前位置的钥匙机互动,下一回合将获得对应钥匙。

返回值:bool,若操作合法,则返回 true.

escape

bool escape(bool to_escape); 

进行逃离。

参数:

  • to_escape:为true表示进入逃生等待状态,为false表示中断逃生等待。

返回值:bool,若操作合法,则返回 true.

bool AI_Client::blink(Pos target);

参数:

  • targetPos&,目标位置的坐标,玩家闪现一步距离(不可跨层闪现),到达 target.

返回值:bool,若操作合法,则返回 true.

finish

void AI_Client::finish();

结束本回合。

2.5 得到拷贝


get_player_copy

Player get_player_copy(int id);

参数:

  • id: 要得到的player的id,可以为自己

返回值:该player的拷贝值。

get_copy

std::pair<AI_Client*, std::vector<Player*>> get_copy();

得到一份完整的AI_Client的拷贝,并返回该拷贝对应的私有变量。

返回值:返回一个AI_Client的拷贝,和该拷贝中所有Player的指针列表。指针列表中按照id顺序,依次存放了该拷贝中,包括自己在内的所有玩家的Player实例。

Tips:修改pos2node的返回值中的信息可以修改当前AI_Client的节点信息。

2.6 主进程函数


run

void AI_Client::run();

用于回合制循环。


类型别名

Pos

using Pos = std::tuple<int, int, int>;

坐标三元组 \((x, y, z)\).

Trapbag

using Trapbag = std::map<std::string, std::vector<std::vector<int>>>;
  • key_type:陷阱类型:
  • "LandMine":地雷
  • "Sticky":粘弹
  • mapped_type:二维数组,该类型陷阱道具的使用信息
  • [0][]:大小为 \(1\) 的列表,剩余陷阱道具的数量。
  • [1][]:大小为 \(1\) 的列表,已放置的陷阱道具的数量。
  • [i][]\(i > 1\),大小为 \(3\) 的列表,已放置陷阱道具的坐标 \([x, y, z]\).

Nodeset

using Nodeset = std::vector<std::vector<std::vector<Node*>>>;

三维数组,用于存储地图,三个维度依次对应 \(x, y, z\).


常量

LAYER

constexpr int LAYER = 3;

地图的层数。

INF

constexpr int INF = 0x3f3f3f3f;

相较于游戏中所有可能出现的合法数值,等效于 \(+\infty\).

ToolType

// 道具类型
struct {
    std::string LandMine = "LandMine";  // 地雷
    std::string Slime = "Sticky";       // 粘弹,策划案中的官方名称为Slime,游戏逻辑中对应为Sticky
    std::string MedKit = "Kit";         // 医疗包,官方名称为MedKit,逻辑中为Kit
    std::string Blink ="Transport";     // 闪现,官方名称为Blink,逻辑中为Transport
} const ToolType;

InterpropsType

// 交互道具类型
struct {
    std::string KeyMachine = "KeyMachine";
    std::string Materials = "Materials";
    std::string EscapeCapsule = "EscapeCapsule";
    std::string Elevator = "Elevator";
    std::string Box = "Box";
} const InterpropsType;

枚举量

STATUS

enum STATUS { ALIVE, DEAD, ESCAPED, SKIP, WAIT_FOR_ESCAPE, AI_ERROR};

玩家的游戏状态。

  • ALIVE:存活
  • DEAD:死亡
  • ESCAPED:逃离成功
  • SKIP:回合跳过(踩中粘弹,或者与钥匙机交互后)
  • WAIT_FOR_ESCAPE:逃生等待状态
  • AI_ERROR:ai错误

MapReaderStatus

enum MapReaderStatus { NODE, EDGE, MATERIAL, HMATERIAL, DOOR, ELEVATOR, BLOCK };

读取地图时,表示当前数据段的类型。

  • NODE:节点
  • EDGE:边
  • MATERIAL:陷阱道具
  • HMATERIAL:医疗包
  • ELEVATOR:电梯
  • BLOCK:功能区

结构体

Edge

struct Edge {
  Pos stpos, edpos;
  bool elevator_only;
  Edge() = default;
  Edge(const Pos& s, const Pos& t);
};

地图中的边。

  • stpos, edposPos,起点、终点。
  • elevator_onlybool,是否为用于电梯的虚边,默认false.
  • 构造函数:

  • 默认构造。

  • 由端点构造:

Node

struct Node {
  Pos pos;           
  std::vector<int> playerid;  
  std::vector<std::string> interprops;  
  std::vector<Edge*> edges;   
  bool box = false;           
  bool has_materials = false;   
  int block_turn = INF;           
  bool able = true;                 
  Node() = default;
  Node(const Pos& p) : pos(p) {}
  Node(const Node& another_node);
};

地图中的节点。

  • posPos,节点的坐标。
  • playeridstd::vector<int>,位于该节点的玩家 ID 列表。
  • interpropsstd::vector<std::string>,交互道具类型:
  • "Materials":物资点
  • "KeyMachine":钥匙机
  • "EscapeCapsule": 逃生舱
  • edgesstd::vector<Edge*>,由该点出发的边的列表。
  • boxbool,若该节点上有玩家死亡后的凋落物,则为 true默认false.
  • has_materialsbool,若该节点上有物资点,则为 true默认false.
  • block_turnint,第 block_turn 回合时该节点将被缩圈,默认INF.
  • ablebool,若该节点已经被缩圈,则为 false默认true.
  • 构造函数:
  • 默认构造。
  • 由坐标构造:
  • 拷贝构造。

Tool

struct Tool {
  int kits_num;
  int blinks_num;
  Trapbag trapbag;
};

一个玩家的所有道具。

  • kits_numint,医疗包数量。 -blinks_num:int,闪现道具数量。
  • trapbagTrapbag,陷阱的物品栏。

Player

struct Player {  
  int hp = 200;   
  STATUS status = ALIVE;  
  int id = -1;       
  bool has_entered_escape_layer = false;   
  std::vector<int> keys;  
  Pos pos;            
  Tool toolbag;         
  Player() = default;
  Player(const Player& another_player) = default;
};

玩家类。

  • hpint,血量。
  • statusSTATUS,玩家的游戏状态。
  • idint,玩家的 ID.
  • has_entered_escape_layer: 仅对于别的玩家有意义,对于自己是无意义的,表示是否曾经到达逃生舱那层。
  • keysstd::vector<int>,持有钥匙的列表。
  • posPos,当前坐标。
  • toolbagTool,持有的道具。
  • 构造函数:
  • 默认构造。
  • 拷贝构造。

Map

// 只展示成员变量
struct Map {
  Nodeset nodeset;
  std::vector<Edge> edgeset;
};

地图类。

  • nodesetNodeset,地图中节点的数组。
  • edgesetstd::vector<Edge>,地图中边的数组,默认容量\(1000\).