[擂台]中国象棋中规则检查的算法(卒,兵)

wingfiring 2003-08-22 04:41:24
写一个检查中国卒棋走棋是否符合规则的算法。先只写如何检查“卒“的规则,检查包括黑白方的“卒“。
已经有了一些定义,如下:
enum ECChess //棋子的编码em_R表示红棋,后面跟拼音。
{
em_NoChess = 0x00,

em_RMin = 0x11,
em_RJu = 0x11,
em_RMa = 0x12,
em_RXiang = 0x13,
em_RShi = 0x14,
em_RShuai = 0x15,
em_RPao = 0x16,
em_RBing = 0x17,
em_RMax = 0x17,

em_BMin = 0x21,
em_BJu = 0x21,
em_BMa = 0x22,
em_BXiang = 0x23,
em_BShi = 0x24,
em_BJiang = 0x25,
em_BPao = 0x26,
em_BZhu = 0x27,
em_BMax = 0x27
};
struct CStep //定义了棋步的起止点。
{
unsigned char from,to;
};
棋盘的定义:
class CChessboard
{
enum EChessboard
{
em_SizeX = 10;
em_SizeY = 9;
};
#define BOARDSIZE (em_SizeX * em_SizeY)
unsigned char cells_[BOARDSIZE]; //棋盘格
......
public:
EChessResult Go(CStep);
......
private:
bool Check(CStep);
};

现在要求在check中检查走棋是否符合中国卒棋规则。
bool CChessboard::Check(CStep s)

要求:
时间和空间综合效率最高者独得100分,要完整的函数,符合规则返回true。效率主要考虑时间,空间效率只要不过分奢侈即可。
另外,我卒对其它的棋子开新贴子,都是100分的贴。有兴趣的可以关注。

补充说明:
棋盘按照自己方是红方,左下角坐标为(0,0),右上角是(9,8)来安排坐标;
按行存储,棋子(i,j)在cells_中的位置为i*em_SizeX + j;
...全文
56 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
Dragon132 2003-09-08
  • 打赏
  • 举报
回复
bool CChessboard::CheckRBing(CStep s) //红兵的检验
{
int x1,x2,y1,y2;
x1=s.from/9;
y1=s.from%9;
x2=s.to/9;
y2=s.to%9;

if( cells_[s.to]>em_RMax && cells_[s.to]<em_RMin ) //看s.to是否是自己的棋子
return false;

if( y1<5 && y2==y1+1 && x1==x2 ) //未过河兵
return true;
if( y1>4 && y2==y1+1 && x1==x2 ) //过河兵向前走
return true;
if( y1>4 && y2==y1 && abs(x1-x2)==1) //过河兵左右走
return true;

return false;
}

bool CChessboard::CheckBZhu(CStep s) //黑卒的检验
{
int x1,x2,y1,y2;
x1=s.from/9;
y1=s.from%9;
x2=s.to/9;
y2=s.to%9;

if( cells_[s.to]>em_BMax && cells_[s.to]<em_BMin ) //看s.to是否是自己的棋子
return false;

if( y1>4 && y2==y1-1 && x1==x2 ) //未过河卒
return true;
if( y1<5 && y2==y1-1 && x1==x2 ) //过河卒向前走
return true;
if( y1<5 && y2==y1 && abs(x1-x2)==1) //过河卒左右走
return true;

return false;
}
Dragon132 2003-09-08
  • 打赏
  • 举报
回复
类定义和Check()函数,与其它的题目都相同

class CChessboard
{
enum EChessboard
{
em_SizeX = 10,
em_SizeY = 9
};
#define BOARDSIZE (em_SizeX * em_SizeY)
unsigned char cells_[BOARDSIZE]; //棋盘格

public:
Go(CStep);

private:
bool Check(CStep);
bool CheckRBing(CStep);
bool CheckBZhu(CStep);
bool CheckRShuai(CStep);
bool CheckBJiang(CStep);
bool CheckRShi(CStep);
bool CheckBShi(CStep);
bool CheckRXiang(CStep);
bool CheckBXiang(CStep);
bool CheckRMa(CStep);
bool CheckBMa(CStep);
bool CheckRJu(CStep);
bool CheckBJu(CStep);
bool CheckRPao(CStep);
bool CheckBPao(CStep);
};

