Bot
来自Botzone Wiki
何为Bot
Bot是Botzone上用户提交的程序,具有一定的人工智能,可以根据已有的游戏规则跟其他的Bot或人类玩家进行对抗。
支持的语言
Bot可以用以下语言编写:
- C/C++(平台上编译时会定义
_BOTZONE_ONLINE
宏) - Java
- JavaScript
- python
- Pascal
交互
Bot的每次生命周期均为一次输入、一次输出,每次输入会包括该Bot以往跟平台的所有交互内容。交互格式为单行JSON。
因此,Bot的程序运行流程应当是:
- 启动程序
- 从平台获取JSON数据
- 根据获得的JSON数据进行计算
- 根据以往自己的输入输出恢复到最新状态
- 根据本次输入给出本次的决策输出
- 输出结果以及保存信息
- 关闭程序
资源限制
如果没有特别指出,每次运行,平台都要求程序在 1秒 内结束、使用的内存在 256 MB 内。
由于不同语言运行效率有别,我们对不同语言的时限也有不同的调整。
- C/C++:1倍
- Java:3倍
- JavaScript:2倍
- python:3倍
- Pascal:1倍
交互格式
Bot 输入
{
"requests" : [
"Judge request in Turn 1", // 第 1 回合从平台获取的信息
"Judge request in Turn 2", // 第 2 回合从平台获取的信息
...
],
"responses" : [
"Bot response in Turn 1", // 第 1 回合输出的信息
"Bot response in Turn 2", // 第 2 回合输出的信息
...
],
"data" : "saved data", // 上回合保存的信息,最大长度为100KB
"globaldata" : "globally saved data", // 来自上次对局的、Bot全局保存的信息,最大长度为100KB
"time_limit" : "", // 时间限制
"memory_limit" : "" // 内存限制
}
Bot输出
{
"response" : "response msg", // 此回合的输出信息
"debug" : "debug info", // 调试信息,将被写入log,最大长度为1KB
"data" : "saved data" // 此回合的保存信息,将在下回合输入
"globaldata" : "globally saved data" // Bot的全局保存信息,将会在下回合输入,对局结束后也会保留,下次对局可以继续利用
}
样例程序
以下给出C++、Java和JavaScript的交互样例程序:
C++
本地编译的方式请查看 JSONCPP。
#include <iostream>
#include <string>
#include <sstream>
#include "jsoncpp/json.h" // C++编译时默认包含此库
using namespace std;
int main()
{
// 读入JSON
string str;
getline(cin, str);
Json::Reader reader;
Json::Value input;
reader.parse(str, input);
// 分析自己收到的输入和自己过往的输出,并恢复状态
string data = input["data"].asString(); // 该对局中,以前该Bot运行时存储的信息
int turnID = input["responses"].size();
for (int i = 0; i < turnID; i++)
{
istringstream in(input["requests"][i].asString()),
out(input["responses"][i].asString());
// 根据这些输入输出逐渐恢复状态到当前回合
}
// 看看自己本回合输入
istringstream in(input["requests"][turnID].asString());
// 做出决策存为myAction
// 输出决策JSON
Json::Value ret;
ret["response"] = myAction;
ret["data"] = myData; // 可以存储一些前述的信息,在整个对局中使用
Json::FastWriter writer;
cout << writer.write(ret) << endl;
return 0;
}
JavaScript
// 初始化标准输入流
process.stdin.resume();
process.stdin.setEncoding('utf8');
var fullInput = "";
// 收到一个输入片段
process.stdin.on('data', function (chunk) {
fullInput += chunk;
});
// 输入全部结束
process.stdin.on('end', function () {
// 解析读入的JSON
var input = JSON.parse(fullInput);
var data = input.data; // 该对局中,以前该Bot运行时存储的信息
// 分析自己收到的输入和自己过往的输出,并恢复状态
for (var i = 0; i < input.responses.length; i++) {
var myInput = input.requests[i], myOutput = input.responses[i];
// 根据这些输入输出逐渐恢复状态到当前回合
}
// 看看自己本回合输入
var currInput = input.requests[input.requests.length - 1];
// 作出决策并输出
console.log(JSON.stringify({
response: myAction,
data: myData // 可以存储一些前述的信息,在整个对局中使用
}));
});
Java
本地编译的方式请查看 JSON.simple。
import java.util.*;
import org.json.simple.JSONValue; // Java 库中自动包含此库
class Main { // 注意!!类名""必须""为 Main,且不要有package语句,但上传的 java 代码文件名可以任意
static class SomeClass {
// 如果要定义类,请使用 static inner class
}
public static void main(String[] args) {
String input = new Scanner(System.in).nextLine();
Map<String, List> inputJSON = (Map) JSONValue.parse(input);
// 下面的 TYPE 为单条 response / request 类型,有较大可能为 Map<String, Long> 或 String
List<TYPE> requests = inputJSON.get("requests");
List<TYPE> responses = inputJSON.get("responses");
for (TYPE rec : requests) {
// 处理一下
}
for (TYPE rec : responses) {
// 再处理一下
}
// 这边运算得出一个 output,注意类型也为 TYPE
Map<String, TYPE> outputJSON = new HashMap();
outputJSON.put("response", output);
System.out.print(JSONValue.toJSONString(outputJSON));
}
}