Bot

来自Botzone Wiki
Administrator讨论 | 贡献2016年12月28日 (三) 19:43的版本 交互格式
跳转至: 导航搜索

何为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));
	}
}