bool CChessboard::Check(CStep s)
{

switch(cells_[s.from])
{
case(em_RBing):
return CheckRBing(s);
case(em_BZhu):
return CheckBZhu(s);
case(em_RShuai):
return CheckRShuai(s);
case(em_BJiang):
return CheckBJiang(s);
case(em_RShi):
return CheckRShi(s);
case(em_BShi):
return CheckBShi(s);
case(em_RXiang):
return CheckRXiang(s);
case(em_BXiang):
return CheckBXiang(s);
case(em_RMa):
return CheckRMa(s);
case(em_BMa):
return CheckBMa(s);
case(em_RJu):
return CheckRJu(s);
case(em_BJu):
return CheckBJu(s);
case(em_RPao):
return CheckRPao(s);
case(em_BPao):
return CheckBPao(s);
}
return false;
}
wingfiring 2003-09-06
  • 打赏
  • 举报
回复
忘记了一个很重要的判断,就是红黑要轮流走棋的判断,这是设计的错误.这样的话,比较好办法似乎是在棋盘上加一个该谁走棋的标记.
之所以这么设计是想完成这样一个任务:客户机向服务器提交棋步,而服务器只做最少的合法性检查,从而防止客户端提交非法棋步来欺诈.服务器尽可能的做到内存、CPU占用少和传输信息少,从而增加同时支持的客户数和更小的带宽需求.尽可能的把负担向客户端转移。
wingfiring 2003-09-06
  • 打赏
  • 举报
回复
Dragon132(Dragon) 写的东西就是我想做的。
我的题目有点问题,应该是em_SizeX = 9;
em_SizeY = 10;
这样的话
在cells_(i,j)应该为i*em_SizeY + j而不应该是i*em_SizeX + j,这个是我弄错了,
先道个谦。
Dragon132(Dragon)的代码是正确的,不过应该可以优化。
有一点忘记说明了:棋盘的当前状态“一定“是正确的状态,可以不用检查。

因此象y1>=3这样的检查可以省略,不过这个我没说清楚。
看了Dragon132(Dragon)的代码,大家应该知道我的题目并不难,只是要求高效率。如
果没有人提出更快的方法,那么100分就是Dragon132(Dragon)的啦:)
Dragon132 2003-09-03
  • 打赏
  • 举报
回复
我只会TC,所以先看看行不行,可以的话我就接着做
erlia 2003-09-03
  • 打赏
  • 举报
回复
up
Cybergate 2003-09-02
  • 打赏
  • 举报
回复
卒的走法好像很简单吧?? 需要用到什么算法????
Dragon132 2003-09-02
  • 打赏
  • 举报
回复
我现在先写一下兵和卒的,看看行不行,如果不行我再改
Dragon132 2003-09-02
  • 打赏
  • 举报
回复
bool CChessboard::CheckRBing(CStep s)
{
int x1,x2,y1,y2;
x1=s.from/10;
y1=s.from%10;
x2=s.to/10;
y2=s.to%10;
if(y1>=3&&y1<=4&&y2==y1+1&&x1==x2&&!(s.to<=em_RMax&&s.to>=em_RMin))
return true;
if( y1>4&&( (y1==y2&&abs(x1-x2)==1) || (x1=x2&&y2==y1+1) ) )
return true;
return false;

}

bool CChessboard::CheckBZhu(CStep s)
{
int x1,x2,y1,y2;
x1=s.from/10;
y1=s.from%10;
x2=s.to/10;
y2=s.to%10;
if(y1>=5&&y1<=6&&y2==y1-1&&x1==x2&&!(s.to<=em_BMax&&s.to>=em_BMin))
return true;
if( y1<5&&( (y1==y2&&abs(x1-x2)==1) || (x1=x2&&y2==y1-1) ) )
return true;
return false;

}

