用户:Syys

来自Botzone Wiki
跳转至: 导航搜索

Amazons 来自Botzone Wiki 跳转至: 导航, 搜索 Amazons(亚马逊棋),是1988年由阿根廷人WalteZamkauska发明的双人棋类游戏,由国际象棋中后的走法衍生而来,属于两人零和完备信息博弈。目前亚马逊棋是ICGA国际机器博弈锦标赛和全国大学生计算机博弈大赛的比赛项目之一。

目录 1 游戏规则 2 游戏交互方式 2.1 具体交互内容 3 游戏样例程序 3.1 C++ 游戏规则 棋盘:由黑白相间的10*10的方格组成,黑方在棋盘左侧,白方在棋盘右侧(坐标从0开始,先x后y) 棋子:每方有4个棋子(4个Amazons),初始位置分别位于(0,3),(3,0),(0,6),(3,9)和(6,0),(9,3),(9,6),(6,9): 1.每个棋子都相当于国际象棋中的皇后,它们的行棋方法与皇后相同,可以在8个方向(上、下、左、右、左上、左下、右上、右下)上任意行走,但不能穿过阻碍 2.当轮到一方行棋时,此方只能而且必须移动4个Amazons中的一个,并在移动完成后,由当前移动的棋子释放一个障碍,障碍的释放方法与棋子的移动方法相同(8个方向,但不能穿过障碍),同样障碍的放置也是必须的 3.当某方完成某次移动后,对方4个棋子均不能再移动时,对方将输掉比赛 4.每次开局位于棋盘左边的玩家(黑方)先手; 5.整个比赛中双方均不能吃掉对方或己方的棋子或障碍 游戏交互方式 本游戏与Botzone上其他游戏一样,使用相同的交互方式:Bot#交互

具体交互内容 每回合Bot收到的request不是字符串,而是一个JSON对象,表示对方落子位置。格式如下:

{
                   "x0": Number, // 起点横坐标
                   "y0": Number, // 起点纵坐标
                   "x1": Number, // 终点横坐标
                   "y1": Number, // 终点纵坐标
                   "x2": Number, // 释放的障碍横坐标
                   "y2": Number  // 释放的障碍纵坐标

} Bot所需要输出的response也是格式相同的JSON对象,表示自己选择移动的棋子的起点、终点和障碍的位置。

如果是黑方的第一回合,则 request 为 {"x0": -1, "y0": -1,"x1":-1,"y1":-1,"x2":-1,"y2":-1}。

游戏样例程序 C++ // 亚马逊棋(Amazons)样例程序

// 随机策略
// 作者:dgf123/syys
// 游戏信息:http://www.botzone.org/games#Amazons
  1. include "stdafx.h"
  2. include
  3. include
  4. include
  5. include
  6. include "jsoncpp/json.h"


  1. define GRIDSIZE 10
  2. define OBSTACLE 2
  3. define judge_black 0
  4. define judge_white 1
  5. define grid_black 1
  6. define grid_white -1

using namespace std;

int currBotColor; // 我所执子颜色(1为黑,-1为白,棋盘状态亦同) int gridInfo[GRIDSIZE][GRIDSIZE] = { 0 }; // 先x后y,记录棋盘状态 int dx[] = { -1,-1,-1,0,0,1,1,1 }; int dy[] = { -1,0,1,-1,1,-1,0,1 };

// 判断是否在地图内 inline bool inMap(int x, int y) { if (x < 0 || x >= GRIDSIZE || y < 0 || y >= GRIDSIZE) return false; return true; }


// 在坐标处落子,检查是否合法或模拟落子 bool ProcStep(int x0, int y0, int x1, int y1, int x2, int y2, int color,bool check_only=true) { if ((!inMap(x0, y0)) || (!inMap(x1, y1)) || (!inMap(x2, y2))) return false; if (gridInfo[x0][y0] != color || gridInfo[x1][y1] != 0) return false; if ((gridInfo[x2][y2] != 0) && !(x2 == x0 && y2 == y0)) return false; if (!check_only) { gridInfo[x0][y0] = 0; gridInfo[x1][y1] = color; gridInfo[x1][y2] = OBSTACLE; } return true; }

