Cocos2d-X开发中国象棋《九》走棋规则
2014-11-19 22:05
120 查看
在上一节中实现了走棋,这篇博客将介绍中国象棋中的走棋规则
在写博客前先可能一下象棋的走棋规则:
1)将
将的坐标关系:横坐标相等,纵坐标相减绝对值等于1,或者纵坐标相等,横坐标相减绝对值等于1
将的特殊要求:目标坐标坐落于九宫内
将的例外情况:如果两个老将面对面而中间没有棋子阻拦,老将可以直接飞到对方九宫吃对方老将
2)士
士的坐标关系:纵坐标和横坐标相减的绝对值都是1,
士的特殊要求:目标坐标坐落于九宫内
3)象
象的坐标关系:纵坐标和横坐标相减的绝对值都是2
象的特殊要求:象眼不能有棋子,不能过河
4)车
车的坐标关系:横坐标或者纵坐标相等
车的特殊要求:两个坐标之间不能有棋子存在
5)马
马的坐标关系:横坐标相减等于1且纵坐标相减等于2,或者反过来
马的特殊要求:马腿不能憋着
6)炮
炮的坐标关系:与车相同
炮的特殊要求:如果目标坐标没有棋子,则与车一样,否则要求中间有一个棋子
7)兵
过河前:
兵的坐标关系:纵坐标相差1,而且只能前进
兵的特殊要求:没有
过河后:
兵的坐标关系:纵坐标相差1或者横坐标相差1,不能后退
兵的特殊要求:没有
实现代码:
首先在在SceneGame类中定义一个成员函数canMove(int moveid, int killid, int x, int y)用于实现走棋规则
然后针对不同的棋子定义成员函数,实现走棋规则
canMoveJiang(int moveid, int killid, int x, int y)实现将的走棋规则
canMoveShi(int moveid, int x, int y)实现士的走棋规则
canMoveXiang(int moveid, int x, int y)实现相的走棋规则
canMoveChe(int moveid, int x, int y)实现车的走棋规则
canMoveMa(int moveid, int x, int y)实现马的走棋规则
canMovePao(int moveid, int killid, int x, int y)实现炮的走棋规则
canMoveBing(int moveid, int x, int y)实现兵的走棋规则
getStoneCount(int xo, int yo, int x, int y)判断两个棋子之间棋子的个数,用于车和炮以及将的对杀
参考文章:/article/1383158.html
在写博客前先可能一下象棋的走棋规则:
1)将
将的坐标关系:横坐标相等,纵坐标相减绝对值等于1,或者纵坐标相等,横坐标相减绝对值等于1
将的特殊要求:目标坐标坐落于九宫内
将的例外情况:如果两个老将面对面而中间没有棋子阻拦,老将可以直接飞到对方九宫吃对方老将
2)士
士的坐标关系:纵坐标和横坐标相减的绝对值都是1,
士的特殊要求:目标坐标坐落于九宫内
3)象
象的坐标关系:纵坐标和横坐标相减的绝对值都是2
象的特殊要求:象眼不能有棋子,不能过河
4)车
车的坐标关系:横坐标或者纵坐标相等
车的特殊要求:两个坐标之间不能有棋子存在
5)马
马的坐标关系:横坐标相减等于1且纵坐标相减等于2,或者反过来
马的特殊要求:马腿不能憋着
6)炮
炮的坐标关系:与车相同
炮的特殊要求:如果目标坐标没有棋子,则与车一样,否则要求中间有一个棋子
7)兵
过河前:
兵的坐标关系:纵坐标相差1,而且只能前进
兵的特殊要求:没有
过河后:
兵的坐标关系:纵坐标相差1或者横坐标相差1,不能后退
兵的特殊要求:没有
实现代码:
首先在在SceneGame类中定义一个成员函数canMove(int moveid, int killid, int x, int y)用于实现走棋规则
//走棋规则 bool SceneGame::canMove(int moveid, int killid, int x, int y) { //获得选中的棋子 Stone* s = _s[moveid]; //棋子的类型 switch(s->getType()) { //将的走棋规则 case Stone::JIANG: { return canMoveJiang(moveid, killid, x, y); } break; //士的走棋规则 case Stone::SHI: { return canMoveShi(moveid, x, y); } break; //相的走棋规则 case Stone::XIANG: { return canMoveXiang(moveid, x, y); } break; //车的走棋规则 case Stone::CHE: { return canMoveChe(moveid, x, y); } break; //马的走棋规则 case Stone::MA: { return canMoveMa(moveid, x, y); } break; //炮的走棋规则 case Stone::PAO: { return canMovePao(moveid, killid, x, y); } break; //兵的走棋规则 case Stone::BING: { return canMoveBing(moveid, x, y); } break; default: { break; } } return false; }
然后针对不同的棋子定义成员函数,实现走棋规则
canMoveJiang(int moveid, int killid, int x, int y)实现将的走棋规则
//将的走棋规则 bool SceneGame::canMoveJiang(int moveid, int killid, int x, int y) { Stone* skill = _s[killid]; //将的走棋规则: //1、一次走一格 //2、不能出九宫格 //CCLog("x=%d, y=%d", x, y); //CCLog("moveid=%d, killid=%d", moveid, killid); //将的对杀 if(skill->getType() == Stone::JIANG) { return canMoveChe(moveid, x, y); } //通过棋子的ID得到棋子 Stone* s = _s[moveid]; //获得将当前的位置 int xo = s->getX(); int yo = s->getY(); //获得将走的格数 //(x,y)表示将走到的位置 int xoff = abs(xo - x); int yoff = abs(yo - y); int d = xoff*10 + yoff; //走将的时候有两种情况 //xoff=1, yoff=0:将向左或向右 //xoff=0, yoff=1:将向前或向后 if(d != 1 && d != 10) { return false; } //判断将是否出了九宫 //红色的将和黑色的将的x坐标的范围都是3<=x<=5 if(x<3 || x>5) { return false; } //如果玩家的棋子是红棋 if(_redSide == s->getRed()) { //判断将是否出了九宫 if(y<0 || y>2) { return false; } } else//判断黑色的将的范围 { //判断将是否出了九宫 if(y>9 || y<7) { return false; } } return true; }
canMoveShi(int moveid, int x, int y)实现士的走棋规则
//士的走棋规则 bool SceneGame::canMoveShi(int moveid, int x, int y) { //士的走棋规则: //1、一次走一格 //2、不能出九宫格 //3、斜着走 //通过棋子的ID得到棋子 Stone* s = _s[moveid]; //获得相走棋前的位置 int xo = s->getX(); int yo = s->getY(); //获得相走的格数 //(x,y)表示将走到的位置 int xoff = abs(xo - x); int yoff = abs(yo - y); int d = xoff*10 + yoff; //士每走一步x方向走1格,y方向走1格 //当走的格数大于1格时 //返回false if(d != 11) { return false; } //判断士是否出了九宫 //红色的士和黑色的士的x坐标的范围都是3<=x<=5 if(x<3 || x>5) { return false; } //如果玩家的棋子是红棋 if(_redSide == s->getRed()) { //判断士是否出了九宫 if(y<0 || y>2) { return false; } } else//判断黑色的士的范围 { //判断士是否出了九宫 if(y>9 || y<7) { return false; } } return true; }
canMoveXiang(int moveid, int x, int y)实现相的走棋规则
//相的走棋规则 bool SceneGame::canMoveXiang(int moveid, int x, int y) { //相的走棋规则: //每走一次x移动2格,y移动2格 //不能过河 //通过棋子的ID得到棋子 Stone* s = _s[moveid]; //获得相走棋前的位置 int xo = s->getX(); int yo = s->getY(); //获得相走的格数 //(x,y)表示将走到的位置 int xoff = abs(xo - x); int yoff = abs(yo - y); int d = xoff*10 + yoff; //相每一次x方向走2格子,y方向走2格 //当走的格数大于2格时 //返回false if(d != 22) { return false; } //计算两个坐标的中点坐标 int xm = (xo + x) / 2; int ym = (yo + y) / 2; //得到(xm,ym)上的棋子 int id = getStone(xm, ym); //当(xm,ym)上有棋子的时候 if(id != -1) { //不能走相 return false; } //限制相不能过河 //如果玩家的棋子是红棋 if(_redSide == s->getRed()) { //判断相是否过了河 if(y > 4) { return false; } } else//判断黑色的相的范围 { //判断相是否过了河 if(y < 5) { return false; } } return true; }
canMoveChe(int moveid, int x, int y)实现车的走棋规则
//车的走棋规则 bool SceneGame::canMoveChe(int moveid, int x, int y) { //通过棋子的ID得到棋子 Stone* s = _s[moveid]; //获得车走棋前的位置 int xo = s->getX(); int yo = s->getY(); //当两点之间有棋子的时候车不能走 if(getStoneCount(xo,yo,x,y) != 0) { return false; } return true; }
canMoveMa(int moveid, int x, int y)实现马的走棋规则
//马的走棋规则 bool SceneGame::canMoveMa(int moveid, int x, int y) { //通过棋子的ID得到棋子 Stone* s = _s[moveid]; //获得马走棋前的位置 int xo = s->getX(); int yo = s->getY(); //CCLog("xo=%d", xo); //CCLog("yo=%d", yo); //获得马走的格数 //(x,y)表示马走到的位置 //马有两种情况: //第一种情况:马先向前或向后走1步,再向左或向右走2步 //第二种情况:马先向左或向右走1不,再向前或向后走2步 int xoff = abs(xo-x); int yoff = abs(yo-y); //CCLog("x=%d", x); //CCLog("y=%d", y); int d = xoff*10 + yoff; //CCLog("d=%d", d); if(d != 12 && d != 21) { return false; } int xm, ym;//记录绑脚点坐标 if(d == 12)//当马走的是第一种情况 { xm = xo;//绑脚点的x坐标为走棋前马的x坐标 ym = (yo + y) / 2;//绑脚点的y坐标为走棋前马的y坐标和走棋后马的y坐标的中点坐标 } else//当马走的是第二种情况 { xm = (xo + x) / 2;//绑脚点的x坐标为走棋前马的x坐标和走棋后马的x坐标的中点坐标 ym = yo;;//绑脚点的y坐标为走棋前马的y坐标 } //CCLog("xm=%d", xm); //CCLog("ym=%d", ym); //当绑脚点有棋子时,不能走 if(getStone(xm, ym) != -1) { return false; } return true; }
canMovePao(int moveid, int killid, int x, int y)实现炮的走棋规则
//炮的走棋规则 bool SceneGame::canMovePao(int moveid, int killid, int x, int y) { //通过棋子的ID得到棋子 Stone* s = _s[moveid]; //获得炮走棋前的位置 int xo = s->getX(); int yo = s->getY(); //当触摸点上有一个棋子 //而且两点之间只有一个棋子的时候 //炮吃掉触摸点上的棋子 if(killid != -1 && this->getStoneCount(xo,yo,x,y) == 1) { return true; } if(killid == -1 && this->getStoneCount(xo, yo, x, y) == 0) { return true; } return false; }
canMoveBing(int moveid, int x, int y)实现兵的走棋规则
//兵的走棋规则 bool SceneGame::canMoveBing(int moveid, int x, int y) { //兵的走棋规则: //1、一次走一格 //2、前进一格后不能后退 //3、过河后才可以左右移动 //通过棋子的ID得到棋子 Stone* s = _s[moveid]; //获得将当前的位置 int xo = s->getX(); int yo = s->getY(); //获得兵走的格数 //(x,y)表示将走到的位置 int xoff = abs(xo - x); int yoff = abs(yo - y); int d = xoff*10 + yoff; //走将的时候有两种情况 //xoff=1, yoff=0:将向左或向右 //xoff=0, yoff=1:将向前或向后 if(d != 1 && d != 10) { return false; } //如果玩家的棋子是红棋 if(_redSide == s->getRed()) { //限制红色的兵不能后退 if(y < yo) { return false; } //红色的兵没有过河不能左右移动 if(yo <= 4 && y == yo) { return false; } } else//判断黑色的兵 { //限制黑色的兵不能后退 if(y > yo) { return false; } //黑色的兵没有过河不能左右移动 if(yo >= 5 && y == yo) { return false; } } return true; }
getStoneCount(int xo, int yo, int x, int y)判断两个棋子之间棋子的个数,用于车和炮以及将的对杀
///计算(xo,yo)和(x,y)之间的棋子数 //如果棋子数为-1,表示(xo,yo)和(x,y)不在一条直线上 int SceneGame::getStoneCount(int xo, int yo, int x, int y) { int ret = 0;//记录两点之间的棋子的个数 //(xo,yo)和(x,y)不在同一条直线上 if(xo != x && yo != y) { return -1; } //(xo,yo)和(x,y)在同一点上 if(xo == x && yo == y) { return -1; } //两点在同一条竖线上 if(xo == x) { //min为两个点中y坐标最小的点的y坐标 int min = yo < y ? yo : y; //max为两个点中y坐标最大的点的y坐标 int max = yo > y ? yo : y; //查找同一条竖线上两点之间的棋子数 for(int yy=min+1; yy<max; yy++) { //当两点之间有棋子的时候 if(getStone(x,yy) != -1) { ++ret;//棋子数加1 } } } else//两点在同一条横线上yo == y { //min为两个点中x坐标最小的点的x坐标 int min = xo < x ? xo : x; //max为两个点中x坐标最大的点的x坐标 int max = xo > x ? xo : x; //查找同一条竖线上两点之间的棋子数 for(int xx=min+1; xx<max; xx++) { //当两点之间有棋子的时候 if(getStone(xx,y) != -1) { ++ret;//棋子数加1 } } } //返回两点之间的棋子数 return ret; }
参考文章:/article/1383158.html
相关文章推荐
- Cocos2d-X开发中国象棋《九》走棋规则
- Cocos2d-X开发中国象棋《一》功能介绍
- Cocos2d-X开发中国象棋《六》游戏开始功能的实现
- cocos2d-x游戏开发系列教程-中国象棋03-主界面
- cocos2d-x游戏开发系列教程-中国象棋02-main函数和欢迎页面
- Cocos2d-X开发中国象棋《二》工程文件概述
- cocos2d-x游戏开发系列教程-中国象棋05-开始游戏
- Cocos2d-X开发中国象棋《八》走棋
- cocos2d-x游戏开发系列教程-中国象棋04-摆棋
- Cocos2d-X开发中国象棋《四》设计游戏场景
- Cocos2d-X开发中国象棋《八》走棋
- Cocos2d-X开发中国象棋《五》摆棋
- Cocos2d-x开发中国象棋《十一》在游戏中添加背景音乐
- Cocos2d-X开发中国象棋《十二》游戏结果的显示与隐藏
- cocos2d-x游戏开发系列教程-中国象棋04-摆棋
- Cocos2d-X开发中国象棋《三》開始场景的实现