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

wingfiring 2003-08-22 04:37:04
写一个检查中国象棋走棋是否符合规则的算法。先只写如何检查“炮“的规则,检查包括黑白方的“炮“。
已经有了一些定义,如下:
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;
...全文
117 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
ZhangYv 2003-08-28
  • 打赏
  • 举报
回复
SORRY,我最近没什么时间.现在我在学校,电脑没带上去资料也不能再发给你,而且上网也很不方便.

对需要验证的走子方法先判断是否越界,无特殊说明均代表不能越棋盘的界限,并且目的地上不允许有自方棋子,红方子在棋盘上标记为1,黑方为2,未占用为0:

对于车2平5(车i平j),除非(由于没)有先前提供的额外判断的信息,所以只能逐个对2,3,4等经过的路径节点一一判断是否有堵塞了.简单举个没有经过具体证实的略去越界判断的例子:
bool judge_CAR_ROW(const int row, const int i, const int j, const int color)
{
if (board[row][j] == color)
return false;
//越界检测就是判断j在限值的一维区间内
int k;
if (i <= j)
for (k = i; k < j; k++)
if (board[row][k])
return false;
else
for (k = i; k > j; k--)
if (board[row][k])
return false;
return true;
}
对于红车2平5(车i平j),则Judge_CAR_ROW(row, i,j,RED);红车2进5则
Judge_CAR_COL(col,i,j,RED)实现有点不同,但是类似.其他类型的棋子也一样,好像没有更好的方法.

对于炮2平5,if (经过节点不堵塞 AND (有且只有一个子间隔[并且目的地上不允许有自方棋子,已在先前隐含的判断过])) than success else error;

bool judge(const int row, const int i, const int j, const int color)
{
if (board[row][j] == color)
return false;
//越界检测就是判断j在限值的一维区间内
int k;
bool flag = true;
if (i <= j)
for (k = i; k < j; k++)
if (board[row][k])
if (flag)
flag = false;
else
return false; //存在多于1个间隔子
else
for (k = i; k > j; k--)
if (board[row][k])
if (flag)
flag = false;
else
return false;

if (flag){
if (!board[row][k])
return true; //无间隔子,目的地未占用
else
return false;
}
else if (board[row][j] == ((color == 1)?2:1)) //目的地是敌子
return true;
else
return false;
}

对于兵,在自方河界内只允许前进1步,并且过河界后还可以左右横移动1步

对于马,判断到目的地的方向(有四个)马脚是否堵塞即可

对于象,同马类似的不多于4个的象眼,不允许越过河界的越界判断,而且假设象在一开始就在正确的象位上

对于士,只要是走自方九宫内的允许界内的斜线(分进退情况判断越界)即可,而且假设士在一开始就在正确的士位上

对于将,只要是走自方九宫内的允许界内的直线即可,而且假设将在一开始就在正确的将位上

越界有3种,一个是棋盘界,一个是己方河界,一个是九宫界,可以做3个常量的.

其他不多说了,由于时间和其他原因我不再回复了.以上代码我都是用记事本写的,没经过验证.
Dragon132 2003-08-26
  • 打赏
  • 举报
回复
我这两天有些忙,过几天我就做一下
wingfiring 2003-08-25
  • 打赏
  • 举报
回复
有兴趣的帮忙顶一下吧。
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
  • 打赏
  • 举报
回复
10M要发N久,至少200分.过了今晚就没有了,明天我开学就要去学校.
ZhangYv 2003-08-22
  • 打赏
  • 举报
回复
我这里有一份<<博弈算法全集>>好像是在饮水思源BBS上找到的.一份很牛的E文论文.
如果楼主要的话,在今晚给我留EMAIL我发给你.
我是拨号的,快10M的文件.我要分交换 :)
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,335

社区成员

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

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