【Qt象棋游戏】05_象棋走棋规则——象、马、将、兵
文章目录
- 01 - 象能否移动
- 02 - 马能否移动
- 03 - 将能否移动
- 04 - 兵能否移动
- 05 - 判断象棋走棋规则函数
- 06 - 总结
01 - 象能否移动
象走田:象走日字格,判断方法为目标坐标和原始坐标横纵坐标绝对值差都为2,另外,还要注意“别象脚”判断,依靠横纵坐标差的中值可以获取到中值坐标,根据该坐标值,调用existChess函数判断在该位置是否有棋子“别象脚”,如果有棋子,那么棋子象不能移动。
/**** @brief : 判断象是否可以移动* @param : moveID : 移动棋子ID* killID : 目标棋子ID (如果无棋子,默认-1)* x : x轴坐标* y : y轴坐标* @return: 可以走 : true, 不可以走 : false***/
bool ChessArea::canMoveXIANG(int moveID, int killID, int x, int y)
{if(killID > 31)return false;//象不能过河if(myChess[moveID].isRed){if(y<5)return false;} else{ /* 黑象 */if(y>4)return false;}//走田字格int dx = myChess[moveID].row - x;int dy = myChess[moveID].col - y;int medium_x = (myChess[moveID].row + x)/2;int medium_y = (myChess[moveID].col + y)/2;if(abs(dx)==2 && abs(dy)==2) {//别象眼检验if(!existChess(medium_x, medium_y))return true;}return false;
}
02 - 马能否移动
马走日:马走日字格,分两种情况,其一是横坐标绝对值差为2,纵坐标绝对值差为 1;还有一种是纵坐标绝对值差为2,横坐标绝对值差为 1。另外,还要注意“别马脚”判断,依靠横纵坐标差的中值可以获取到中值坐标,根据这个坐标值,调用existChess函数判断在该位置是否有棋子“别马脚”,如果有棋子那么不能走。
/**** @brief : 判断马是否可以移动* @param : moveID : 移动棋子ID* killID : 目标棋子ID (如果无棋子,默认-1)* x : x轴坐标* y : y轴坐标* @return: 可以走 : true, 不可以走 : false***/
bool ChessArea::canMoveMA(int moveID, int killID, int x, int y)
{if(killID > 31)return false;int dx = myChess[moveID].row - x;int dy = myChess[moveID].col - y;int medium_x = (myChess[moveID].row + x)/2;int medium_y = (myChess[moveID].col + y)/2;if((abs(dx)==1&&abs(dy)==2) || (abs(dx)==2&&abs(dy)==1)){if(abs(dx)==2){//别马腿检验if(existChess(medium_x, myChess[moveID].col)==false)return true;} else if(abs(dy)==2) {//别马腿检验if(existChess(myChess[moveID].row, medium_y)==false)return true;}}return false;
}
03 - 将能否移动
将不出营:将不出营指的是将不能跳出士保护范围(米字格)外,每次将只能移动一个步长。另外,当双方的将在同一直线上,而且没有隔着任何棋子时,那么将就可以吃掉对方的将。
/**** @brief : 判断将是否可以移动* @param : moveID : 移动棋子ID* killID : 目标棋子ID (如果无棋子,默认-1)* x : x轴坐标* y : y轴坐标* @return: 可以走 : true, 不可以走 : false***/
bool ChessArea::canMoveJIANG(int moveID, int killID, int x, int y)
{//flag_be用来存放位于同一列上的两个将之间棋子的个数int flag_be = -1;int step = 0;//列超出范围if(x<3 || x>5)return false;//行坐标差int dx = myChess[moveID].row - x;//列坐标差int dy = myChess[moveID].col - y;//判断步长是否为1if((abs(dx)==1&&abs(dy)==0) || (abs(dx)==0&&abs(dy)==1))step = 1;//红棋if(myChess[moveID].isRed){//要杀掉的棋子必须是对面的老将且与对面的老将在同一列上if(killID == 20 && myChess[moveID].row == myChess[20].row){flag_be = middleChessNum(moveID, x, y);if(flag_be == 0)return true;}//在田字格里面行走if(y<=9 && y>=7 && step==1)return true;} else{ //黑棋//要杀掉的棋子必须是对面的老将且与对面的老将在同一列上if(killID == 4 && myChess[moveID].row == myChess[4].row){flag_be = middleChessNum(moveID, x, y);if(flag_be == 0)return true;}//在田字格里面行走if(y>=0 && y<=2 && step==1)return true;}return false;
}
04 - 兵能否移动
兵去不还:兵的走法比较复杂,考虑的细节较多。无论兵有没有过河都不能回头走,过河后,兵才能向左右走。根据这个规则代码可以分为红方和黑方的兵过河前和过河后四个方面进行处理,也比较容易理解。
/**** @brief : 判断兵是否可以移动* @param : moveID : 移动棋子ID* killID : 目标棋子ID (如果无棋子,默认-1)* x : x轴坐标* y : y轴坐标* @return: 可以走 : true, 不可以走 : false***/
bool ChessArea::canMoveBING(int moveID, int killID, int x, int y)
{if(killID > 31)return false;int dx=myChess[moveID].row - x;int dy=myChess[moveID].col - y;if(myChess[moveID].isRed){// 红方棋子,过河前的行走规则if(myChess[moveID].col>=5 && myChess[moveID].col<=6) {if(dy==1 && dx==0) //竖着走,不回头return true;else //横着走,走不通return false;} else { /* 过河后 */if((abs(dy)==1 && abs(dx)==0) ||(abs(dx)==1 && abs(dy)==0)){if(dy == -1) //竖着走return false; //竖着走走了回头路就要返回错误else //横着走return true;}else {return false;} }} else { /* 黑棋 */// 黑方棋子,过河前的行走规则if(myChess[moveID].col>= 3 && myChess[moveID].col<=4){if(dy == -1 && dx==0) //竖着走,不回头return true;else //横着走,走不通return false;} else { /* 过河后 */if((abs(dx)==1&&abs(dy)==0)||(abs(dy)==1&&abs(dx)==0)){if(dy == 1) //竖着回头走,走不通return false;else //横着走,一样走得通return true;} else {return false; }}}return false;
}
05 - 判断象棋走棋规则函数
经过了两篇象棋走棋规则讲解,基本把象棋棋子走法规则理清楚,下面通过canMove函数调用判断各个棋子能否走棋的方法,如果能走棋返回true,否则返回false。
/**** @brief : 判断棋子是否可以移动** @param : moveID : 移动棋子ID* killID : 目标棋子ID (如果无棋子,默认-1)* x : x轴坐标* y : y轴坐标** @return: 可以走 : true, 不可以走 : false***/
bool ChessArea::canMove(int moveID, int killID, int x, int y)
{if(moveID < 0)return false;// killID 为 -1 表示该ID是没有棋子if(killID==-1 || !sameColor(moveID, killID)){switch(myChess[moveID].chessType){case Chess::JIANG:return canMoveJIANG(moveID, killID, x, y);break;case Chess::SHI:return canMoveSHI(moveID, killID, x, y );break;case Chess::XIANG:return canMoveXIANG(moveID, killID, x, y);break;case Chess::CHE:return canMoveCHE(moveID, killID, x, y);break;case Chess::MA:return canMoveMA(moveID, killID, x, y);break;case Chess::PAO:return canMovePAO(moveID, killID, x, y);break;case Chess::BING:return canMoveBING(moveID, killID, x, y);break;default: break;}}// 棋子颜色相同,不能走if(sameColor(moveID, killID))return false;return false;
}
06 - 总结
到了这里,象棋走棋规则就制定完毕了,接下来需要结合鼠标按压事件,获取到走棋目标坐标,然后使用上象棋走棋规则判断点击选中的棋子是否能移动,然后在进行图标绘制和删除就能完成象棋游戏。
- 01_开发象棋游戏简介
- 02_绘画象棋棋盘
- 03_象棋棋子摆放
- 04_象棋走棋规则——車、炮、士
- 05_象棋走棋规则——象、马、将、兵
- 06_象棋游戏法则
- 07_人机博弈算法开端
- 08_人机博弈高阶算法
【Qt象棋游戏】05_象棋走棋规则——象、马、将、兵相关推荐
- QT小游戏——中国象棋
QT小游戏--中国象棋 前言 项目整体结构 棋子类 棋盘类 几个重要方法 1.坐标转化 2.移动规则 3.悔棋和撤销 项目文件 前言 最近用qt做了个中国象棋的小游戏. 目前只能左右互博,支持悔棋.效 ...
- Cocos2d-X开发中国象棋《九》走棋规则
在上一节中实现了走棋,这篇博客将介绍中国象棋中的走棋规则 在写博客前先可能一下象棋的走棋规则: 1)将 将的坐标关系:横坐标相等,纵坐标相减绝对值等于1,或者纵坐标相等,横坐标相减绝对值等于1 将的特 ...
- HTML5中国象棋游戏(自定义象棋难度)源码下载
棋类游戏在桌面游戏中已经非常成熟,中国象棋的版本也非常多.今天这款基于HTML5技术的中国象棋游戏非常有特色,我们不仅可以选择中国象棋的游戏难度,而且可以切换棋盘的样式.程序写累了,喝上一杯咖啡,和电 ...
- 【Qt象棋游戏】04_象棋走棋规则——車、炮、士
文章目录 01 - 象棋规则 02 - 棋子移动规则 03 - 車能否移动 04 - 炮能否移动 05 - 士能否移动 06 - 总结 01 - 象棋规则 经过两篇前面棋盘和棋子绘制,象棋框架基本 ...
- 中国象棋游戏Chess(3) - 实现走棋规则
棋盘的绘制和走棋参看博文:中国象棋游戏Chess(1) - 棋盘绘制以及棋子的绘制,中国象棋游戏Chess(2) - 走棋 现在重新整理之前写的代码,并且对于每个棋子的走棋规则都进行了限制,不像之前那 ...
- 【Qt象棋游戏】03_象棋棋子摆放
文章目录 01 - 加载棋子UI资源 02 - 添加棋子属性类 03 - 添加棋子标签 04 - 效果 05 - 总结 棋子图片百度云链接: 01 - 加载棋子UI资源 添加制作好的棋子UI图片到 ...
- 【Qt象棋游戏】02_绘画象棋棋盘
文章目录 01 - 相关成员与方法 02 - 棋盘颜色 03 - 绘画棋盘线 04 - 添加"井"字格 05 - 总结 01 - 相关成员与方法 进行代码编写之前,在chess ...
- 【Qt象棋游戏】06_象棋游戏法则
文章目录 01 - 象棋游戏规则 02 - 鼠标移动事件 03 - 鼠标点击事件 04 - 总结 01 - 象棋游戏规则 实现上两章节的棋子走棋规则后,开始思考象棋游戏规则,比如轮到谁走,怎么判断 ...
- 【Qt象棋游戏】08_人机博弈高阶算法
文章目录 01 - 极大极小值算法 02 - 电脑和人类所有走棋路径 03 - 走一步看两步 04 - 走一步看多步 04 - 总结 01 - 极大极小值算法 上一期博客介绍了最为简单的人机博弈算 ...
- 【Qt象棋游戏】07_人机博弈算法开端
文章目录 01 - 人机博弈算法简述 02 - 相关成员与方法 03 - 获取电脑棋子能走路径 04 - 电脑走棋 05 - 总结 01 - 人机博弈算法简述 前面详细介绍了棋盘类的封装.棋子类的 ...
最新文章
- 随机密码生成python_每日一课 | Python 中生成 0 到 9 之间的随机整数
- Redis分布式锁实现
- (chap4 Http状态码) 4XX
- cordova报错:Error: Failed to find ‘ANDROID_HOME‘ environment variable. Try setting setting it manually
- LNMP服务跨省迁移的解决方案
- python如何连redis_python操作redis
- Selenium之利用Excel实现参数化
- 压缩word的简单方法看这里
- VM12虚拟机安装xp系统教程
- 星梦邮轮世界梦号推出深圳母港特别航次
- listmanager htdocs
- 国内高校大数据教研机构调研报告
- VS中未定义标识符cout,endl
- android模拟器玩手游,电脑上玩手游PC安卓模拟器哪个好用?哪个手机模拟器最好...
- Linux正则表达式和文本处理工具(gred、awk、sed)
- Nginx + uWSGI + Python + Django构建必应高清壁纸站
- 图书管理系统——C语言版
- asp.net毕业生信息管理系统VS开发sqlserver数据库web结构c#编程计算机网页源码项目
- 网游“梦幻西游”“my.exe”在Win7(或XP)下出现“已停止工作”报错无法运行的解决方法
- 什么是Python语言?Python成为热门编程语言的原因
热门文章
- html网页加线条,「网站特效」html5 canvas粒子线条特效制作方法
- 【云原生之Docker实战】使用Docker部署BookStack文档管理系统
- 【快递100】 物流公司对应编码分享(截止到2021-09-19 最新数据)
- python开发一个自动批改本地Word作业的程序
- java程序一图片为背景_利用Java处理图片,更换背景
- 分享一篇酷炫粒子风暴代码!
- 网站优化快速排名软件大全,用不用随你不做建议
- openwrt 格式化_OpenWRT上进行EXT4格式化和内容写入
- 在GIS中如何绘制胡焕庸线
- Python学习_基础_29_面向对象编程之多态、鸭子类型