铣床国际象棋棋盘多少格程序!急求啊

急求C++设计象棋打谱程序的源代码_百度知道
急求C++设计象棋打谱程序的源代码
选修课的大作业,不需要加入AI,最好给阐述一下思想,以及怎么导入棋子图片作为控件,谢谢!
这是一个简单的程序,会自动计算提子,但不会数目。其它的运行一次估计就差不多会用了。稍微写了点注释。#include&stdio.h&#include&stdlib.h&char board[21][21];char move[5][2]=,,,,};void initBoard();//初始化棋盘 void showBoard();//输出棋盘char set(int x,int y,char color);//下子 void process(int xx,int yy);//计算提子 int main(){
FILE * fptr=NULL;
char pufile[256]=;
int x,y,r;
while(s!=1 && s!=2)
printf(&选择模式:\n1---下棋\n2---看棋谱\n0---退出\n&);
printf(&下棋模式下,下子请输入s x y(x,y为位置),认输输入g,和棋输入h\n选择:&);
scanf(&%d&,&s);
if(s==0) return 0;
if(s==10) printf(&Programmer: swordlance :)\n&);
//Egg1 end
getchar();
printf(&输入棋谱路径:&);
gets(pufile);
if(s==1) fptr=fopen(pufile,&w&);
else fptr=fopen(pufile,&r&);
printf(&文件无法打开(创建)!\n&);
system(&PAUSE&);
return -1;
initBoard();
color='B';
while(op!='g')
system(&CLS&);
showBoard();
printf(&(第%d手)&,++cnt);
printf(&%c 方:&,color);
scanf(&%c&,&op);
//printf(&[%c]&,op);
if(op=='s')
scanf(&%d %d&,&x,&y);
getchar();
if(set(x,y,color)!=0)
printf(&该处不能落子!\n&);
system(&PAUSE&);
process(x,y);
fprintf(fptr,&%d %d\n&,x,y);
if(color=='B') color='W';
else color='B';
else if(op=='g')
printf(&%c 方认输。\n&,color);
if(color=='B') fprintf(fptr,&0 1\n&);
else fprintf(fptr,&0 -1\n&);
fflush(fptr);
fclose(fptr);
system(&PAUSE&);
else if(op=='h')
printf(&和棋。\n&);
fprintf(fptr,&0 0\n&);
fflush(fptr);
fclose(fptr);
system(&PAUSE&);
printf(&参数错误,下子请输入s x y(x,y为位置),认输输入 g,和棋输入h&);
system(&PAUSE&);
fscanf(fptr,&%d %d&,&x,&y);
if(y&0) printf(&W 方胜!\n&);
else if(y&0) printf(&B 方胜!\n&);
else printf(&和棋!\n&);
system(&PAUSE&);
printf(&%c 方落子(%d,%d)\n&,color,x,y);
set(x,y,color);
process(x,y);
if(color=='B') color='W';
else color='B';
system(&PAUSE&);
system(&PAUSE&);
return 0;}void initBoard(){
board[0][0]='O';
for(i=1;i&=19;i++) board[0][i]='-';
board[0][20]='O';
for(i=1;i&=19;i++)
board[i][0]='|';
for(j=1;j&=19;j++) board[i][j]='+';
board[i][20]='|';
board[20][0]='O';
for(i=1;i&=19;i++) board[20][i]='-';
board[20][20]='O';
board[4][4]=board[4][10]=board[4][16]=
board[10][4]=board[10][10]=board[10][16]=
board[16][4]=board[16][10]=board[16][16]='*';}void showBoard(){
for(i=0;i&=20;i++)
for(j=0;j&=20;j++)
printf(&%c&,board[i][j]);
printf(&\n&);
}}char set(int x,int y,char color){
if(board[x][y]=='W' || board[x][y]=='B') return -1;//不能落子
else board[x][y]=
return 0;}//计算提子 void process(int xx,int yy){
char his[21][21]=;//记录算过的棋子以节约效率
char Q[400][2]=;//某一片棋 //Q的长度。 //这片棋的颜色//另一种颜色
int QI=0;//气数
int i,j,k,l,m;
for(m=0;m&5;m++)
i=xx+move[m][0];//为了能够完成打劫,先算别人再算自己
j=yy+move[m][1];
if(his[i][j]==0 && (board[i][j]=='W' || board[i][j]=='B')) //该位置有子开始算气
his[i][j]=1;
mcolor=board[i][j];
ecolor=(board[i][j]=='W'?'B':'W');
//printf(&m=%c e=%c\n&,mcolor,ecolor);
Q[0][0]=i;
Q[0][1]=j;
for(k=0;k&e;k++)
for(l=0;l&4;l++)
x=Q[k][0]+move[l][0];
y=Q[k][1]+move[l][1];
//printf(&x=%d y=%d\n&,x,y);
//system(&PAUSE&);
if(x&0 && y&0 && x&20 && y&20 && his[x][y]==0)
if(board[x][y]==mcolor)//己方,长气
Q[e][0]=x;
Q[e][1]=y;
his[x][y]=1;
if(board[x][y]=='+') QI++; //空地,加气,忽略重复计算
//printf(&QI=%d\n&,QI);
//system(&PAUSE&);
if(!QI)//死棋,提子
for(k=0;k&e;k++)
board[Q[k][0]][Q[k][1]]='+';
his[Q[k][0]][Q[k][1]]=0;
其他类似问题
象棋的相关知识
您可能关注的推广
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁C++程序代码(打印国际象棋的棋盘) - 下载频道 - CSDN.NET
&&&&C++程序代码(打印国际象棋的棋盘)
&C++程序代码(打印国际象棋的棋盘)
该工程文件能够编译、组建和执行,主要是练习打印国际象棋的棋盘,有很好的C++训练功能,仅供参考!
若举报审核通过,可奖励20下载分
被举报人:
shenjiangrong
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
您可能还需要
Q.为什么我点的下载下不了,但积分却被扣了
A. 由于下载人数众多,下载服务器做了并发的限制。若发现下载不了,请稍后再试,多次下载是不会重复扣分的。
Q.我的积分不多了,如何获取积分?
A. 传优质资源可以获取积分,详细见。选择完成有奖的任务,可以获取积分。选择购买VIP会员服务,无需积分下载资源。评价资源返积分:第一次绑定手机,将获50下载积分及100论坛可用分。论坛可用分兑换下载积分。
下载资源意味着您已经同意遵守以下协议
资源的所有权益归上传用户所有
未经权益所有人同意,不得将资源中的内容挪作商业或盈利用途
CSDN下载频道仅提供交流平台,并不能对任何下载资源负责
下载资源中如有侵权或不适当内容,
本站不保证本站提供的资源的准确性,安全性和完整性,同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
开发技术下载排行
你下载资源过于频繁,请输入验证码
如何快速获得积分?
你已经下载过该资源,再次下载不需要扣除积分
C++程序代码(打印国际象棋的棋盘)
所需积分:1
剩余积分:
VIP会员,免积分下载
会员到期时间:日
剩余下载次数:1000中国象棋程序的设计与实现(10)-棋盘的定义和绘制_产品黏度跟用户体验_在CentOS上装配rabbitmq-server__脚本百事通
稍等,加载中……
^_^请注意,有可能下面的2篇文章才是您想要的内容:
中国象棋程序的设计与实现(10)-棋盘的定义和绘制
产品黏度跟用户体验
在CentOS上装配rabbitmq-server
中国象棋程序的设计与实现(10)-棋盘的定义和绘制
中国象棋程序的设计与实现(十)--棋盘的定义和绘制本篇简要介绍棋盘类的定义、棋盘的关键属性、棋盘绘制算法的骨架。
棋盘的详细绘制算法等内容,我们将在接下来的几篇进行详细介绍。
棋盘类的定义
public abstract class ChessBoard extends JPanel
棋盘是一个继承自JLabel的图形界面组件,当在界面展示,看起来比较美观。
细心的读者注意到,abstract表明 这是一个抽象类。
本中国象棋程序,实现了联网对战、残局打谱、全局打谱、人机对弈等多种形式的功能。
不同的功能,它们所对应的棋盘有一些差别,因此,将共同的功能和设计,抽象为一个类。
棋盘类的关键属性
// 棋子点,共90个,横9*纵10
public ChessPoint chessPoints[][];
// 红方16个棋子
public ChessPiece 红車1, 红車2, 红馬1, 红馬2, 红相1, 红相2, 红帥, 红仕1, 红仕2, 红兵1, 红兵2,
红兵3, 红兵4, 红兵5, 红炮1, 红炮2;
// 黑方16个棋子
public ChessPiece 黑車1, 黑車2, 黑馬1, 黑馬2, 黑象1, 黑象2, 黑將, 黑士1, 黑士2, 黑卒1, 黑卒2,
黑卒3, 黑卒4, 黑卒5, 黑炮1, 黑炮2;
构造棋盘对象
* 构造棋盘
public ChessBoard() {
// 不可忽视
setLayout(null);
// 设置棋盘的背景色
setBackground(getBackgroundColor());
// 鼠标适配器
addMouseListener(getMouseAdapter());
// 初始化棋子点
chessPoints = new ChessPoint[X + 1][Y + 1];
for (int i = 1; i &= X; i++) {
for (int j = 1; j &= Y; j++) {
chessPoints[i][j] = new ChessPoint(i * UNIT_WIDTH, j
* UNIT_HEIGHT);
// 为32个棋子分配空间
init32Pieces();
// 初始化32个棋子的工具提示
init32PiecesTooltip();
chessManual = new ChessManual(this);
// 初始化炮和兵的位置,以便画出标记
initPBFlag();
// 棋子闪烁线程
winkThread = new Thread(this);
winkThread.start();
到目前的讲解,读者朋友只能读懂上面的一部分代码。
棋盘是GUI界面的重要的关键的组成部分,和其它模块交互比较多,理解起来有点费事。
不过,不要紧,先读下去,等了解了更多信息后,再回头来读。
* 绘制棋盘:10条横线、9条纵线、炮兵卒14个标记、九宫格、楚河漢界
* 根据需要还绘制棋子移动的标记
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// 绘制棋盘背景
drawBackgroundImage(g);
Graphics2D g2 = (Graphics2D)
// 兵、卒、炮标记笔画
BasicStroke bsFlag = new BasicStroke(2);
// 楚河汉界、棋盘边框笔画
BasicStroke bsLine = new BasicStroke(2);
// 棋盘线笔画
BasicStroke bs1 = new BasicStroke(1);
// 绘制直线
drawLines(g2, bsLine, bs1);
// 绘制九宫格
drawJiuGongLines(g2, bs1);
// 绘制楚河漢界
drawChuheHanjieString(g2);
// 绘制炮和兵标记
drawPaoBingFlag(g2, bsFlag);
// 如果有棋子移动,画出2个提示框,每个提示框由8条线组成
drawMoveFlag(g2);
// 绘制可选走法的提示框
drawWillMoveFlag(g2);
// 设置字体和线宽,为画坐标做准备
BasicStroke bsOld = new BasicStroke(1);
g2.setStroke(bsOld);
g2.setFont(new Font("宋体", Font.PLAIN, 14));
g2.setColor(new Color(0, 0, 0));
// 绘制竖线标记
drawShuXianFlag(g2);
以上,是棋盘绘制算法的骨架。
考虑到棋盘的绘制比较复杂,我们将在下一篇,详细介绍如何绘制棋盘。
网友的一个吐槽
"楼主的中文命名法 让我和蛋疼。"
参见 http://blog.csdn.net/fansunion/article/details/
答:車馬炮等中国象棋中的一些名词,是中国独有的游戏。翻译成对应的英文,比较费事。
假设我翻译成了英文,我看得懂,但是很多人是分不清的。
首先,我有一套自己的编码规范,但是我不会为了所谓的“编码规范”,把自己“束缚”了。
该灵活的就灵活,如果谁看了不舒服,可以修改成自己习惯的方式。
中国象棋程序的设计与实现(零)--原始版源码
中国象棋程序的设计与实现(一)--项目截图
中国象棋程序的设计与实现(二)--源码
中国象棋程序的设计与实现(三)--2012本科毕业论文等重要文档资料
中国象棋程序的设计与实现(四)-- 一次“流产”的写书计划
中国象棋程序的设计与实现(五)--回答CSDN读者的一些问题
中国象棋程序的设计与实现(六)--N皇后问题的算法设计与实现(源码+注释+截图)
中国象棋程序的设计与实现(七)--心得体会和开发日志
中国象棋程序的设计与实现(八)-如何构造一个棋子(車馬炮等)
中国象棋程序的设计与实现(九)–棋子点,棋子的小窝
原文参见:/articles/2905
产品黏度跟用户体验
产品黏度和用户体验先说说黏度。 人怎样会对一种东西产生黏度呢?我列举以下集中情况来说明。一、 人们对连续剧或者小说,总是有很多热情。常常不看完一部连续剧,或者一部小说,就欲罢不能。为什么呢?因为小说也好,连续剧也好,它们总是用一个又一个扣人心弦的故事将人们吸引住,如果你看不完,你就不能知道最后的结果。于是,小说和连续剧就产生了极大的粘性。这种粘性, 我成为 "连续性"。二、一个人,总有自己喜欢的游戏,至少又自己曾经喜欢的游戏。常常为玩游戏,通宵达旦。为什么?因为,游戏总能抓住人的兴趣点,让你不断相似但是不同的体验,让你能够去做,但是不重复。这种粘性,我称为"趣味性"。三、很多人都有打开固定网站看新闻的习惯,而且时间很固定。以前,很多人在吃早餐的时候看早报;现在,很多人上班后第一件事就是打开网页看新闻。这也是一种粘性。我吧这种粘性叫做"习惯性"或者"不可替代性"。为什么既是习惯性又是不可替代性呢? 因为,世界上不存在绝对不可替代的事物,它是相对的,就相对于人的习惯。
比如,一个人如果偶尔需要打电话,那么,他不必买个手机,他可以借别人的手机打,或者用公用电话打,
但是,如果他要经常打电话,他就有必要自己买部手机了; 再比如,一个要偶尔出去旅行,他不需要买个车,他只需要租个车,或者坐出租车即可,但是,如果他经常需要旅行,买个车对他来说,就是必须的了。因此,不可替代性是相对于习惯来说的,当一个人习惯做一件事情的时候,他就必须有合适趁手的工具了。四、人社会性动物,人需要交流,这是人的内在需求。因此,"社交性",也是最重要的一种粘性。再说说用户体验(UX)。什么样的用户体验才是好的?我想,可以从几个方面来考虑:一、无论如何,产品必须是可用的。对人没有用的东西,是不会被珍惜的。
这是产品的"可用性"。 "可用性"的关键词是 "正确","准确"。只有正确且准确的产品,才能给用户提供真正的帮助。二、所谓"工欲善其事,必先利其器",
谁都喜欢流畅的、反应快的产品,用起来才舒服,对于工作,可以提高效率,独有娱乐,才能身心舒畅。 这是产品的"易用性"。
他的关键在于"及时、快速"。三、无论什么工具,人初次接触都需要了解和熟悉,对于软件更是有一个学习的过程。当一个人使用一个软件的时候,他内心必定是对该软件有所需求的。而软件产品,需要用他的图片、文字、布局、声音等组成的
UI界面,来告诉用户:"我能帮你做什么",以及,"怎样让我来帮助你"。 这是产品的"明确性", 让用户能够一目了然。 "明确性"的关键词是"直接、简单"。苹果产品中运用了很多方法来"明确":比如,拟物化设计。它的动画设计,总是力图暗示视图之间存在的某种联系。四、"美观性"。人都有审美需求,对于美的事物,必定喜欢,而且愿意为它花费时间。"美观性"至关重要,它会对用户形成第一印象。而且,在使用过程中,美观的界面让人赏心悦目,缓解疲劳,提高效率。作用是非常大的。一个好的产品,包括两个重要的部分:内容和形式。内容是产品根本,也是产生粘性的根源。凡是有一定价值的产品,其内容必定符合上面提到的四种粘性的一种或者多种。形式是用户体验的载体,用户体验如果做不到"可用性","易用性","明确性"和"美观性"这四点,都不能称为一个好的产品。
在CentOS上装配rabbitmq-server
在CentOS上安装rabbitmq-server
***在 CentOS 6.4上安装python***
注意啊,自己手动安装python2.7.5,不要动系统上面其他的版本
1,先安装GCC,用如下命令yum install gcc gcc-c++
yum install zlib
yum install zlib-devel
2,下载python-2.7.5.tar.gz文件,修改文件权限chmode +x python-7.5.tar.gz
3,解压tar文件,tar -xzvf python-2.7.5.tar.gz
4,cd python-2.7.5
vim Python-2.7.5/Modules/Setup.dist
./configure --prefix=/usr/local/python27 --with-zlib=/usr/include
make && make install
5、建立软连接,使系统默认的python指向python27
mv /usr/bin/python /usr/bin/python2.6.6.old
ln -s /usr/local/bin/python27 /usr/bin/python
已经安装完成python的安装或升级的全部操作了,我们再来看一下现在的python的版本:
# python -V
Python 2.7.5
虽然现在python已经安装完成,但是使用yum命令会有问题——yum不能正常工作:
这是因为yum默认使用的python版本是2.6.6,到哪是现在的python版本是2.7.5,故会出现上述问题,只需要该一下yum的默认python配置版本就行了:
#vi /usr/bin/yum
将文件头部的#!/usr/bin/python改为
#!/usr/bin/python2.6
***在 CentOS 6.4上安装Erlang***
在本节中,我们将来学习如何在CentOS 6.4上安装erlang,具体的Erlang版本是R16B02。
在安装之前,需要先要安装一些其他的软件,否则在安装中间会出现一些由于没有其依赖的软件模块而失败。
1、首先要先安装GCC GCC-C++ Openssl等以来模块:
yum -y install make gcc gcc-c++ kernel-devel m4 ncurses-devel openssl-devel
2、再安装ncurses模块
yum -y install ncurses-devel
yum install ncurses-devel
3、下载Erang源代码文件文件,并对其付权限和解压文件:
wget http://www.erlang.org/download/otp_src_R16B02.tar.gz
chmod +x otp_src_R16B02.tar.gz
tar -xzvf otp_src_R16B02.tar.gz
mv otp_src_R16B02 erlang_R16B #重命名解压厚的文件
4、下面是安装erlang的重头戏,依次执行以下操作:
cd erlang_R16B/
./configure --prefix=/usr/local/erlang --with-ssl --enable-threads --enable-smp-support --enable-kernel-poll --enable-hipe --without-javac
//不用java编译,故去掉java避免错误
make && make install //编译后安装
5、配置erlang环境:
vi /etc/profile
ERL_HOME=/usr/local/erlang
export PATH=$PATH:$ERL_HOME/bin
好了,现在erlang的已经配置好了,现在我们来测试一下是否安装成功,在控制台输入命令erl,如果在erlang shell里出现下图所示就说明安装成功了:
此处省略截图了...
*** 在CentOS上安装rabbitmq-server-3.1.5 ***
在本节中我们来看一下如何在CentOS上安装RabbitMQ。我们使用的rabbitmq的版本是rabbitmq-server-3.1.5.tar.gz,CentOS的版本是CentOS 6.4。
在安装rabbitmq之前需要先安装python和erlang,这两部分的安装过程请参看在 CentOS 6.4上安装python和在 CentOS 6.4上安装Erlang,这里不再赘述。
安装rabbitmq的具体步骤如下:
1、下载rabbitmq-server-3.1.5.tar.gz文件,并解压之:
#cd /usr/local
#wget /releases/rabbitmq-server/v3.1.5/rabbitmq-server-3.1.5.tar.gz
#chmod +x rabbitmq-server-3.1.5.tar.gz
#tar -xzvf rabbitmq-server-3.1.5.tar.gz
2、在编译rabbitmq源码之前先要安装其需要以来包:
#yum -y install xmlto
否则会编译不通过:
/bin/sh: line 1: xmlto: command not found
3、开始编译源代码:
#cd rabbitmq-server-3.1.5
#make install TARGET_DIR=/opt/mq/rabbitmq SBIN_DIR=/opt/mq/rabbitmq/sbin MAN_DIR=/opt/mq/rabbitmq/man //将rabbitmq编译到/opt/mq/rabbitmq目录
4、安装web插件管理界面
#cd /opt/mq/rabbitmq/sbin
#mkdir /etc/rabbitmq/
#rabbitmq-plugins enable rabbitmq_management
5、好了,到这里rabbitmq已经配置好了,可以启动了:
#./rabbitmq-server start &
我运行的时候报错了,ERROR: epmd error for host "springzoo": timeout (timed out)
更改下/etc/hosts:
localhost springzoo
localhost springzoo
# ps aux | grep rabbitmq //查看端口,默认就是5672
netstat -tnlp | grep 5672
0 0.0.0.0:15672
30435/beam.smp
0 0.0.0.0:55672
30435/beam.smp
30435/beam.smp
如果看到下面的信息就表明已经启动成功了:
省略截图....
最好我们就可以在浏览器上输入http://127.0.0.1:15672/登录管理界面了
使用登录的名户名和密码默认都算guest,登录后的页面如下:
截图再次省略...
如果您想提高自己的技术水平,欢迎加入本站官方1号QQ群:&&,&&2号QQ群:,在群里结识技术精英和交流技术^_^
本站联系邮箱:求数据结构课程设计 马踏棋盘
C语言_百度知道
求数据结构课程设计 马踏棋盘
将马随机放在国际象棋的8* 8棋盘Bord[8Ⅱ8]的某个方格中,马按走棋规则进行移动。要求每个方格上只进入一次,走遍棋盘上全部64个方格。编制非递归程序,求出马的行走路线 ,并按求出的行走路线,将数字1,2,…,64依次填入�个8* 8的方阵,输出之。一定要是非递归的,用栈实现,尽量简洁。拜托了。。
运行得过加分100
最好附带课程设计实验报告 源程序
大家也可以发我邮箱
谢谢大家了
提问者采纳
没看见你说的是非递归的。其实我也不懂,碰巧知道答案,在51CTO上下的。
不能插图。9.3
马踏棋盘(1) 【题目要求】 国际象棋的棋盘为8*8的方格棋盘。现将&马&放在任意指定的方格中,按照&马&走棋的规则将&马&进行移动。要求每个方格只能进入一次,最终使得&马&走遍棋盘的64个方格。编写一个C程序,实现马踏棋盘操作,要求用1~64这64个数字标注马移动的路径,也就是按照求出的行走路线,将数字1,2,……64依次填入棋盘的方格中,并输出。 国际象棋中,&马&的移动规则如图9-4所示。
图9-4 &马&的移动规则
如图9-4所示,图中实心的圆圈代表&马&的位置,它下一步可移动到图中空心圆圈标注的8个位置上,该规则叫做&马走日&。但是如果&马&位于棋盘的边界附近,它下一步可移动到的位置就不一定有8个了,因为要保证&马&每一步都走在棋盘中。 【题目分析】 马踏棋盘的问题其实就是要将1,2,…,64填入到一个8*8的矩阵中,要求相邻的两个数按照&马&的移动规则放置在矩阵中。例如数字a放置在矩阵的(i,j)位置上,数字a+1只能放置在矩阵的(i-2,j+1),(i-1,j+2),(i+1,j+2),(i+2,j+1),(i+2,j-1),(i+1,j-2),(i-1,j-2),(i-2,j-1)之中的一个位置上。将矩阵填满并输出。这样在矩阵中从1,2…遍历到64,就得到了马踏棋盘的行走路线。因此本题的最终目的是输出一个8*8的矩阵,在该矩阵中填有1,2…64这64个数字,相邻数字之间遵照&马走日&的规则。 解决马踏棋盘问题的一种比较容易理解的方法是应用递归的深度优先搜索的思想。因为&马&每走一步都是盲目的,它并不能判断当前的走步一定正确,而只能保证当前这步是可走的。&马&走的每一步棋都是从它当前位置出发,向下一步的8个位置中的1个行走(在它下一步有8个位置可走的情况下)。因此&马&当前所走的路径并不一定正确,因为它可能还有剩下的可选路径没有尝试,如图9-5所示。
图9-5 &马&的可选路径
如图9-5所示,假设最开始&马&位于棋盘的(0,0)的位置,接下来&马&有两处位置可走,即(1,2)和(2,1)。这时&马&是无法确定走2的位置最终是正确的,还是走3的位置最终是正确的。因此&马&只能任意先从一个路径走下去(例如从2的位置)。如果这条路是正确的,那当然是幸运的,如果不正确,则&马&要退回到第一步,继续从3的位置走下去。以后&马&走的每一步行走都遵循这个规则。这个过程就是一种深度搜索的过程,同时也是一种具有重复性操作的递归过程。可以用一棵&探索树&来描述该深度优先搜索过程,如图9-6所示。
深度优先搜索过程
&马&的行走过程实际上就是一个深度探索的过程。如图9-6所示,&探索树&的根结点为&马&在棋盘中的初始位置(这里用4*4的棋盘示意)。接下来&马&有两种行走方式,于是根结点派生出两个分支。而再往下一步行走,根结点的两个孩子又能够分别派生出其他不同的&行走路线&分支,如此派生下去,就得到了&马&的所有可能的走步状态。可以想见,该探索树的叶子结点只可能有两种状态:一是该结点不能再派生出其他的&走步&分支了,也就是&马&走不通了;二是棋盘中的每个方格都被走到,即&马&踏遍棋盘。于是从该探索树的根结点到第二种情况的叶结点构成的路径就是马踏棋盘的行走过程。 如何才能通过搜索这棵探索树找到这条马踏棋盘的行走路径呢?可以采用深度优先搜索的方法以先序的方式访问树中的各个结点,直到访问到叶结点。如果叶结点是第二种情况的叶结点,则搜索过程可以结束,因为找到了马踏棋盘的行走路径;如果叶结点为第一种情况的叶结点,即走不通了,则需要返回到上一层的结点,顺着该结点的下一条分支继续进行深度优先搜索下去。 因此在设计&马踏棋盘&的算法时可以借鉴前面讲过的图的深度优先遍历算法和二叉树的先序遍历算法。但是在这里并不需要真正地构建这样一棵探索树,我们只需要借用探索树的思想。在实际的操作过程中,所谓的探索树实际就是深度优先搜索的探索路径,每个结点实际就是当前的棋盘状态,而所谓的叶结点要么就是在当前棋盘状态下,&马&无法再进行下一步行走;要么就是马踏棋盘成功。该算法描述可如下:int TravelChess Board (int x,int y,int tag)
chess[x][y] =
if(tag == 64)
{ return 1;}
找到&马&的下一个行走坐标(x1,y1),如果找到返回flag=1,否则返回flag=0;
while(flag ){
if(TravelChessBoard (x1,y1,tag+1))return 1; /*递归调用TravelChess ,
从x1,y1向下搜索;如果从
x1,y1往下马踏棋盘成功,返回1*/
继续找到&马&的下一个行走坐标(x1,y1),如果找到返回flag=1,否则返回flag=0;
if(flag == 0)
chess[x][y] = 0;
} 9.3 马踏棋盘(2)
清华大学出版社
我要评论(0)摘要:《妙趣横生的算法(C语言实现)》第9章综合题,,本章将列举一些经典的综合题编程实例。这些题目生动有趣,同时具有一定的难度,因此作者尽量做到讲解深入浅出,把问题讲透彻,讲清楚。同时希望读者能从中得到启发,启迪思维,提高自身的编程水平。本节为大家介绍马踏棋盘。标签:妙趣横生
妙趣横生的算法(C语言实现) Oracle帮您准确洞察各个物流环节 9.3
马踏棋盘(2) 该算法中通过函数TravelChess()递归地搜索&马&的每一种走法。其中参数x,y指定 &马& 当前走到棋盘中的位置,tag是标记变量,每走一个棋盘方格,tag自动增1,它标识着马踏棋盘的行走路线。 算法首先将当前&马&处在棋盘中的位置上添加标记tag,然后判断tag是否等于64,如果等于64,说明这是马踏棋盘的最后一步,因此搜索成功,程序应当结束,返回1。否则,找到&马&下一步可以走到的位置(x1,y1),如果找到这个位置坐标,flag置1,否则flag置0。 下面在flag为1的条件下(即找到x1,y1),递归地调用函数TravelChess()。也就是从x1,y1指定的棋盘中的位置继续向下深度搜索。如果从x1,y1向下搜索成功,即程序一直执行下去,直到tag等于64返回1,那就说明&马&已经踏遍棋盘(马踏棋盘的过程是:先走到棋盘的(x,y)位置,再从(x1,y1)向下深度搜索,走遍全棋盘),于是搜索结束,返回1;否则继续找到&马&的下一个可以行走的坐标(x1,y1),如果找到这个位置坐标,flag置1,并从(x1,y1)向下重复上述的递归搜索,否则flag置0,本次递归结束。 如果找遍当前位置(x,y)的下一个坐标(x1,y1)(一般情况是8种),但是从(x1,y1)向下继续深度优先搜索都不能成功地&马踏棋盘&(此时flag等于0),则表明当前所处的状态并不处于马踏棋盘的&行走路径&上,也就是说&马&本不应该走到(x,y)的位置上,因此将chess[x][y]置0,表明棋盘中该位置未被走过(擦掉足迹),同时返回0,程序退到上一层的探索状态。 这里应当知道,所谓当前位置(x,y)的下一个坐标(x1,y1)是指&马&下一步可以走到的地方,用坐标(x1,y1)返回。在探索树中它处在(x,y)所在的结点的子结点中,如图9-7所示。
(x,y)的下一个坐标(x1,y1)
当前位置(x,y)的下一个坐标(x1,y1)的可选个数由当前棋盘的局面决定。一般情况下是有8种可走的位置(如图9-7所示),但是如果&马&位于棋盘的边缘(如图9-7所示的探索树的根结点)或者8个可选位置中有的已被&马&前面的足迹所占据,在这两种情况下(x1,y1)的可选个数就不是8个了。 上述搜索算法相当于先序遍历探索树,只不过它不一定是将探索树完整地遍历,而是当tag等于64时,也就是棋盘被全部&踏遍&时就停止继续搜索了。 下面给出完整的程序清单供读者参考。 程序清单9-3/*--------------------------------- 9-3.c --------------------------*/
#define X 8
#define Y 8
int chess[X][Y];
int nextxy(int *x,int *y,int count) /*找到基于x、y位置的下一个可走的位置*/
switch(count)
case 0: if(*x+2&=X-1 && *y-1&=0 && chess[*x+2][*y-1]==0) {*x =*x+2;*y
= *y-1;return 1; }
case 1: if(*x+2&=X-1 && *y+1&=Y-1 && chess[*x+2][*y+1]==0) {*x = *x+2;
*y = *y+1 ;
return 1;}
case 2: if(*x+1&=X-1 && *y-2&=0 && chess[*x+1][*y-2]==0) {*x = *x+1;
*y = *y-2; return 1;}
case 3: if(*x+1&=X-1 && *y+2&=Y-1 &&chess[*x+1][*y+2]==0) {*x = *x+1;
*y = *y+2;
return 1;}
case 4: if(*x-2&=0 && *y-1&=0 && chess[*x-2][*y-1]==0) {*x = *x-2;
*y = *y-1; return 1;}
case 5: if(*x-2&=0 && *y+1&=Y-1 && chess[*x-2][*y+1]==0){*x = *x-2;
*y = *y+1; return 1;}
case 6:if(*x-1&=0 && *y-2&=0 && chess[*x-1][*y-2]==0) {*x = *x-1; *y
= *y-2;return 1;}
if(*x-1&=0 && *y+2&=Y-1 && chess[*x-1][*y+2]==0) {*x = *x-1;
*y = *y+2;
return 1;}
int TravelChessBoard(int x,int y,int tag)
/*深度优先搜索地&马踏棋盘&*/
int xx1 = x, yy1 = y, flag = 0,a,b ,count = 0 ;
chess[x][y] =
if(tag == X*Y)
{ return 1;}
flag = nextxy(&x1,&y1,count);
while(flag == 0 && count &7){
countcount = count + 1;
flag = nextxy(&x1,&y1,count);
while(flag ){
if(TravelChessBoard(x1,y1,tag+1))return 1;
xx1 =yy1 =
countcount = count +1;
flag = nextxy(&x1,&y1,count);
/*寻找下一个(x,y)*/
while(flag == 0 && count &7){
/*循环地寻找下一个(x,y)*/
countcount = count + 1;
flag = nextxy(&x1,&y1,count);
if(flag == 0)
chess[x][y] = 0;
for(i=0;i&X;i++)
for(j=0;j&Y;j++)
chess[i][j] = 0;
if(TravelChessBoard(2,0,1)) {
for(i=0;i&X;i++) {
for(j=0;j&Y;j++)
printf(&%d
&,chess[i][j]);
printf(&\n&);
printf(&The horse has travelled the chess borad\n&);
printf(&The horse cannot travel the chess board\n&);
} 9.3 马踏棋盘(3)
清华大学出版社
我要评论(0)摘要:《妙趣横生的算法(C语言实现)》第9章综合题,,本章将列举一些经典的综合题编程实例。这些题目生动有趣,同时具有一定的难度,因此作者尽量做到讲解深入浅出,把问题讲透彻,讲清楚。同时希望读者能从中得到启发,启迪思维,提高自身的编程水平。本节为大家介绍int nextxy(int *x,int *y,int count)。标签:妙趣横生
妙趣横生的算法(C语言实现) Oracle帮您准确洞察各个物流环节 9.3
马踏棋盘(3) 【程序说明】 本程序中应用二维数组chess[8][8]作为8*8的棋盘,&马&每走到棋盘的(i,j)处,就将当前的步数tag赋值给chess[i][j]。为了方便起见,将数组chess设置为外部变量。另外定义字符常量X,Y,它规定棋盘的大小。本程序清单中将X和Y都设置为8。 函数TravelChessBoard()是上述马踏棋盘算法的具体实现。本程序中初始的(x,y)位置为(2,0),说明&马&从chess[8][8]的chess[2][0]位置开始进行&马踏棋盘&的。在函数TravelChessBoard()中要调用函数nextxy()。int nextxy(int *x,int *y,int count)
函数nextxy()包含3个参数:x和y为传递下来的&马&当前踏到棋盘上的位置,它是指针变量。变量count的作用是标记调用nextxy()过程的次数,根据count值的不同,返回基于(x,y)的下一个不同的坐标,以此来避免返回同一个坐标,真正实现寻找&针对当前位置(x,y)的下一个位置&的目的。函数nextxy()的作用是找到&马&当前的位置(x,y)的下一个可以行走的位置,并通过指针修改x、y的内容,将下一个位置坐标用变量x、y返回。 &寻找(x,y)的下一个位置坐标&的操作通过代码:xx1 =
/*将坐标(x1,y1)初始化为当前访问的坐标
(x,y),因为(x,y)不能被改动*/
flag = nextxy(&x1,&y1,count);
/*寻找(x,y)下一个位置坐标(x1,y1)*/
while(flag == 0 && count &7){
/*循环地寻找(x,y)的下一个坐标*/
countcount = count + 1;
flag = nextxy(&x1,&y1,count);
实现。程序最开始将(x1,y1)初始化为当前坐标(x,y),因为&马&的当前位置坐标(x,y)不能被轻易改动。然后将&x1、&y1作为函数nextxy的参数传递,并通过参数&x1和&y1返回当前坐标(x,y)的第count个下一个坐标(x1,y1)。只有当flag为1时,才表明找到了下一个坐标,于是循环可以停止。但是如果count的值超过了7,则说明无法找到(x,y)的下一个坐标,也就说明棋走不通了。所谓当前位置(x,y)的&下一个位置&,如图9-8所示。
(点击查看大图)图9-8
(x,y)的&下一个位置&示意
图中实心的圆圈的坐标为(x,y),它周围的8个空心的圆圈1~8,为当前坐标(x,y)的可选的&下一个&坐标(x1,y1)。每次调用nextxy()都可能得到这8个坐标其中的一个,当参数count为i时,返回圆圈i所处的坐标。这样就保证了不返回同一个坐标。 如果像本程序这样将字符常量X和Y都设置为8,那么程序就执行8*8的马踏棋盘。但是这样一来会非常费时,实践证明应用本程序运算出8*8的马踏棋盘的结果要花几分钟的时间。因此读者在调试程序时可以通过设置X和Y的值减小棋盘的规格,从而更快地得到结果。 本程序的运行结果如图9-9所示。
(点击查看大图)图9-9
程序9-3的运行结果
其他类似问题
数据结构课程设计的相关知识
您可能关注的推广回答者:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁}

我要回帖

更多关于 中国象棋棋盘 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信