日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Cocos2d-X开发中国象棋《九》走棋规则

發布時間:2023/12/10 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Cocos2d-X开发中国象棋《九》走棋规则 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在上一節中實現了走棋,這篇博客將介紹中國象棋中的走棋規則


在寫博客前先可能一下象棋的走棋規則:

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<=5if(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格時//返回falseif(d != 11){return false;}//推斷士是否出了九宮//紅色的士和黑色的士的x坐標的范圍都是3<=x<=5if(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格時//返回falseif(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; }


參考文章:http://blog.csdn.net/itcastcpp/article/details/17673393



轉載于:https://www.cnblogs.com/jzssuanfa/p/7270587.html

總結

以上是生活随笔為你收集整理的Cocos2d-X开发中国象棋《九》走棋规则的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。