//现在要求在check中检查走棋是否符合中国象棋规则。
bool CChessboard::Check(CStep s)
{

switch(cells_[s.from])
{
case(em_RBing):
return CheckRBing(s);
case(em_BZhu):
return CheckBZhu(s);
}
return false;
}
Dragon132 2003-09-02
  • 打赏
  • 举报
回复




bool CChessboard::CheckRBing(CStep s)
{
int x1,x2,y1,y2;
x1=s.from/10;
y1=s.from%10;
x2=s.to/10;
y2=s.to%10;
if(y1>=3&&y1<=4&&y2==y1+1&&x1==x2&&!(s.to<=em_RMax&&s.to>=em_RMin))
return true;
if( y1>4&&( (y1==y2&&abs(x1-x2)==1) || (x1=x2&&y2==y1+1) ) )
return true;
return false;

}

bool CChessboard::CheckBZhu(CStep s)
{
int x1,x2,y1,y2;
x1=s.from/10;
y1=s.from%10;
x2=s.to/10;
y2=s.to%10;
if(y1>=5&&y1<=6&&y2==y1-1&&x1==x2&&!(s.to<=em_BMax&&s.to>=em_BMin))
return true;
if( y1<5&&( (y1==y2&&abs(x1-x2)==1) || (x1=x2&&y2==y1-1) ) )
return true;
return false;

}

//ÏÖÔÚÒªÇóÔÚcheckÖмì²é×ßÆåÊÇ·ñ·ûºÏÖйúÏóÆå¹æÔò¡£
bool CChessboard::Check(CStep s)
{

switch(cells_[s.from])
{
case(em_RBing):
return CheckRBing(s);
case(em_BZhu):
return CheckBZhu(s);
}
return false;
}
wingfiring 2003-08-24
  • 打赏
  • 举报
回复
我的不是做“走法产生器”那么复杂的东西,而是对是否符合规则做检查。
举个例子:车2平5。那么我要检查这一步是不是合法:5位置上有本方棋子,非法;3或者4上有任意一方的棋子,非法。必须3,4位置是空的,5位置是空的或者是对方棋子,才是合法的棋步。我只是做这个检查。
thrillers 2003-08-23
  • 打赏
  • 举报
回复
up
学习
Dragon132 2003-08-23
  • 打赏
  • 举报
回复
mark
ZhangYv 2003-08-22
  • 打赏
  • 举报
回复
楼上的老大...
《PC游戏编程----人机博弈》包括整个一套做棋类博弈的代码.
其中包括: 局面描述 搜索引擎 评价函数 走法产生器
你要求的就是"走法产生器"中的验证功能.
wingfiring 2003-08-22
  • 打赏
  • 举报
回复
拜托,楼上的老大,你的几个连接都是说人机博弈的,和我的要求没有关系啊。
ZhangYv 2003-08-22
  • 打赏
  • 举报
回复
晕啊.怎么发了这么多.
王小春的《PC游戏编程----人机博弈》有完整的代码可以参考.它也是对博弈算法稍稍入门的好书如果你找到了,别忘了给我些分 :)
wingfiring 2003-08-22
  • 打赏
  • 举报
回复
擂台所有项目的连接:
http://expert.csdn.net/Expert/topic/2177/2177761.xml?temp=.5416223
http://expert.csdn.net/Expert/topic/2177/2177860.xml?temp=9.517848E-03
http://expert.csdn.net/Expert/topic/2177/2177862.xml?temp=.95599
http://expert.csdn.net/Expert/topic/2177/2177871.xml?temp=.1810266
http://expert.csdn.net/Expert/topic/2177/2177874.xml?temp=.6430628
http://expert.csdn.net/Expert/topic/2177/2177882.xml?temp=.598324
http://expert.csdn.net/Expert/topic/2177/2177840.xml?temp=.900387

69,336

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