1、黑白棋游戏课程设计湖南文理学院课程设计报告课程名称: 计算机软件技术基础 学 院: 电气与信息工程学院 专业班级: 通信08102班 * * 学 号: 200816020210 * * * * 完成时间: 2010年12月29日 报告成绩: 评阅意见: 评阅老师: 评阅时间: 黑白棋游戏C语言课程设计一、设计目的本课程设计是计算机软件技术基础重要的实践性环节之一,是在学生学习完程序设计语言(C)课程后进行的一次全面的综合练习。本课程设计的目的和任务: (1)巩固和加深学生对C语言课程的基本知识的理解和掌握;(2)掌握C语言编程和程序调试的基本技能; (3)利用C语言进行基本的软件设计,掌握软件
2、设计一般方法,了解软件设计的思路;(4)掌握书写程序设计报告的能力;(5)提高运用C语言解决实际问题的能力;这个程序也是对编程基本功的一个训练,对于初学C语言的人,讲分支、循环、数组函数综合应用,而不仅限于编制独立的小程序,能够大大提高变成水平。二、设计要求(1)收集资料,全面分析课题,分解问题,形成中体编程思路;(2)深入分析各个小问题,编写个部分程序模块;(3)对于设计中用到的关键函数,要联系实际 问题进行具体介绍;(4)上机调试,确保程序能正确运行;(5)设计完成后提交课程设计报告;三、所需仪器设备(1)硬件要求能运行Windows 2000/XP操作系统的微机系统。(2)C语言程序设计
3、及相应的开发环境。(本设计用的是Turbo C for Windows 集成实验与学习环境 V6.0)四、课题分析编写一个黑白棋游戏的C程序,包括以下功能:初始状态:在一个8*8的棋盘中央交叉排放黑白棋子各两枚,白棋先走。(1)每个棋手下棋时,摆子的位置必须是以自己的棋子能包围住对方一个或多个棋子,被包围住的对方棋子将成为自己的棋子。包围的方向可以是上下左右以及斜线8个方向,只要能连成一线即可。(2)当轮到某一个棋手下子,但是他没有可以包围对方棋子的位置时,他必须停步,让对方走棋,直到他可以走为止。(3)当棋盘上一方的棋子为0或者下满64格,游戏结束,棋子少者输。五、具体设计过程5.1、设计思
4、路程序界面应是一个二维平面图,所以数据的表示用二维数组,数组两个下标可以表示棋盘上的位置,数组元素的值代表棋格中的状态,共有三种情况,分别是空格、黑棋和白棋。这样给数组元素的取值设定为0、1、2,其中0代表空格,1代表白色棋子,2代表黑色棋子。这样程序的主要工作是接收棋手按键操作,一旦接收到回车键,说明棋手摆子,先判断是不是有效位置,也就是能不能包围住对方棋子,如果能,便为棋子所在的位置往上下、左右、左上、左下、右上、右下8个方向寻找被包围住的所有棋子(必须是连续的,中间不能有空格),将这些被包围住的对方棋子都变成自己的棋子,然后对当前棋盘中的黑白棋个数进行统计并输出结果。如果没有这样的位置可
5、以落子,则停步,让对方走棋,重复上述步骤,直到游戏结束。如果想提前终止游戏,可以按Esc键。 5.2、程序设计流程图 (1)程序整体组成结构框图如下图所示: 图1 程序整体组成结构框图(2)由上述设计思路可画出程序整体流程图,如下图所示:图2 程序整体流程图(3)人人对战模块程序流程图如下图所示: 图3 人人对战模块流程图(4) 成绩输出模块程序流程图如下图所示 图4 成绩输出模块程序流程图5.3、函数实现说明(1)main()主函数在主函数中,首先定义使用到的常数、全局变量、函数原型说明。盘状态用数组a88,初值为0,表示空格。函数的实体部分,开始初始化图形系统,然后通过调用函数DrawQp
6、()先画出棋盘,调用playtoplay()人人对战函数开始游戏,一旦游戏结束后,关闭图形系统,程序结束。(2)DrawQp()画棋盘函数背景颜色设为蓝色,从坐标(100,100)开始每隔40个单位用白色画一条水平直线,一条垂直线,构成棋盘,用循环语句实现。函数setfillstyle()可以设置填充模式和填充颜色,fillellipse(int x,int y,xradius,int yradius)以x和y为圆心,xradius和yradius为水平和垂直轴画一填充椭圆,当xradius和yradius相等时,则画出的是圆,用它表示棋子。(3)SetPlayColor()设置棋子的颜色 函
7、数的参数为整型变量t,根据t的值来设计填充棋子的当前颜色,值为1代表白棋,值为2代表黑棋。(4)MoveColor()恢复原来格子的状态由于棋手在走棋的时候,他的棋子总是首先出现在棋盘的左上角,棋手要通过移动光标走到要落子的位置,在经过的路程上显示当前棋子,就会覆盖原来的棋盘状态,所以一旦棋子走过后,就应恢复原来的状态,是空格的依然显示空格,是棋子的就显示原来棋子的颜色。因为棋子移动过程并没有改变数组元素的值,所以可以根据数组元素的值判定原来的状态,如果值是1,就恢复白色棋子,值是2则恢复黑色棋子,否则恢复蓝色空格。(5)、playtoplay()人人对战函数 这是游戏进行的函数,主要是接收棋
8、手的按键消息,其处理过程如下: 1)按Esc键程序可以随时结束。 2)按上下左右光标键,则改变棋子移动的坐标值。 3)按回车键后判断: 如落子的位置已经有棋则无效,继续压键。 如落子位置是空格,可以将棋子落入格内,调用函数QpChange()判断是否引起棋盘的变化,函数值为1有变化,为0没变化。如果棋盘有变化,说明将包围的对方棋子吃掉,统计当前分数,如果棋盘没有变化,则说明落子的位置无法包围对方的棋子也视为无效棋,可以继续寻找合适的位置,但开始统计其落子次数,一旦尝试次数超过当前棋盘的空格数,则说明他无棋可走,则放弃此步,让对方下棋。 如果棋子变化后,格子已占满64格或一方棋子为0,则游戏结束
9、,显示胜利方信息。按任意键程序结束。 重复上述步骤,直到游戏结束。(6)、QpChange()判断棋盘变化当棋手按回车键落子后,就要分别往8个方向判断是否包围住对方棋子,如果是,则改变棋盘,也就是棋盘上黑白棋子的个数要发生变化。如果所有方向都判断过,并且没有引起棋盘的变化,则棋盘变化标志值yes为0,返回yes,结束本函数。(7)、DoScore()处理分数 根据当前数组元素的值判断分数,也就是各方棋子的个数,如果数组元素值为1,白棋棋子数累加;如果数组元素值为2,则黑棋棋子数累加。(8)、PrintScore()输出成绩 利用设置实体填充模式填充矩形条清除掉前次的成绩,再利用sprintf(
10、)函数将整数转换为字符串的形式,再利用outtextxy()函数将成绩输出。(9)、playWin()输出胜利者结果 根据分数值score1和score2的大小得出下棋的结果,输出赢者信息。如果是白方胜就输出“white win!”,黑方胜就输出“black win!”,平局就输出“you all win!”。5.4、图形库函数介绍图形库 是TC里面的图形库,分为:像素函数、直线和线型函数、多边形函数、填充函数等。在本程序中主要应用到了以下功能函数:(1)、line() 画线函数功能: 函数line()使用当前绘图色、线型及线宽,在给定的两点间画一直线。 函数原型: void line(int
11、 startx,int starty,int endx,int endy); 说明: 参数startx,starty为起点坐标,endx,endy为终点坐标,函数调用前后,图形状态下屏幕光标(一般不可见)当前位置不改变。 (2)、setcolor()图形屏幕函数 函数原型:void setcolor(int color) 功能:将当前图形屏幕的当前笔画颜色置为color.(3)、setfillstyle() 设置填充图样和颜色函数函数原型: void far setfillstyle(int pattern, int color);功 能: 设置填充模式和颜色 (4)、fillellipse(
12、) 画椭圆区函数功 能: 画出并填充一椭圆 函数原型: void far fillellipse(int x, int y, int xradius, int yradius); 说明:填充边框所定义的椭圆的内部,该边框由一对坐标、一个宽度和一个高度指定。(5)、setbkcolor()功能:该函数用指定的颜色值来设置当前的背景色函数原型:Void far SetBkColor(int Color );(6)、C语言中的颜色表及填充模式如下两表所示:5.5、程序源代码及注释 #include graphics.h /*图形系统头文件*/#define LEFT 0x4b00 /*光标左键值*/
13、#define RIGHT 0x4d00 /*光标右键值*/#define DOWN 0x5000 /*光标下键值*/#define UP 0x4800 /*光标上键值*/#define ESC 0x011b /* ESC键值*/#define ENTER 0x1c0d /* 回车键值*/int a88=0,key,score1,score2;/*具体分数以及按键与存放棋子的变量*/char playone3,playtwo3;/*两个人的得分转换成字符串输出*/void playtoplay(void);/*人人对战函数*/void DrawQp(void);/*画棋盘函数*/void Se
14、tPlayColor(int x);/*设置棋子第一次的颜色*/void MoveColor(int x,int y);/*恢复原来棋盘状态*/int QpChange(int x,int y,int z);/*判断棋盘的变化*/void DoScore(void);/*处理分数*/void PrintScore(int n);/*输出成绩*/void playWin(void);/*输出胜利者信息*/*主函数*/void main(void)int gd=DETECT,gr;initgraph(&gd,&gr,c:tc); /*初始化图形系统*/DrawQp();/*画棋盘*/playtop
15、lay();/*人人对战*/getch();closegraph();/*关闭图形系统*/void DrawQp()/*画棋盘*/int i,j;score1=score2=0;/*棋手一开始得分都为0*/setbkcolor(BLUE);for(i=100;i=64-score1-score2) /*如果尝试超过空格数则停步*/MoveColor(x,y);fillellipse(x,y,15,15);break;elsecontinue;/*如果按键无效*/DoScore();/*分数的改变*/break;/*棋盘变化了,则轮对方走棋*/else/*已经有棋子就继续按键*/continue
16、;else /*四个方向按键的判断*/if(key=LEFT&x120)/*左方向键*/MoveColor(x,y);fillellipse(x,y,15,15);SetPlayColor(t);x-=40;fillellipse(x,y,15,15);elseif(key=RIGHT&x80)/*右方向键*/MoveColor(x,y);fillellipse(x,y,15,15);SetPlayColor(t);x+=40;fillellipse(x,y,15,15);elseif(key=UP&y120)/*上方向键*/MoveColor(x,y);fillellipse(x,y,15,
17、15);SetPlayColor(t);y-=40;fillellipse(x,y,15,15);elseif(key=DOWN&y400)/*下方向键*/MoveColor(x,y);fillellipse(x,y,15,15);SetPlayColor(t);y+=40;fillellipse(x,y,15,15);if(key=ESC)/*结束游戏*/break;if(score1+score2)=64|score1=0|score2=0)/*格子已经占满或一方棋子为0判断胜负*/playWin();/*输出最后结果*/break;t=t%2+1; /*一方走后,改变棋子颜色即轮对方走*
18、/cc=0; /*计数值恢复为0*/ /*endwhile*/void SetPlayColor(int t)/*设置棋子颜色*/if(t%2=1)setfillstyle(SOLID_FILL,15);/*白色*/elsesetfillstyle(SOLID_FILL,8);/*灰色*/void MoveColor(int x,int y)/*走了一步后恢复原来格子的状态*/if(y100)/*如果是从起点出发就恢复蓝色*/setfillstyle(SOLID_FILL,BLUE);else/*其他情况如果是1就恢复白色棋子,2恢复黑色棋子,或恢复蓝色棋盘*/switch(a(x-120)/
19、40(y-120)/40)case 1:setfillstyle(SOLID_FILL,15);break; /*白色*/case 2:setfillstyle(SOLID_FILL,8);break; /*黑色*/default:setfillstyle(SOLID_FILL,BLUE); /*蓝色*/int QpChange(int x,int y,int t)/*判断棋盘的变化*/int i,j,k,kk,ii,jj,yes;yes=0;i=(x-120)/40; /*计算数组元素的行下标*/j=(y-120)/40; /*计算数组元素的列下标*/SetPlayColor(t);/*设置
20、棋子变化的颜色*/*开始往8个方向判断变化*/if(j6)/*往右边*/for(k=j+1;k8;k+)if(aik=aij|aik=0)/*遇到自己的棋子或空格结束*/break;if(aik!=0&k8)for(kk=j+1;kkk&k1)/*判断左边*/for(k=j-1;k=0;k-)if(aik=aij|!aik)break;if(aik!=0&k=0)for(kk=j-1;kkk&k=0;kk-)aikk=aij;fillellipse(120+i*40,120+kk*40,15,15);if(kk!=j-1)yes=1;if(i6)/*判断下边*/for(k=i+1;k8;k+)
21、if(akj=aij|!akj)break;if(akj!=0&k8)for(kk=i+1;kkk&k1)/*判断上边*/for(k=i-1;k=0;k-)if(akj=aij|!akj)break;if(akj!=0&k=0)for(kk=i-1;kkk&k=0;kk-)akkj=aij;fillellipse(120+kk*40,120+j*40,15,15);if(kk!=i-1)yes=1;if(i1&j=0&kk=0&kkk&k=0;ii-,jj+)aiijj=aij;fillellipse(120+ii*40,120+jj*40,15,15);if(ii!=i-1)yes=1;if
22、(i1)/*左下*/for(k=i+1,kk=j-1;k=0;k+,kk-)if(akkk=aij|!akkk)break;if(akkk!=0&k=0)for(ii=i+1,jj=j-1;iik&k1&j1)/*左上*/for(k=i-1,kk=j-1;k=0&kk=0;k-,kk-)if(akkk=aij|!akkk)break;if(akkk!=0&k=0&kk=0)for(ii=i-1,jj=j-1;iik&k=0;ii-,jj-)aiijj=aij;fillellipse(120+ii*40,120+jj*40,15,15);if(ii!=i-1)yes=1;if(i6&j6)/*
23、右下*/for(k=i+1,kk=j+1;kk8&kk8;k+,kk+)if(akkk=aij|!akkk)break;if(akkk!=0&kk8&k8)for(ii=i+1,jj=j+1;iik&k8;ii+,jj+)aiijj=aij;fillellipse(120+ii*40,120+jj*40,15,15);if(ii!=i+1)yes=1;return yes;/*返回是否改变过棋子颜色的标记*/void DoScore()/*处理分数*/int i,j;score1=score2=0;/*重新开始计分数*/for(i=0;i8;i+)for(j=0;j8;j+)if(aij=1)/*分别统计两个人的分数*/score1+;elseif(aij=2)score2+;void PrintScore(int playnum)/*输出成绩*/if(playnum=1)/*
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1