实验报告马踏棋盘.docx
- 文档编号:4546768
- 上传时间:2022-12-06
- 格式:DOCX
- 页数:11
- 大小:69.51KB
实验报告马踏棋盘.docx
《实验报告马踏棋盘.docx》由会员分享,可在线阅读,更多相关《实验报告马踏棋盘.docx(11页珍藏版)》请在冰豆网上搜索。
实验报告马踏棋盘
2.4题马踏棋盘
题目:
设计一个国际象棋的马踏棋盘的演示程序
班级:
:
学号:
完成日期:
一.需求分析
(1) 输入的形式和输入值的围:
输入马的初始行坐标X和列坐标Y,
X和Y的围都是[1,8]。
(2) 输出形式:
以数组下表的形式输入,i为行标,j为列标,用空格符号隔开。
以棋盘形式输出,每一格打印马走的步数,这种方式比较直观
(3) 程序所能达到的功能:
让马从任意起点出发都能够遍历整个8*8的
棋盘。
(4) 测试数据,包括正确输入及输出结果和含有错误的输入及其输出结
果。
数据可以任定,只要1<=x,y<=8就可以了。
正确的输出结果为一个二维数组,每个元素的值表示马行走的第几步,若输入有错,则程序会显示:
“输入有误!
请重新输入……”并且要求用户重新输入数据,直至输入正确为止。
二.概要设计
(1)、位置的存储表示方式
(2) typedef struct {
int x;
int y;
int from;
}Point;
(2)、栈的存储方式
#define STACKSIZE 70
#define STACKINCREASE 10
typedef struct Stack {
Point *top;
Point *base;
int stacksize;
};
(1)、设定栈的抽象数据类型定义:
ADT Stack {
数据对象:
D={ai | ai∈ElemSet,i=1,2,„,n,n≥0}
数据关系:
R1={
约定an端为栈顶,ai端为栈顶。
基本操作:
InitStack(&s)
操作结果:
构造一个空栈s,
DestroyStack(&s)
初始条件:
栈s已存在。
操作结果:
栈s被销毁。
ClearStack(&s)
初始条件:
栈s已存在。
操作结果:
栈s清为空栈。
StackEmpty(&s)
初始条件:
栈s已存在。
操作结果:
若栈s为空栈,则返回TRUE,否则返回FALSE。
StackLength(s);
初始条件:
栈s存在。
操作结果:
返回s的元素个数,即栈的长度。
GetTop (s,&e);
初始条件:
栈s已存在且非空。
操作结果:
用e返回s的栈顶元素。
Push(&s,e)
初始条件:
栈s已存在。
操作结果:
插入元素e为新的栈顶元素。
Pop(&s,&e)
初始条件:
栈s存在且非空。
操作结果:
删除栈顶元素,并用e返回。
stackTraverse(s,visit())
初始条件:
栈s存在且非空。
操作结果:
从栈底到栈顶依次对s的每个元素调用visit()。
一旦visit()失败,则操作失败。
}ADT Stack
本程序包含模块:
1、主程序模块:
void main(){定义变量;接受命令;处理命令;退出;}
2、起始坐标函数模块——马儿在棋盘上的起始位置;
3、探寻路径函数模块——马儿每个方向进行尝试,直到试完整个棋盘;
4、输出路径函数模块——输出马儿行走的路径;
三.详细设计
1.函数声明
VoidInitLocation(intxi,int yi); //马儿在棋盘上的起始位置标 int TryPath(int i,int j); //马儿每个方向进行尝试,直到试完整个棋盘
void Display(); //输出马儿行走的路径 2. 起始坐标函数模块
void InitLocation(int xi,int yi) {
int x,y; //定义棋盘的横纵坐标变量
top++; //栈指针指向第一个栈首
stack[top].i=xi; //将起始位置的横坐标进栈
stack[top].j=yi; //将起始位置的纵坐标进栈
stack[top].director=-1; //将起始位置的尝试方向赋初值
board[xi][yi]=top+1; //标记棋盘
x=stack[top].i; //将起始位置的横坐标赋给棋盘的横标
y=stack[top].j; //将起始位置的纵坐标赋给棋盘的纵坐标
if(TryPath(x,y)) //调用马儿探寻函数,如果马儿探寻整个棋盘返回1否则0
Display(); //输出马儿的行走路径 else
printf("无解");
}
3. 探寻路径函数模块
int TryPath(int i,int j) {
int find,director,number,min; //定义几个临时变量
int i1,j1,h,k,s; //定义几个临时变量
int a[8],b1[8],b2[8],d[8]; //定义几个临时数组
while(top>-1) //栈不空时循环
{
for(h=0;h<8;h++) //用数组a[8]记录当前位置的下一个位置的可行路径的条数
{
number=0;
i=stack[top].i+Htry1[h];
j=stack[top].j+Htry2[h];
b1[h]=i;
b2[h]=j;
if(board[i][j]==0&&i>=0&&i<8&&j>=0&&j<8) //如果找到下一位置
{
for(k=0;k<8;k++)
{
i1=b1[h]+Htry1[k];
j1=b2[h]+Htry2[k];
if(board[i1][j1]==0&&i1>=0&&i1<8&&j1>=0&&j1<8) //如果找到下一位置
number++; //记录条数
}
a[h]=number; //将条数存入数组a[8]中
}
}
for(h=0;h<8;h++) //根据可行路径条数小到大按下表排序放d[8]中
{
min=9;
for(k=0;k<8;k++)
if(min>a[k])
{
min=a[k];
d[h]=k; //将下表存入数组d[8]中
s=k;
}
a[s]=9;
}
director=stack[top].director;
if(top>=63) //如果走完整个棋盘返回1
return
(1);
find=0; //表示没有找到下一个位置
for(h=director+1;h<8;h++) //向八个方向进行探寻
{ i=stack[top].i+Htry1[d[h]];
j=stack[top].j+Htry2[d[h]];
if(board[i][j]==0&&i>=0&&i<8&&j>=0&&j<8) //如果找到下一位置
{
find=1; //表示找到下一个位置
Break;
}
}
if(find==1) //如果找到下一个位置进栈
{
stack[top].director=director; //存储栈结点的方向
top++; //栈指针前移进栈
stack[top].i=i;
stack[top].j=j;
stack[top].director=-1; //重新初始化下一栈结点的尝试方向
board[i][j]=top+1; //标记棋盘
}
else //否则退栈
{
board[stack[top].i][stack[top].j]=0; //清除棋盘的标记
top--; //栈指针前移退栈
}
}
return (0);
}
4. 输出路径函数模块
void Display()
{
int i,j;
for(i=0;i { for(j=0;j printf("\t%d ",board[i][j]); //输出马儿在棋盘上走过的路径 printf("\n\n"); } printf("\n"); } 四、测试数据及测试结果 测试数据: x=2,y=3 测试结果如下: 五.原程序代码 #include #define MAXSIZE 100 #define N 8 int board[8][8]; //定义棋盘 int Htry1[8]={1,-1,-2,2,2,1,-1,-2}; /*存储马各个出口位置相对当前位置行下标的*/ int Htry2[8]={2,-2,1,1,-1,-2,2,-1}; /*存储马各个出口位置相对当前位置列下标的增量数组*/ struct Stack{ //定义栈类型 int i; //行坐标 int j; //列坐标 int director; //存储方向 }stack[MAXSIZE]; //定义一个栈数组 int top=-1; //栈指针 void InitLocation(int xi,int yi); //马儿在棋盘上的起始位置坐标 int TryPath(int i,int j); //马儿每个方向进行尝试,直到试完整个棋盘 void Display(); //输出马儿行走的路径 void InitLocation(int xi,int yi) { int x,y; //定义棋盘的横纵坐标变量 top++; //栈指针指向第一个栈首 stack[top].i=xi; //将起始位置的横坐标进栈 stack[top].j=yi; //将起始位置的纵坐标进栈 stack[top].director=-1; //将起始位置的尝试方向赋初值 board[xi][yi]=top+1; //标记棋盘 x=stack[top].i; //将起始位置的横坐标赋给棋盘的横坐标 y=stack[top].j; //将起始位置的纵坐标赋给棋盘的纵坐标 if(TryPath(x,y)) //调用马儿探寻函数,如果马儿探寻整个棋盘返回1否则返回0 Display(); //输出马儿的行走路径 else printf("无解"); } int TryPath(int i,int j) { int find,director,number,min; //定义几个临时变量 int i1,j1,h,k,s; //定义几个临时变量 int a[8],b1[8],b2[8],d[8]; //定义几个临时数组 while(top>-1) //栈不空时循环 { for(h=0;h<8;h++) //用数组a[8]记录当前位置的下一个位置的可行路径的条数 { number=0; i=stack[top].i+Htry1[h]; j=stack[top].j+Htry2[h]; b1[h]=i; b2[h]=j; if(board[i][j]==0&&i>=0&&i<8&&j>=0&&j<8) //如果找到下一位置 { for(k=0;k<8;k++) { i1=b1[h]+Htry1[k]; j1=b2[h]+Htry2[k]; if(board[i1][j1]==0&&i1>=0&&i1<8&&j1>=0&&j1<8) //如果找到下一位置 number++; //记录条数 } a[h]=number; //将条数存入数组a[8]中 } } for(h=0;h<8;h++) //根据可行路径条数小到大按下表排序放 入数组d[8]中 { min=9; for(k=0;k<8;k++) If(min>a[k]) { min=a[k]; d[h]=k; //将下表存入数组d[8]中 s=k; } a[s]=9; } director=stack[top].director; if(top>=63) //如果走完整个棋盘返回1 return (1); find=0; //表示没有找到下一个位置 for(h=director+1;h<8;h++) //向八个方向进行探寻 { i=stack[top].i+Htry1[d[h]]; j=stack[top].j+Htry2[d[h]]; if(board[i][j]==0&&i>=0&&i<8&&j>=0&&j<8) //如果找到下一位置 { find=1; //表示找到下一个位置 break; } } if(find==1) //如果找到下一个位置进栈 { stack[top].director=director; //存储栈结点的方向 top++; //栈指针前移进栈 stack[top].i=i; stack[top].j=j; stack[top].director=-1; //重新初始化下一栈结点的尝试方向 board[i][j]=top+1; //标记棋盘 } else //否则退栈 { board[stack[top].i][stack[top].j]=0; //清除棋盘的标记 top--; //栈指针前移退栈 } } return (0); } void Display() { int i,j; for(i=0;i { for(j=0;j printf("\t%d ",board[i][j]); //输出马儿在棋盘上走过的路径 printf("\n\n"); } printf("\n"); } int main() { int i,j; int x,y; for(i=0;i for(j=0;j board[i][j]=0; for(;;) { printf("Please input importpoint(1<=x<=8 and 1<=y<=8)\n"); printf("Input x = "); scanf("%d",&x); //输入起始位置的横坐标 printf("Input y = "); scanf("%d",&y); //输入起始位置的纵坐标 if(x>=1&&x<=8&&y>=1&&y<=8)break; printf("Your input is worng! ! ! \n"); } printf("begin with %d board: \n\n", 8*(x-1)+y); InitLocation(x-1,y-1); //调用起始坐标函数 }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 报告 棋盘