“Kingz”的版本间的差异
(样例程序) |
(→C++ JSON交互样例程序) |
||
第153行: | 第153行: | ||
#include <cstring> | #include <cstring> | ||
#include "jsoncpp/json.h" | #include "jsoncpp/json.h" | ||
+ | |||
#define ind Json::Value::ArrayIndex | #define ind Json::Value::ArrayIndex | ||
using namespace std; | using namespace std; | ||
int currBotColor; // 正在等待输出结果的BOT | int currBotColor; // 正在等待输出结果的BOT | ||
− | int troop[10][10]={0},tr[3][10][10]; | + | int troop[10][10] = {0}, tr[3][10][10]; |
− | int info[10][10]={0}; //-1障碍 0空地 1堡垒 2基地 | + | int info[10][10] = {0}; //-1障碍 0空地 1堡垒 2基地 |
− | int col[10][10]={0}; //0无, 1黑, 2白 | + | int col[10][10] = {0}; //0无, 1黑, 2白 |
− | int dx[5]={-1,1,0,0,0},dy[5]={0,0,-1,1,0}; | + | int dx[5] = {-1, 1, 0, 0, 0}, dy[5] = {0, 0, -1, 1, 0}; |
− | int ran(int n){return rand()%n;} | + | int ran(int n) { return rand() % n; } |
− | void fight(int &x,int &y,int &z) | + | void fight(int &x, int &y, int &z) { |
− | { | + | int m = min(x, y); |
− | int m=min(x,y); | + | x -= m; |
− | x-=m;y-=m; | + | y -= m; |
− | if (x>0) | + | if (x > 0) { |
− | + | m = min(x, z); | |
− | m=min(x,z); | + | x -= m; |
− | x-=m;z-=m; | + | z -= m; |
− | } | + | } else if (y > 0) { |
− | + | m = min(y, z); | |
− | + | y -= m; | |
− | m=min(y,z); | + | z -= m; |
− | y-=m;z-=m; | ||
} | } | ||
} | } | ||
− | int main() | + | int main() { |
− | { | ||
string str; | string str; | ||
getline(cin, str); | getline(cin, str); | ||
Json::Reader reader; | Json::Reader reader; | ||
− | Json::Value input,output,gr,req,res,nreq,nres; | + | Json::Value input, output, gr, req, res, nreq, nres; |
− | reader.parse(str, input);req=input["requests"];res=input["responses"]; | + | reader.parse(str, input); |
− | + | req = input["requests"]; | |
+ | res = input["responses"]; | ||
+ | |||
//初始化棋盘 | //初始化棋盘 | ||
− | int turn=req.size(); | + | int turn = req.size(); |
− | gr=req[(ind)0]; | + | gr = req[(ind) 0]; |
− | for (int i=0;i<10;i++) | + | for (int i = 0; i < 10; i++) |
− | + | for (int j = 0; j < 10; j++) { | |
− | + | troop[i][j] = gr[i * 10 + j].asInt(); | |
− | + | if (troop[i][j] == -1) info[i][j] = -1; | |
− | + | else if (troop[i][j] == 0) info[i][j] = 0; | |
− | + | else info[i][j] = 1; | |
− | + | } | |
− | + | int bgx = gr[100].asInt(), bgy = gr[101].asInt(); | |
− | int bgx=gr[100].asInt(),bgy=gr[101].asInt(); | + | info[bgx][bgy] = 2; |
− | info[bgx][bgy]=2;col[bgx][bgy]=1;//cerr<<"gggg "<<bgx<<' '<<bgy<<' '<<troop[bgx][bgy]<<endl; | + | col[bgx][bgy] = 1;//cerr<<"gggg "<<bgx<<' '<<bgy<<' '<<troop[bgx][bgy]<<endl; |
− | info[9-bgx][9-bgy]=2;col[9-bgx][9-bgy]=2; | + | info[9 - bgx][9 - bgy] = 2; |
− | + | col[9 - bgx][9 - bgy] = 2; | |
+ | |||
//计算当前棋盘 | //计算当前棋盘 | ||
− | for (int t=1;t<turn;t++) | + | for (int t = 1; t < turn; t++) { |
− | + | nres = res[t - 1]; | |
− | nres=res[t-1]; | + | nreq = req[t]; |
− | nreq=req[t]; | + | int x1 = nres[(ind) 0].asInt(), y1 = nres[(ind) 1].asInt(), w1 = nres[(ind) 2].asInt(), dir1 = nres[(ind) 3].asInt(); |
− | int x1=nres[(ind)0].asInt(),y1=nres[(ind)1].asInt(),w1=nres[(ind)2].asInt(),dir1=nres[(ind)3].asInt(); | + | int x2 = nreq[(ind) 0].asInt(), y2 = nreq[(ind) 1].asInt(), w2 = nreq[(ind) 2].asInt(), dir2 = nreq[(ind) 3].asInt(); |
− | int x2=nreq[(ind)0].asInt(),y2=nreq[(ind)1].asInt(),w2=nreq[(ind)2].asInt(),dir2=nreq[(ind)3].asInt(); | + | |
− | |||
//处理移动 | //处理移动 | ||
− | memset(tr,0,sizeof(tr)); | + | memset(tr, 0, sizeof(tr)); |
− | for (int i=0;i<10;i++) for (int j=0;j<10;j++) if (troop[i][j]>=0) tr[col[i][j]][i][j]=troop[i][j]; | + | for (int i = 0; i < 10; i++) |
− | tr[1][x1][y1]-=w1;tr[1][x1+dx[dir1]][y1+dy[dir1]]+=w1; | + | for (int j = 0; j < 10; j++) |
− | tr[2][x2][y2]-=w2;tr[2][x2+dx[dir2]][y2+dy[dir2]]+=w2; | + | if (troop[i][j] >= 0)tr[col[i][j]][i][j] = troop[i][j]; |
− | for (int i=0;i<10;i++) for (int j=0;j<10;j++) | + | tr[1][x1][y1] -= w1; |
− | + | tr[1][x1 + dx[dir1]][y1 + dy[dir1]] += w1; | |
− | + | tr[2][x2][y2] -= w2; | |
− | + | tr[2][x2 + dx[dir2]][y2 + dy[dir2]] += w2; | |
− | + | for (int i = 0; i < 10; i++) | |
− | + | for (int j = 0; j < 10; j++) { | |
− | + | fight(tr[0][i][j], tr[1][i][j], tr[2][i][j]); | |
− | + | troop[i][j] = tr[0][i][j] + tr[1][i][j] + tr[2][i][j]; | |
− | + | if (tr[0][i][j]) col[i][j] = 0; | |
+ | else if (tr[1][i][j]) col[i][j] = 1; | ||
+ | else if (tr[2][i][j]) col[i][j] = 2; | ||
+ | } | ||
+ | |||
//处理驻军增加 | //处理驻军增加 | ||
− | for (int i=0;i<10;i++) | + | for (int i = 0; i < 10; i++) |
− | + | for (int j = 0; j < 10; j++) { | |
− | + | if ((info[i][j] == 0) && (t % 8 == 0) && (col[i][j] != 0)) | |
− | + | troop[i][j]++; | |
− | + | if ((info[i][j] == 1) && (t % 2 == 0) && (col[i][j] != 0)) | |
− | + | troop[i][j]++; | |
− | + | if (info[i][j] == 2) troop[i][j]++; | |
+ | } | ||
} | } | ||
− | + | ||
//srand(time(NULL)); | //srand(time(NULL)); | ||
− | int mx=-1,xx,yy,ww,dd; | + | int mx = -1, xx, yy, ww, dd; |
− | for (int x=0;x<10;x++) | + | for (int x = 0; x < 10; x++) |
− | + | for (int y = 0; y < 10; y++) | |
− | + | if ((col[x][y] == 1) && (troop[x][y] > 1)) | |
− | + | for (int dir = 0; dir <= 4; dir++) { | |
− | + | int w = troop[x][y] - 1, tx = x + dx[dir], ty = y + dy[dir]; | |
− | + | if ((tx < 0) || (tx >= 10) || (ty < 0) || (ty >= 10) || | |
− | + | (info[tx][ty] == -1)) | |
− | + | continue; | |
− | + | int score = 0; | |
− | + | if (w > troop[tx][ty]) { | |
− | + | if (col[tx][ty] == 2) score += 3; | |
− | + | if (info[tx][ty] == 1) score += 2; | |
− | + | if ((info[tx][ty] == 2) && (col[tx][ty] == 2)) score += 4; | |
− | + | } | |
− | + | if (score > mx) { | |
− | + | mx = score; | |
− | output[(ind)0]=xx;output[(ind)1]=yy;output[(ind)2]=ww;output[(ind)3]=dd; | + | xx = x; |
− | + | yy = y; | |
+ | ww = w; | ||
+ | dd = dir; | ||
+ | } | ||
+ | else if ((score == mx) && (ran(5) == 0)) { | ||
+ | mx = score; | ||
+ | xx = x; | ||
+ | yy = y; | ||
+ | ww = w; | ||
+ | dd = dir; | ||
+ | } | ||
+ | } | ||
+ | output[(ind) 0] = xx; | ||
+ | output[(ind) 1] = yy; | ||
+ | output[(ind) 2] = ww; | ||
+ | output[(ind) 3] = dd; | ||
+ | |||
Json::FastWriter writer; | Json::FastWriter writer; | ||
− | cout<<writer.write(output)<<endl; | + | cout << writer.write(output) << endl; |
} | } | ||
</syntaxhighlight> | </syntaxhighlight> |
2020年1月12日 (日) 16:34的版本
目录
作者
裁判程序 yx_lu 播放器 zball
故事
没有。
人类玩家操作说明
当前的人类玩家操作仅仅是可用状态。
点击一个所属格,在底下对应的输入框中会填入坐标,分散兵力数(第二个输入框)会改为该格子兵力数-1。第三个输入框可以输入方向,可以将光标移到这个输入框后输入方向键。点击 go 按钮发送一次移动。
游戏规则
本游戏为双人回合制游戏,两个玩家是对抗关系。
两名玩家分别是:0 号玩家(红方),1 号玩家(蓝方)。
每个玩家控制一片土地,土地的每个格子驻兵,土地根据其类型会以一定的速度使其上面的兵力增长。玩家可以移动兵力、抵消兵力,最后推平对方基地者获胜。
地图和物件
地图是 10×10 的矩阵,初始状态是中心对称的。每个格子可以是基地、堡垒、空地或者障碍,障碍格子无法通过。在程序中,坐标是 (x,y) 的形式,为了照顾按行储存的编程习惯,x是纵坐标,y是横坐标;左上角是 (0,0), 右下角是 (9,9). 基地红蓝双方各有一个。
初始的地图中会随机分布着一些堡垒,每个堡垒中会存在固定数量的不变的中立兵,在占领堡垒时需要抵消这一部分兵力。
对于地图上的每一个格子,所属可能有三种情况:红方、蓝方、中立。如果一个格子有红蓝中某一方的驻兵,则属于此方,否则中立。
操作
每回合玩家的操作是一个四元组 (x,y,w,d), 其中 (x,y) 是起始点的坐标,w 是移动的兵力数,d 是移动方向。w 需要小于 (x,y) 格子这个玩家的驻兵数。对于这个操作,玩家会将 (x,y) 格子所属的 w 兵力向 d 方向移动一格,移动中可能会发生战斗。
d | 方向 |
---|---|
0 | 向上移动 |
1 | 向下移动 |
2 | 向左移动 |
3 | 向右移动 |
4 | 一动不动 |
战斗
1. 如果红蓝双方同时向同一个各自移动了 w1, w2 兵力,则 w1 和 w2 会先做差,其中更大的一方参与后续的战斗(但是兵力数减去了另一方的兵力数)。如果一样大则不会参与 2. 的战斗。
2. 接下来会和当地的原有驻兵发生战斗:这方的兵力会和当地兵力做差,其中更大的一方占领这片地,而兵力数减去另一方的兵力。如果一样大则这块地变为无所属的地,上面没有兵力。
兵力增长
兵力增长会发生在回合结束(战斗完成)后。基地每回合兵力增长 1, 堡垒每两回合兵力增长 1(当堡垒被红蓝中的一方占领时才会增长), 空地每八回合兵力增长 1.
判定流程
在游戏开始时裁判程序将向双方发放本方基地地址。
每个回合将依次执行以下动作:
- 裁判程序向双方发放当前局面所有信息。
- 两方分别作出移动决策。
- 裁判程序计算所有移动后发生的驻军战斗以及战斗后的归属转变。
- 判程序计算驻军生成。
胜负
一切非法行为会被立即判负,包括程序崩溃,超时,坐标越界,格式错误,非法操作等。
基地被对方控制的一方会被判负。
双方同时判负会被认定为平局。
在游戏的第 1024 (待定)回合结束后若仍未结束,将按照双方驻军总和判定胜负。驻军总和少的一方被判负,若相等则为平局。
地图生成
游戏开始前裁判程序将生成地图,生成的地图保证:
- 游戏场地为 10×10 的方形场地,地图的所有物件及驻军初始都呈中心对称。
- 堡垒初始驻军不超过 256。
- 双方基地四联通。
游戏交互方式
与Botzone上其他游戏不一样,本游戏每步(每次程序运行)限时0.1秒。具体规则请参看Bot词条或提交程序处的提示。
如果希望在回合间传递数据,请参阅Bot#交互。
提示
如果你不能理解以下交互方式,可以直接看#样例程序,从 main
函数开始修改
本游戏与Botzone上其他游戏一样,使用相同的交互方式:Bot#交互。
本游戏只支持JSON交互。
调试时可以通过拖动进度条来快速调试。
JSON交互
每回合Bot收到的request不是字符串,而是一个JSON数组或对象,格式如下:
第一回合
[ tr00, ... , tr99, x, y ]
/* tr00 到 tr99 是按行储存的地图,
-1表示是障碍格,0表示空地,
非零值表示有驻军的堡垒或基地。
(x,y) 表示基地的坐标。*/
其他回合
[x,y,w,d] //含义同 操作 所述,表示对方上回合的操作
Bot所需要输出的response也是JSON数组,格式如下:
[x,y,w,d] //含义同 操作 所述
样例程序
建议仔细阅读样例程序的注释。
请注意展开按钮在右侧!-----=====≡≡≡≡≡>
C++ JSON交互样例程序
本地编译和调试的方式请查看 JSONCPP。
// Kingz 游戏样例程序
// 最后更新于2020-1-10 1:54:27
// 随机策略
// 作者:yx_lu
// https://botzone.org.cn/game/Kingz
#include <iostream>
#include <sstream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include "jsoncpp/json.h"
#define ind Json::Value::ArrayIndex
using namespace std;
int currBotColor; // 正在等待输出结果的BOT
int troop[10][10] = {0}, tr[3][10][10];
int info[10][10] = {0}; //-1障碍 0空地 1堡垒 2基地
int col[10][10] = {0}; //0无, 1黑, 2白
int dx[5] = {-1, 1, 0, 0, 0}, dy[5] = {0, 0, -1, 1, 0};
int ran(int n) { return rand() % n; }
void fight(int &x, int &y, int &z) {
int m = min(x, y);
x -= m;
y -= m;
if (x > 0) {
m = min(x, z);
x -= m;
z -= m;
} else if (y > 0) {
m = min(y, z);
y -= m;
z -= m;
}
}
int main() {
string str;
getline(cin, str);
Json::Reader reader;
Json::Value input, output, gr, req, res, nreq, nres;
reader.parse(str, input);
req = input["requests"];
res = input["responses"];
//初始化棋盘
int turn = req.size();
gr = req[(ind) 0];
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++) {
troop[i][j] = gr[i * 10 + j].asInt();
if (troop[i][j] == -1) info[i][j] = -1;
else if (troop[i][j] == 0) info[i][j] = 0;
else info[i][j] = 1;
}
int bgx = gr[100].asInt(), bgy = gr[101].asInt();
info[bgx][bgy] = 2;
col[bgx][bgy] = 1;//cerr<<"gggg "<<bgx<<' '<<bgy<<' '<<troop[bgx][bgy]<<endl;
info[9 - bgx][9 - bgy] = 2;
col[9 - bgx][9 - bgy] = 2;
//计算当前棋盘
for (int t = 1; t < turn; t++) {
nres = res[t - 1];
nreq = req[t];
int x1 = nres[(ind) 0].asInt(), y1 = nres[(ind) 1].asInt(), w1 = nres[(ind) 2].asInt(), dir1 = nres[(ind) 3].asInt();
int x2 = nreq[(ind) 0].asInt(), y2 = nreq[(ind) 1].asInt(), w2 = nreq[(ind) 2].asInt(), dir2 = nreq[(ind) 3].asInt();
//处理移动
memset(tr, 0, sizeof(tr));
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
if (troop[i][j] >= 0)tr[col[i][j]][i][j] = troop[i][j];
tr[1][x1][y1] -= w1;
tr[1][x1 + dx[dir1]][y1 + dy[dir1]] += w1;
tr[2][x2][y2] -= w2;
tr[2][x2 + dx[dir2]][y2 + dy[dir2]] += w2;
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++) {
fight(tr[0][i][j], tr[1][i][j], tr[2][i][j]);
troop[i][j] = tr[0][i][j] + tr[1][i][j] + tr[2][i][j];
if (tr[0][i][j]) col[i][j] = 0;
else if (tr[1][i][j]) col[i][j] = 1;
else if (tr[2][i][j]) col[i][j] = 2;
}
//处理驻军增加
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++) {
if ((info[i][j] == 0) && (t % 8 == 0) && (col[i][j] != 0))
troop[i][j]++;
if ((info[i][j] == 1) && (t % 2 == 0) && (col[i][j] != 0))
troop[i][j]++;
if (info[i][j] == 2) troop[i][j]++;
}
}
//srand(time(NULL));
int mx = -1, xx, yy, ww, dd;
for (int x = 0; x < 10; x++)
for (int y = 0; y < 10; y++)
if ((col[x][y] == 1) && (troop[x][y] > 1))
for (int dir = 0; dir <= 4; dir++) {
int w = troop[x][y] - 1, tx = x + dx[dir], ty = y + dy[dir];
if ((tx < 0) || (tx >= 10) || (ty < 0) || (ty >= 10) ||
(info[tx][ty] == -1))
continue;
int score = 0;
if (w > troop[tx][ty]) {
if (col[tx][ty] == 2) score += 3;
if (info[tx][ty] == 1) score += 2;
if ((info[tx][ty] == 2) && (col[tx][ty] == 2)) score += 4;
}
if (score > mx) {
mx = score;
xx = x;
yy = y;
ww = w;
dd = dir;
}
else if ((score == mx) && (ran(5) == 0)) {
mx = score;
xx = x;
yy = y;
ww = w;
dd = dir;
}
}
output[(ind) 0] = xx;
output[(ind) 1] = yy;
output[(ind) 2] = ww;
output[(ind) 3] = dd;
Json::FastWriter writer;
cout << writer.write(output) << endl;
}