2014年春季学期《C项目设计》报告题目:八皇后问题学号:092213112姓名:刘泽中组名:1指导教师:宋东兴日期:2014.05.15目录正文 (3)1.问题描述 (3)2. 总体设计与分析 (3)3. 相关代码 (5)4. 调试分析 (9)5.软件使用说明书 (11)总结 (11)附录:部分原程序代码 (12)一、问题描述1.八皇后问题:是一个古老而著名的问题。
该问题是十九世纪著名的数学家高斯1850年提出:在8×8棋盘上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法?2.解决八皇后问题的关键在于:(1)找到合理的数据结构存放棋子的摆放位置。
(2)要有合理的冲突检查算法。
采用的方法是,先把8个棋子摆在棋盘上,每行摆一个,然后去检查这种摆放是否有冲突,如果没有冲突,即找到了一种解决方案。
由于皇后的摆放位置不能通过某种公式来确定,因此对于每个皇后的摆放位置都要进行试探和纠正,这就是“回溯”的思想。
在8个皇后未放置完成前,每行摆放一个皇后,摆放第i个皇后和第i+1个皇后的试探方法是相同的,因此完全可以采用递归的方法来处理。
二、总体设计与分析1.设计效果画一个8*8的国际象棋盘,在棋盘某一位置上放一棋子,并让它按从左到右的方向自动运动,用户可以使用光标键调整棋子运动的方向,找出所有可能的摆放方案,将包含指定的棋子的(如3行4列)摆放方案找出并显示出来。
2.、总体设计程序总体分为两大块:(1)八皇后摆法的寻找;(2)棋盘及棋子的设计。
3、详细模块(1)八皇后摆法的寻找:int chess[8][8]={0}; //二维数组表示8*8棋盘,全部清0,(0代表该位没有放棋子)void queen(int i,int n){ //i表示从第i行起为后续棋子选择合适位置,n代表n*n棋盘if(i==n)output(n); //输出棋盘当前布局;else{for(j=0;j<n;j++){ //每行可能有n个摆放位置chess[i][j] = 1; //在第i行,j列上放一棋子if(!canAttack(i,j)) //如果当前布局合法,不受前i-1行的攻击queen(i+1,n); //递归摆放i+1行chess[i][j] = 0; //移走第i行,j列的棋子}}}int canAttack(int i,int j){ //判断0到i-1行已摆放的棋子,对[i,j]位置是否可以攻击for(m=0;m<i;m++){for(n=0;n<8;n++){if(chess[m][n]==1){if(m==i||n==j) return 1;if(m+n==i+j || m-n==i-j) return 1;}}}return 0;}void output(){ //输出一组解,即打印出8个皇后的坐标for(int i=0;i<8;i++){for(int j=0;j<8;j++){if(chess[i][j]==1){printf("(%d,%d)",i,j);}}}printf(“\n”);}int main(){queen(0,8);return 0;}(2)棋盘及棋子的设计:void drawBlock(int i,int j){ //棋盘的设计(每一个小方块)int x0,y0,x1,y1;x0=ORGX+j*W;y0=ORGY+i*H;x1=x0+W-1;y1=y0+H-1;setcolor(WHITE);rectangle(x0,y0,x1,y1);setfillstyle(1,LIGHTGRAY);floodfill(x0+1,y0+1,WHITE);setcolor(WHITE);line(x0,y0,x1,y0);line(x0,y0,x0,y1);setcolor(BLACK);line(x1,y0,x1,y1);line(x0,y1,x1,y1);}void drawBall(Ball ball){ //棋子的设计int x0,y0;x0=ball.startX+ball.c*ball.w+ball.w/2;y0=ball.startY+ball.r*ball.h+ball.h/2;setcolor(RED);setfillstyle(1,RED);fillellipse(x0,y0,10,10);}4.程序设计思路:先设计程序,找到八皇后的摆放位置,方法是:先把8个棋子摆在棋盘上,每行摆一个,然后去检查这种摆放是否有冲突,如果没有冲突,即找到了一种解决方案。