README 排名评定 游戏教程 安装使用教程 开发指南 Lua接口文档 Python接口文档 C/C++接口文档 地图编辑器说明 自动评测教程

UserAPI使用说明

注:当前C/C++API文档还未更新,可能有部分函数为1.1版本的旧函数,有问题请在群里询问。

概览

`c++ class UserAPI { public:

UserAPI(UserAPI &) = delete;

//禁用构造函数

bool operator=(const UserAPI &) = delete;

//禁用函数符'='重载


static UserAPI &Singleton(lua_State *L = nullptr);

// 初始化一个类成员函数的执行,参数为类名和函数名
void init_func_call(std::string class_name, std::string func_name);

// 执行lua_State栈顶的函数,参数分别为参数个数与返回值个数
void execute_func_call(int param_num = 0, int ret_num = 0);

// 向lua_State中压入一个字符串
void lua_pushstring(std::string str);

// 获取lua表中的元素(可以是函数),两个参数分别为全局表名和数据项名
void get_lua_property(std::string class_name, std::string property_name);
// 执行移动操作(仅列出,不建议使用)
void move_to(VECTOR dest, double moveNum);

// 另一种方式执行移动操作 void movebydirection(VECTOR src, double moveNum, int direction)

// 又一种方式执行移动操作
void move_by_coordinates(VECTOR src, VECTOR dest, double moveNum)  

// 判断两个点是否相连
bool is_connected(int posX1, int posY1, int posX2, int posY2);

// 获取King的位置
VECTOR king_pos();

// 获取当前的step数
int get_current_step();

// 获取当前选中的位置(1.1版本)
VECTOR selected_pos();

// 设置当前选中位置(1.1版本)
void selected_pos(VECTOR pos);
// 获取当前选中的位置(新版)
VECTOR UserAPI::getSelectedPos()

// 设置当前选中位置(新版)
void UserAPI::setSelectedPos(VECTOR pos) 

private:

lua_State *luaState;
UserAPI(lua_State *L) : luaState(L) {}

}; `

部分函数详解

1 .static UserAPI &Singleton

`c++ UserAPI(UserAPI &) = delete; bool operator=(const UserAPI &) = delete;

static UserAPI &Singleton(luaState *L = nullptr) {

static bool has
init = false;
if (!has_init && L == nullptr)
    printf("ERROR: argument lua_State not given for initialization");
static UserAPI singleton(L);
has_init = true;
return singleton;

} `

​ 这个函数用于获取UserAPI单一实例的一个引用,在首次调用时需要传入一个lua_State 指针,此后可以不传。

​ 这是由于一次游戏中,用户只有一份SDK,因此我们使用单一实例模式来进行实现。用户调用Singleton()可以获取一份SDK实例。注意,在第一次调用时,需要用户手动提供lua_State指针来初始化SDK。这里提供了一份最小的userMain()实现

`C++ static int userMain(lua_State *luaState) { UserAPI &API = UserAPI::Singleton(luaState); // 初始化并获取单例 // ... return 0; // 必须返回0作为参数(代表正确退出),否则程序会崩溃 } `

​ 有关单例模式详细情况请查看此博客

2 .initfunccall

`c++ void init_func_call(std::string class_name, std::string func_name) { lua_getglobal(luaState, class_name.c_str()); if (!lua_istable(luaState, -1)) throw "AI SDK -- not a table error"; lua_pushstring(func_name); lua_gettable(luaState, -2); } `

​ 这个接口主要用于初始化调用 对接的lua文件中存在的. 表结构成员函数

​ 例如:

`c++ void selected_pos(VECTOR pos) { init_func_call("AI_SDK", "setSelected"); ...... } `

​ 对应lua文件中的表叫做"AI_SDK",表中有一个函数叫"setSelected",调用此接口对函数初始化以使用此函数。

3 .executefunccal

`c++ void execute_func_call(int param_num = 0, int ret_num = 0) { int iRet = lua_pcall(luaState, param_num, ret_num, 0); if (iRet) { throw lua_tostring(luaState, -1); } } `

​ 这个接口用于执行luaState栈顶的函数,参数paramnum和retnum分别为参数个数与返回值个数。具体的过程由luapcall函数执行,此函数会执行栈顶的函数,若执行过程中出现错误,则会返回一个非0值。此时我们用抛出异常函数throw将其抛出,以待之后处理。

4 .lua_pushstring

`c++ void lua_pushstring(std::string str) { ::lua_pushstring(luaState, str.c_str()); } `

​ 这个接口用于向lua_State中压入一个字符串。

5 .getluaproperty

