黑白棋样例程序及注释解析(无决策算法)
来源:互联网 发布:安庆网络问政平台新版 编辑:程序博客网 时间:2024/05/19 03:46
// 黑白棋(Reversi)样例程序 // 随机策略 // 作者:zhouhy // 游戏信息:http://www.botzone.org/games#Reversi #include <iostream> #include <string> #include <cstdlib> #include <ctime> #include "jsoncpp/json.h" // C++编译时默认包含此库 using namespace std; int currBotColor; // 我所执子颜色(1为黑,-1为白,棋盘状态亦同) int gridInfo[8][8] = { 0 }; // 先x后y,记录棋盘状态 int blackPieceCount = 2, whitePieceCount = 2; // 向Direction方向改动坐标,并返回是否越界 这个是八个方向上的 inline bool MoveStep(int &x, int &y, int Direction) //注意:这里调用一次move,x,y也相应移动了一步 { if (Direction == 0 || Direction == 6 || Direction == 7) x++; if (Direction == 0 || Direction == 1 || Direction == 2) y++; if (Direction == 2 || Direction == 3 || Direction == 4) x--; if (Direction == 4 || Direction == 5 || Direction == 6) y--; if (x < 0 || x > 7 || y < 0 || y > 7) return false; return true; } // 在坐标处落子,检查是否合法(八个方向有一个方向是可以夹住对方子的)或模拟落子 bool ProcStep(int xPos, int yPos, int color, bool checkOnly = false) { int effectivePoints[8][2]; int dir, x, y, currCount; bool isValidMove = false; //是否是合法的移动 if (gridInfo[xPos][yPos] != 0) //如果棋盘上这个位置有子,下面都是这个地方没字的情况 return false; //返回不合法 for (dir = 0; dir < 8; dir++) // 这里遍历八个方向,每次搞一个方向 搞一圈下来把所有方向上面的夹住的对方的棋子保存在effectivePoints上 { x = xPos; y = yPos; currCount = 0; while (1) { if (!MoveStep(x, y, dir))//朝着一个方向上移动判断是否超界,边界就break, 每while一次都会往dir方向前进一步 { currCount = 0; break; } if (gridInfo[x][y] == -color) //移动一下还是对方棋子那就对方棋子个数加1,把对方的个数和位置记下来保存到effectivePoints数组上 { currCount++; //数字就加一 effectivePoints[currCount][0] = x; effectivePoints[currCount][1] = y; } else if (gridInfo[x][y] == 0) //没有棋子 { currCount = 0; break; } else //这种情况指的是这个棋子是我方,那么计数器就不置0了,直接跳出,这时已经是我方棋子夹住了currCount多的敌方棋子 { break; } } if (currCount != 0) { isValidMove = true; //如果八个方向只要有一个方向使对方子可以反转的,这步棋就是可以的 if (checkOnly) //如果只是检查这步是否合法就返回合法,下面的不进行反转操作 return true; if (color == 1) //如果是黑棋 { blackPieceCount += currCount; whitePieceCount -= currCount; //改变黑白棋子个数 } else //白棋 { whitePieceCount += currCount; blackPieceCount -= currCount; } while (currCount > 0) //这里把加在中间的对方棋子翻转过去 { x = effectivePoints[currCount][0]; y = effectivePoints[currCount][1]; gridInfo[x][y] *= -1; currCount--; } } } if (isValidMove) //如果这个地方是合法的坐标,那么下面就对这盘棋的黑白进行改变+1 { gridInfo[xPos][yPos] = color; if (color == 1) blackPieceCount++; else whitePieceCount++; return true; } else return false; } // 检查color方有无合法棋步 bool CheckIfHasValidMove(int color) { int x, y; for (y = 0; y < 8; y++) for (x = 0; x < 8; x++) if (ProcStep(x, y, color, true)) // 坐标处的落子,检查是否合法 return true; //都合法才返回合法真 return false; //有一个不合法就返回不合法假 } int main() { int x, y; // 初始化棋盘 gridInfo[3][4] = gridInfo[4][3] = 1; //|白|黑| gridInfo[3][3] = gridInfo[4][4] = -1; //|黑|白| // 读入JSON string str; getline(cin, str); Json::Reader reader; Json::Value input; //三维,保存n个回合双方的棋子坐标 reader.parse(str, input); // 分析自己收到的输入和自己过往的输出,并恢复状态 int turnID = input["responses"].size();//大概就是第几回合的意思 currBotColor = input["requests"][(Json::Value::UInt) 0]["x"].asInt() < 0 ? 1 : -1; // 第一回合收到坐标是-1, -1,说明我是黑方 for (int i = 0; i < turnID; i++) //以往回合的落子信息已经保存到全局变量gridInfo里面了 { // 根据这些输入输出逐渐恢复状态到当前回合 x = input["requests"][i]["x"].asInt(); y = input["requests"][i]["y"].asInt(); if (x >= 0) ProcStep(x, y, -currBotColor); // 模拟对方落子 x = input["responses"][i]["x"].asInt(); y = input["responses"][i]["y"].asInt(); if (x >= 0) ProcStep(x, y, currBotColor); // 模拟己方落子 } // 看看自己本回合输入 x = input["requests"][turnID]["x"].asInt(); y = input["requests"][turnID]["y"].asInt(); if (x >= 0) ProcStep(x, y, -currBotColor); // 模拟对方落子 // 找出合法落子点 int possiblePos[64][2], posCount = 0, choice; for (y = 0; y < 8; y++) for (x = 0; x < 8; x++) //遍历棋盘找出可以落子的点, if (ProcStep(x, y, currBotColor, true)) { possiblePos[posCount][0] = x; possiblePos[posCount++][1] = y; } // 做出决策(你只需修改以下部分) int resultX, resultY; if (posCount > 0) { srand(time(0)); choice = rand() % posCount; resultX = possiblePos[choice][0]; resultY = possiblePos[choice][1]; } else { resultX = -1; resultY = -1; } // 决策结束,输出结果(你只需修改以上部分) Json::Value ret; ret["response"]["x"] = resultX; ret["response"]["y"] = resultY; Json::FastWriter writer; cout << writer.write(ret) << endl; //这是电脑上的决定 return 0; }
阅读全文
0 0
- 黑白棋样例程序及注释解析(无决策算法)
- 课程设计 黑白棋算法
- 黑白棋(game)
- 枚举(黑白棋)
- 黑白棋(博弈论)
- 黑白棋(落子)
- 黑白棋(aphabeta剪枝算法的应用)带界面
- 黑白棋判定稳定子的算法
- 黑白棋
- 黑白棋
- 黑白棋
- 黑白棋
- 黑白棋
- 黑白棋
- 黑白棋
- 黑白棋
- 黑白棋
- 黑白棋
- Java util包中的Random类
- 简单的封装Activity与fragement类
- header_banner.xml
- 蓝桥杯--马虎的算式
- item01.xml
- 黑白棋样例程序及注释解析(无决策算法)
- 拼写错误
- Hololens官方教程精简版
- [Python]使用TuShare能获取到哪些信息?
- item02.xml
- 内存的战争
- PullToRefresh刷新的相关代码结合无限轮播
- Codeforces 276D. Little Girl and Maximum XOR(模拟)
- linux报"xxx is not in the sudoers file.This incident will be reported"错误