int main() { int x0, y0, x1, y1, x2, y2;

// 初始化棋盘 gridInfo[0][3] = gridInfo[3][0] = gridInfo[6][0] = gridInfo[9][3] = grid_black; gridInfo[0][6] = gridInfo[3][9] = gridInfo[6][9] = gridInfo[9][6] = grid_white;

// 读入JSON string str; getline(cin, str); Json::Reader reader; Json::Value input; reader.parse(str, input);

// 分析自己收到的输入和自己过往的输出,并恢复状态 int turnID = input["responses"].size(); currBotColor = input["requests"][(Json::Value::UInt) 0]["x0"].asInt() < 0 ? grid_black : grid_white; // 第一回合收到坐标是-1, -1,说明我是黑方 for (int i = 0; i < turnID; i++) { // 根据这些输入输出逐渐恢复状态到当前回合 x0 = input["requests"][i]["x0"].asInt(); y0 = input["requests"][i]["y0"].asInt(); x1 = input["requests"][i]["x1"].asInt(); y1 = input["requests"][i]["y1"].asInt(); x2 = input["requests"][i]["x2"].asInt(); y2 = input["requests"][i]["y2"].asInt(); if (x0 >= 0) ProcStep(x0, y0, x1, y1, x2, y2, -currBotColor, false); // 模拟对方落子 x0 = input["responses"][i]["x0"].asInt(); y0 = input["responses"][i]["y0"].asInt(); x1 = input["responses"][i]["x1"].asInt(); y1 = input["responses"][i]["y1"].asInt(); x2 = input["responses"][i]["x2"].asInt(); y2 = input["responses"][i]["y2"].asInt(); if (x0 >= 0) ProcStep(x0, y0, x1, y1, x2, y2, currBotColor, false); // 模拟己方落子 }

// 看看自己本回合输入 x0 = input["requests"][turnID]["x0"].asInt(); y0 = input["requests"][turnID]["y0"].asInt(); x1 = input["requests"][turnID]["x1"].asInt(); y1 = input["requests"][turnID]["y1"].asInt(); x2 = input["requests"][turnID]["x2"].asInt(); y2 = input["requests"][turnID]["y2"].asInt(); if (x0 >= 0) ProcStep(x0, y0, x1, y1, x2, y2, -currBotColor, false); // 模拟对方落子 int beginPos[3000][2], possiblePos[3000][2], obstaclePos[3000][2]; int posCount = 0, choice; for (int i = 0; i < GRIDSIZE; ++i) { for (int j = 0; j < GRIDSIZE; ++j) { for (int k = 0; k < 8; ++k) { int xx = i + dx[k]; int yy = j + dy[k]; for (int l = 0; l < 8; ++l) { int xxx = xx + dx[l]; int yyy = yy + dy[l]; if (ProcStep(i, j, xx, yy, xxx, yyy, currBotColor)) { beginPos[posCount][0] = i; beginPos[posCount][1] = j; possiblePos[posCount][0] = xx; possiblePos[posCount][1] = yy; obstaclePos[posCount][0] = xxx; obstaclePos[posCount++][1] = yyy; } } } } }

// 做出决策(你只需修改以下部分)

int startX, startY, resultX, resultY, obstacleX, obstacleY; if (posCount > 0) { srand(time(0)); choice = rand() % posCount; startX = beginPos[choice][0]; startY = beginPos[choice][1]; resultX = possiblePos[choice][0]; resultY = possiblePos[choice][1]; obstacleX = obstaclePos[choice][0]; obstacleY = obstaclePos[choice][1]; } else { startX = -1; startY = -1; resultX = -1; resultY = -1; obstacleX = -1; obstacleY = -1; }

// 决策结束,输出结果(你只需修改以上部分)

Json::Value ret; ret["response"]["x0"] = startX; ret["response"]["y0"] = startY; ret["response"]["x1"] = resultX; ret["response"]["y1"] = resultY; ret["response"]["x2"] = obstacleX; ret["response"]["y2"] = obstacleY; Json::FastWriter writer; cout << writer.write(ret) << endl; return 0; }