`c++ void get_lua_property(std::string class_name, std::string property_name) { lua_getglobal(luaState, class_name.c_str()); if (!lua_istable(luaState, -1)) { std::cout << "Error: not a table" << std::endl; throw "not a table" + class_name; } lua_getfield(luaState, -1, property_name.c_str()); } `

​ 这个接口用于获取lua表中的元素(可以是函数),两个参数分别为全局表名和数据项名

6 .move_to

`c++ void move_to(VECTOR dest, double moveNum) { init_func_call("AI_SDK", "MoveTo"); lua_pushnumber(luaState, dest.x); lua_pushnumber(luaState, dest.y); lua_pushnumber(luaState, moveNum); execute_func_call(3); } `

​ 这是移动军队的接口,( dest.x , dest.y )为目标点坐标,用户调用moveTo函数之前需要提前用函数selected_pos设定好选中的点。

​ moveNum为移动兵力,其中,其值为0时只在原地留一个士兵;大于1时移动其值数量的兵力;小于1时按比例移动,如0.5为移动一半。

使用示例:

`C++ UserAPI &API = UserAPI::Singleton(); double x , y , x1 , y1 ; // 分别设置选中位置和目标位置 ... // 赋值 API.selected_pos() = {x, y}; // 设置现在选中位置 API.move_to({x1, y1}, 0.5); // 执行移动操作,从(x,y)–>(x1,y1),移动(x,y)一半的兵力 `

7 .movebydirection

`c++ void move_by_direction(VECTOR src, double moveNum, int direction) { init_func_call("AI_SDK", "MoveByDirection"); lua_pushnumber(luaState, src.x); lua_pushnumber(luaState, src.y); lua_pushnumber(luaState, moveNum); lua_pushnumber(luaState, direction); execute_func_call(4); } `

​ 这个函数是对moveTo的封装,用户调用此函数时只需传入起始点坐标src,移动兵力moveNum和方向direction(正六边形自右上边顺时针方向分别为1~6)。moveNum参考moveTo中的moveNum。

8 .movebycoordinates

`c++ void move_by_coordinates(VECTOR src, VECTOR dest, double moveNum) { init_func_call("AI_SDK", "MoveByCoordinates"); lua_pushnumber(luaState, src.x); lua_pushnumber(luaState, src.y); lua_pushnumber(luaState, dest.x); lua_pushnumber(luaState, dest.y); lua_pushnumber(luaState, moveNum); execute_func_call(5); } `

​ 这个函数是对moveTo的封装,用户调用此函数时只需传入起始点坐标src,终点坐标dest和移动兵力。

9 .is_connected

`c++ bool is_connected(int posX1, int posY1, int posX2, int posY2) { ... } `

​ 这个接口用于判断两个选定坐标的格子(X1,Y1)与(X2,Y2)是否相邻。

10.king_pos

`c++ VECTOR king_pos() { get_lua_property("AI_SDK", "KingPos"); if (!lua_istable(luaState, -1)) { throw "not a table: KingPos"; } lua_getfield(luaState, -1, "x"); int x = lua_tonumber(luaState, -1); lua_getfield(luaState, -2, "y"); int y = lua_tonumber(luaState, -1); return {x, y}; } `

​ 这个接口用于获取王的位置,返回的是一个形式为{ X , Y }的VECTOR变量。

11.getcurrentstep

`c++ int get_current_step() { get_lua_property("ReplayGame", "step"); return lua_tonumber(luaState, -1); } `

​ 这个接口用于获取当前的步数。

12.selected_pos(1.1版本)

`c++ VECTOR selected_pos() { get_lua_property("AI_SDK", "SelectPos"); if (!lua_istable(luaState, -1)) { throw "not a table: SelectPos"; } lua_getfield(luaState, -1, "x"); int x = lua_tonumber(luaState, -1); lua_getfield(luaState, -2, "y"); int y = lua_tonumber(luaState, -1); return {x, y}; } `

​ 这个接口用于获取选中点的位置,返回的是一个形式为{ X , Y }的VECTOR变量。

13.getSelectedPos(新版)

`c++ VECTOR UserAPI::getSelectedPos() { ... return {x, y}; } `

这个接口用于获取选中点的位置,返回的是一个形式为{ X , Y }的VECTOR变量。
14.selected_pos(1.1版)

`c++ void selected_pos(VECTOR pos) { ... } `

​ 这个接口用于将当前传入的点pos设置为选中状态,一般与moveto配合使用,不用moveto可以不关注。

15.setSelectedPos(新版)

`c++ void UserAPI::setSelectedPos(VECTOR pos) { ... } `

这个接口用于将当前传入的点pos设置为选中状态,一般与moveto配合使用,不用moveto可以不关注。