C语言程序设计课程设计(论文)-黑白棋.doc

上传人:小小飞 文档编号:3901886 上传时间:2019-10-09 格式:DOC 页数:20 大小:110KB
返回 下载 相关 举报
C语言程序设计课程设计(论文)-黑白棋.doc_第1页
第1页 / 共20页
C语言程序设计课程设计(论文)-黑白棋.doc_第2页
第2页 / 共20页
C语言程序设计课程设计(论文)-黑白棋.doc_第3页
第3页 / 共20页
C语言程序设计课程设计(论文)-黑白棋.doc_第4页
第4页 / 共20页
C语言程序设计课程设计(论文)-黑白棋.doc_第5页
第5页 / 共20页
点击查看更多>>
资源描述

《C语言程序设计课程设计(论文)-黑白棋.doc》由会员分享,可在线阅读,更多相关《C语言程序设计课程设计(论文)-黑白棋.doc(20页珍藏版)》请在三一文库上搜索。

1、- 大 学 C语言程序设计 课程设计(论文)题目: 黑白棋 院(系): 专业班级: 学 号: 学生姓名: 指导教师: 教师职称: 起止时间: 课程设计(报告)任务及评语院(系): 教研室:学 号学生姓名专业班级程序设计(报告)题目黑白棋程序设计(报告)任务程序设计的任务与要求:(1)掌握C语言编程的基础知识。(2)较熟练地编写C语言应用程序。(3)了解C语言的常用标准函数、编程技巧、异常处理。(5)联系已学过的内容,巩固所学的理论,增强独立工作能力。(6)通过设计主要使学生有一个独立编写程序的过程,对理论学习及动手能力都有一个很大的提高。(7)通过本次设计,进一步培养学生热爱专业的思想,同时对

2、本专业综合素质的提高起一个积极的推动作用。课程设计过程中,要严格遵守实践环节的时间安排,听从指导教师的指导。正确地完成上述内容,记录实习日记,规范完整地撰写出课程设计报告。指导教师评语及成绩成绩: 指导教师签字: 2011 年 1 月 4 日辽 宁 工 业 大 学 课 程 设 计 说 明 书(论 文)目 录第1章 课程设计的目的与要求11.1 课程设计目的11.2 课程设计的实验环境11.3 课程设计的预备知识11.4 课程设计要求1第2章 课程设计内容22.1程序功能介绍22.2程序整体设计说明22.2.1设计思路22.2.2数据结构设计及用法说明22.2.3程序结构(流程图)72.2.4各

3、模块的功能及程序说明82.2.5程序结果102.3程序源代码及注释11第3章 课程设计总结16参考资料 17第1章 课程设计的目的与要求1.1 课程设计目的本课程设计是计算机科学与技术专业重要的实践性环节之一,是在学生学习完程序设计语言(C)课程后进行的一次全面的综合练习。本课程设计的目的和任务: 1. 巩固和加深学生对C语言课程的基本知识的理解和掌握 2. 掌握C语言编程和程序调试的基本技能 3. 利用C语言进行基本的软件设计4. 掌握书写程序设计说明文档的能力5. 提高运用C语言解决实际问题的能力6.了解C语言与函数的关系7.掌握一些初等函数1.2 课程设计的实验环境硬件要求能运行Wind

4、ows 2000/XP操作系统的微机系统。C语言程序设计及相应的开发环境。1.3 课程设计的预备知识熟悉C语言及C语言开发工具。1.4 课程设计要求1. 分析课程设计题目的要求2. 写出详细设计说明3. 编写程序代码,调试程序使其能正确运行4. 设计完成的软件要便于操作和使用5. 设计完成后提交课程设计报告第2章 课程设计内容2.1程序功能介绍这种棋通常是黑白两个面。一方执白,一方执黑,每次在棋盘上走一个子。无论横竖线或斜线均可。只要两个同样颜色的将另一个颜色的夹在中间了,就可以将这个颜色翻过来,最终看哪个要色多,即获胜。我认为胜利的根本是占边。2.2程序整体设计说明2.2.1设计思路首先可以

5、用二维数组表示棋盘(比方可以是int,元素为“1”表示玩家甲的棋子,“2”表示玩家乙.) ,然后写一个函数实现如下功能: 每下一子,就利用下标检测此子周围8个元素(边上的没有这么多,就要通过下标的限制了)有没有相同的,有的话,累计(要考虑分4种情况累计,横竖斜),并调用相应方向的函数检测那些相同的元素,没有就跳过继续。 再写四个函数(检测横竖斜4个方向的) 最后主函数完善。2.2.2数据结构设计及用法说明 现在有如图示的这样一个棋局,轮到电脑下棋。现在它发现有这样三个地方可以下:e3,c3,c5。这三种下法分别会形成三种局面:A、B、C。如果是人在下棋,就会思考:那一种下法更好呢?比如A被别人

6、占角,B没什么变化,C占了别人的角。当然棋手会选择下C。电脑也是如此,它会对每一种棋局评一个分,比如它判断,如果被别人占角,就减80分,相反占别人的角就加80分。那么A=-80分,B=0分,C=80分。电脑会选择下C。电脑程序对棋局评分的部分,称为“估值函数”(Evaluation Function)。真正的估值函数当然不会这么简单。它会用到技巧篇提到的如行动力、潜在行动力、余裕手、边角判断、稳定子等综合因素来判断。具体的估值函数,我会在“估值函数”一节中详细讲述。初始棋局(-1)-+-| | |e3 c3 c5(A) (B) (C) 接下来,如果人就这么判断。那么它顶多也就是个初学者。为什么

7、呢?因为它不会推理,碰到对手弃角之类的战术,如“边角判断”中示例的一些情况,就输得一塌糊涂了。当然,可以告诉电脑,碰到“边角判断”中的几种情况,就如何如何下。但是,真实的棋局是非常复杂的,电脑(也包括人脑)几乎不可能对动态的棋局给出静态的评估。因为实际对局总会出现这样那样的情况,是无法预先估计的。碰到这些情况,人就会向后推几步,看一看会是怎样的一个局面。一些棋类大师往往可以推十几步甚至更深。电脑也是如此。 还是刚才那一幅图的演化。甲方下棋-乙方下棋-初始棋局-+-| | |e3 c3 c5-+- -+- -+-| | | | | | | | | | | | | |f2 f3 f4 f5 f6

8、c2 d3 e6 f5 b6 c6 d6 e6 f6 +84+36+12 +5 -1+11 -1 +6 +6 +6 +0 -5 +3 +5 电脑在自己下棋以后,把对手的下棋情况也推理出来。然后加以评分。(最下一排是电脑评估的得分)这一次电脑又如何下呢?这时电脑假设对手是高手。如果电脑下e3,对手就会下对电脑最不利的情况f6。同样,电脑下c3,对手就会下d3,电脑下c5,对手就会下d6。这三种情况,c5是最不好的(因为c5的下一步d6的得分最低),c3与e3一样。因此电脑会下c3或者e3。用程序化的语言这样描述: 如上图所示棋局,设电脑为白棋,推理深度为2,可以形成如下的树:(数字为节点值)初始

9、棋局-白棋下棋之后-黑棋下棋之后估值初始棋局(-1)-+-| | |e3(-1) c3(-1) c5(-5)-+- -+- -+-| | | | | | | | | | | | | |f2 f3 f4 f5 f6 c2 d3 e6 f5 b6 c6 d6 e6 f6 +84+36+12 +5 -1+11 -1 +6 +6 +6 +0 -5 +3 +5 结果:应该下e3或c3具体实现的伪算法类似于经典的八皇后问题。还有几种alpha-beta算法的改进型,最广泛采用的是NegaScout,(Alexander Reinefeld发明),但它和一般的alpha-beta剪枝算法没有根本的不同。其他

10、的还有PVS和SSS*。下面举例说明。 还是基于刚才的棋形,假设先搜索e3-f2 f3 f4 f5 f6、再c3-c2 d3 e6 f5、再c5-b6 c6 d6 e6 f6,即从左至右的顺序的深度优先搜索。则搜索到d3分枝之后,就不用搜索e6和f5了。因为如果接下来的值比d3大,就不会赋值给c3,如果比d3小,赋值给c3后,也不会赋给根节点,因为根节点取最大的值,现在根节点的值是-1,不会取更小的值。同样的,搜索d6后,也不用搜索e6、f6了,也就是说,搜索到比-1还小的值之后,就不用搜索了。 在搜索过程中,电脑下棋结点的当前最优值被称为 值(即初始棋局的值),对手下棋结点的当前最优值被称为

11、 值(即例子中C3的值)。在搜索过程中, 值递增,值递减,两者构成了一个区间。这个区间被称为窗口,而对手下棋的结点最终的最优值将落在这个窗口中。一旦在电脑下棋的结点得到其子结点的返回值大于 值,则发生剪枝。初始棋局(-1)-+-| | |e3(-1) c3(-1) c5(-5)-+- -+- -+-| | | | | | | | | | | | | |f2 f3 f4 f5 f6 c2 d3 e6 f5 b6 c6 d6 e6 f6+84+36+12 +5 -1+11 -1 +6 +6 +6 +0 -5 +3 +5这是一个程序中最重要的部分,如果这个模块太弱,则就算算法再好也没有用。这里将要叙

12、述三种不同的估值函数范例。大多数的黑白棋程序都可以归结于此。 1、棋格表 这种算法的意思是,不同的棋格有不同的值,角的值大而角旁边的格子值要小。忽视对称的话,棋盘上有10个不同的位置,每个格子根据三种可能性赋值:黑棋、白棋和空。更有经验的逼近是在游戏的不同阶段对格子赋予不同的值。例如,角在开局阶段和中局开始阶段比终局阶段更重要。 2、基于行动力的估值 这种更久远的接近有很强的全局观,而不像棋格表那样局部化。观察表明,许多人类玩者努力获得最大的行动力(可下棋的数目)和潜在行动力(临近对手棋子的空格,见技巧篇)。如果代码有效率的话,可以很快发现,它们提高棋力很多。和另一种人类的策略一样,许多基于行

13、动力估值的程序同时还有一些边角配置的知识,试图在中盘早期使棋子最少。3、基于模版的估值 正如上面提及的,许多中等力量的程序经常合并一些边角判断的知识,最大行动力和潜在行动力是全局特性,但是他们可以被切割成局部配置,再加在一起。棋子最少化也是如此。 这导致了以下的概括:在估值函数中仅用局部配置(模版),通常单独计算每一行、一列、斜边和角落的模板,再线性叠加在一起来实现。并且,配置情况的值非常依赖于游戏的不同阶段。比如,一条边有3321种配置情况(38-34)/2+34),每种情况的分值好坏在游戏的不同阶段都不相同。分值基于强力玩者和程序的游戏结果统计,他们存于数据库中,游戏启动时自动调入。 常见

14、的有这样一些模板: 表2.1数据表名称类似区域配置数去掉对称后的配置数corner5x2a1:e2310=59049(310-35)/2+35 = 29646diag5a5:e135 =243(35 -33)/2+33 = 135diag6a6:f136 =729(36 -33)/2+33 = 378diag7a7:g137 =2187(37 -34)/2+34 = 1134diag8a8:h138 =6561(38 -34)/2+34 = 3321edge2xa1:h1 + b2 + g2310=59049(310-35)/2+35 = 29646hor2a2:h238 =6561(38 -

15、34)/2+34 = 3321hor3a3:h338 =6561(38 -34)/2+34 = 3321hor4a4:h438 =6561(38 -34)/2+34 = 3321trianglea1:a4:d1310=59049(310-35)/2+35 = 296464、估值合并 一般程序的估值基于许多的参数,如行动力、潜在行动力、余裕手、边角判断、稳定子(见技巧篇)。但是怎么样将他们合并起来得到一个估值呢?为了提高速度,一般的程序采用线性合并。设a1,a2,a3,a4为参数,则估值s:=n1*a1+n2*a2+n3*a3+n4*a4。其中n1,n2,n3,n4为常数,术语叫“权重”(wei

16、ght),它决定了参数的重要性,来自于统计值。所的强力程序都采用了开局定式,许多顶级程序的定式大多来自IOS游戏。对于强力的程序而言,他会在每一次对局结束以后升级定式,因此,对于有自学习功能的电脑来说,用上一次击败电脑的战术对付电脑是不会管用的。另一方面,具有自学习功能的电脑的中局棋力也会越来越强,原因是电脑会通过不断升级估值函数的权重来提高棋力。TD(Temporal Difference)就是一个实用的强化学习技术。一个应用了该技术的国际象棋程序在国际互联网上进行了300多局对局后,其等级分从1650分(一般水平)上涨到了2110分。5、终局 终局是电脑的强项,它的搜索比中局快得多,主要有

17、这样几个理由:1.终局的估值函数很简单,他只用看双方谁胜了,估值就等于电脑的棋子减去对手的棋子。而不用判断行动力、潜在行动力、余裕手、边角判断和稳定子。2.终局的搜索由于空格越来越少,使得搜索节点很少。如深度为5的搜索,中盘时叶子节点平均为10*10*10*10*10=100000,而终局时最大为5*4*3*2*1=120。3.哈希表在终局时效率更高。 因为随着游戏向终局接近,玩者可下的位置逐渐减少,在终局阶段程序可以搜索得更深。这使得他们在终局比人类下得更好。看计算机在终局下棋经常感到不可思议,因为双方都在游戏结束20步以前知道了游戏的结果。对计算机而言,终局早在人类玩家中局结尾时就开始了,

18、离游戏结束还有20-30步。2.2.3程序结构(流程图)此流程图为初始画棋盘部分图2.1与人机对战部分流程图2.2.4各模块的功能及程序说明黑白棋程序的整体流程是主函数main()通过调用图形系统初始化函数initgraph()、棋盘绘制函数DrawQp()、对战函数Playtoplay()以及关闭图形系统函数closegraph()来实现游戏程序。函数DrawQp()绘制棋盘并进行游戏状态初始化。对战函数playtoplay()使用两个嵌套的while循环来模拟走棋的过程,外层循环用来变换棋手,内层循环用来模拟棋手的具体走棋过程,关键是调用函数QpChange()来判断棋盘的变化。按Esc键

19、直接退出游戏。除此之外,实现黑白棋游戏的其他函数包括SetPlayColor()、MoveColor()、DoScore() 、PrintScore()等。函数SetPlayColor()用来设置棋子的初始颜色为黑色和白色。函数MoveColor()完成恢复棋盘原始状态的功能:棋手每走完一步棋后,该函数恢复棋盘格子的原始状态,即如果是从起点出发就将格子恢复为红色,其他情况如果是1,则恢复白色棋子,是2则恢复黑色棋子。函数DoScore()用来处理棋手所得的分数。函数PrintScore()完成在不同的位置输出棋手的成绩。函数PlayWin()输出最后胜利者的结果信息。黑白棋游戏的棋盘由8*8个

20、格子组成,每个格子的大小为40*40的屏幕像速。棋盘左上角的坐标为(100,100),右下角的坐标为(420,420),棋盘左上角格子的中心坐标为x=120,y=120.游戏中棋子为半径15像速的圆,分别填充为黑色和白色。程序采用8*8二维数组Map来存放对局双方对弈情况即双方在棋盘上的对弈棋子。数组元素Map00在棋盘左上角第一个位置相对应,数组元素Map01与棋盘第一行第二个位置相对应,以此类推。因此,数组元素Map70对应着棋盘左下角的落子位置,元素Map77对应着棋盘右下角位置棋子。程序约定:数组元素值为1代表黑方,2代表白方,否则说明棋盘上该位置对弈双方尚未落子。棋手下棋时,棋子每次

21、都在棋盘左上方的初始位置(120,80)出现,以供游戏者移动。程序中用变量x、y分别代表当前棋子的横、纵坐标(x、y)。用下棋手数t来标识对弈棋手,t不能被2整除则代表黑方,能被2整除则代表白方棋手。因此根据下棋手数t记录黑、白双方对弈棋局Map的代码为:If(t%2=1) /*黑方棋手,则将棋盘数组中对应元素置1*/Map(x-120)/40(y-120)/40=1;Else /*白方棋手,则将棋盘数组中对应元素置2*/Map(x-120)/40(y-120)/40=2;游戏中判断对弈双方是否可以在当前位置(x,y)落子是实现的关键。落子的判断条件为:当前位置(x ,y)不是初始位置(120

22、,80)。同时在该位置黑、白双方尚未落子,并且可以翻转对方棋子时,方可在当前位置落子。程序首先进行判断:Y!=80&Map(x-120)/40(y-120)/40!=1&Map(x-120)/40(y-120)/40!=2即当前棋子位置不是初始位置,并且双方均未落子。在满足上述条件的前提下,通过调用函数QpChange()来判断当前下棋位置是否乐意翻转对方棋子,并最终确定此置是否可以落子。函数QpChange()入口参数包括落子当前的位置坐标(x,y),以及下棋手数t。函数根据当前棋局的情况,即记录在数组Map中的游戏双方对弈的内容,以棋手下棋的当前位置为中心对棋盘的八个方向进行判断,决定是否

23、可以使对方棋子翻转,同时修改被翻转棋子的颜色,最后将棋盘修改标记yes返回。这里以向右的判断为例,来说明函数QpChange()的具体实现:初始时棋盘修改标记yes为0,即为棋子翻转。通过行列坐标交换计算当前棋子在棋盘数组Map中的,当棋子位于棋盘8列中的前6列时才向右进行判断;遇到己方棋子或空格时停止,并将位于两位置间的对方棋子变为己方颜色的棋子。若存在被改变颜色的棋子,则置位棋盘修改标记yes为1。若无棋子颜色翻转,则不做修改,其他7个方向的情况类似。程序通过检测方向键来移动旗子,移动一步后重复落子条件的判断,满足落子条件则落子,然后换对手下棋,若累计尝试落子次数超过棋盘上剩余空格的数量时

24、,当前棋手失去一次落子机会,换对手下棋。游戏者分数score的更新通过函数DoScore()实现。该函数通过统计保存对弈情况数组Map的元素值实现对棋手得分的更新。2.2.5程序结果图2.2输入棋图图2.3输入棋起始图图2.4黑白棋运行图2.3程序源代码及注释#include graphics.h /*图形系统头文件*/#define LEFT 0x4b00 /*光标左键值*/#define RIGHT 0x4d00 /*光标右键值*/#define DOWN 0x5000 /*光标下键值*/#define UP 0x4800 /*光标上键值*/#define ESC 0x011b /* ES

25、C键值*/#define ENTER 0x1c0d /* 回车键值*/int a88=0,key,score1,score2;/*具体分数以及按键与存放棋子的变量*/char playone3,playtwo3;/*两个人的得分转换成字符串输出*/void playtoplay(void);/*人人对战函数*/void DrawQp(void);/*画棋盘函数*/void SetPlayColor(int x);/*设置棋子第一次的颜色*/void MoveColor(int x,int y);/*恢复原来棋盘状态*/int QpChange(int x,int y,int z);/*判断棋盘

26、的变化*/void DoScore(void);/*处理分数*/void PrintScore(int n);/*输出成绩*/void playWin(void);/*输出胜利者信息*/*主函数*/void main(void) int gd=DETECT,gr; initgraph(&gd,&gr,c:tc); /*初始化图形系统*/ DrawQp();/*画棋盘*/ playtoplay();/*人人对战*/ getch(); closegraph();/*关闭图形系统*/void DrawQp()/*画棋盘*/ int i,j; score1=score2=0;/*棋手一开始得分都为0*

27、/ setbkcolor(BLUE); for(i=100;i120)/*左方向键*/ MoveColor(x,y); fillellipse(x,y,15,15); SetPlayColor(t); x-=40; fillellipse(x,y,15,15); else if(key=RIGHT&x80)/*右方向键*/ MoveColor(x,y); fillellipse(x,y,15,15); SetPlayColor(t); x+=40; fillellipse(x,y,15,15); else if(key=UP&y120)/*上方向键*/ MoveColor(x,y); fill

28、ellipse(x,y,15,15); SetPlayColor(t); y-=40; fillellipse(x,y,15,15); else if(key=DOWN&y400)/*下方向键*/ MoveColor(x,y); fillellipse(x,y,15,15); SetPlayColor(t); y+=40; fillellipse(x,y,15,15); t=t%2+1; /*一方走后,改变棋子颜色即轮对方走*/ cc=0; /*计数值恢复为0*/ /*endwhile*/void SetPlayColor(int t)/*设置棋子颜色*/ if(t%2=1) setfills

29、tyle(SOLID_FILL,15);/*白色*/ else setfillstyle(SOLID_FILL,8);/*灰色*/void MoveColor(int x,int y)/*走了一步后恢复原来格子的状态*/ if(y100)/*如果是从起点出发就恢复蓝色*/ setfillstyle(SOLID_FILL,BLUE); else/*其他情况如果是1就恢复白色棋子,2恢复黑色棋子,或恢复蓝色棋盘*/ switch(a(x-120)/40(y-120)/40) case 1: setfillstyle(SOLID_FILL,15);break; /*白色*/ case 2: setf

30、illstyle(SOLID_FILL,8);break; /*黑色*/ default: setfillstyle(SOLID_FILL,BLUE); /*蓝色*/ 第3章 课程设计总结通过本次C程序课程设计,我觉得对计算机的应用,数据结构的作用及C语言的使用都有了更深入的了解。尤其是C语言的进步让我深刻感受到任何所学的知识都需要实践,没有实践就无法真正这些知识以及掌握它们,使其成为自己的知识。同时也对自己提高很大:克服了的偷懒的毛病,这在我以后的学习和工作中的心理定位与调节有很大的帮助。我感受到了编程是一项非常烦琐周密的活动,他不但需要一个人周密的思考问题的能力,处理问题的能力,还需要有足

31、够的耐心和严谨治学的作风,来不得半点马虎。本次我通过课程设计学会了团体合作也初步学会了论文设计的基本方法,学会了怎样去借鉴别人的方法和经验,知道如何去查找资料和整合处理这些资料的能力,这为以后的大学毕业设计论文打下了一个初步的基础使我收益最大的是享受到了一种成功的喜悦,在这两个星期之中从开始的确定论文题目,然后是上网和上图书馆查找资料,编写C语言原程序,然后是进行编译,这个环节是一个非常痛苦和艰难的,常常会因为一小点的错误而在编译失败与再次修改的漫漫循环之路中,但失败的越多,对人的考验就越多,在编译运行成功之后的享受成功的喜悦也就越多,另外在调试程序的过程中不断的思考和运用已经学到的知识,这对

32、于自己是有很大的提高的。这个黑白棋游戏原程序的最大特点是采用了在主函数中调用子函数思想,每一种功能都是用子函数的办法来进行处理,简洁,清晰,方便,不容易出现错误。 在输入错误时本来想用一种警告的铃声来提醒用户,由于所学的知识不多,自己的编程经验不足,按现有的知识水平有些东西暂时还无法解决,还有待于在以后的学习中不断提高和改进!通过这次我了解C语言的重要性,我而且也学会了C语言与函数是紧密相关的,所以我今后一定会好好学习C语言。能够在社会和生活中起到实际重用,同时也让我明白了科技的深奥与奇妙。参考资料1 蔡先华 C语言程序设计基础.2001年版.北京. 高等教育出版社.2001.240页2 何光

33、明,杨静宇C语言程序设计与应用开发第2版.北京:清华大学出版社,2006:237页3 谭浩强. C 语言程序设计.99年版.北京:清华大学出版社,1999:249页4 廖雷C语言程序设计第2版北京:高等教育出版社,2006:347页5张强华. C 语言程序设计.00年版.北京:人民邮电出版社,2001:359页6徐新华. C 语言程序设计教程.第一版.北京: 清华大学出版社,1999:168页7 贾学斌,宋海民C语言程序设计06年版北京:中国铁道出版社,2007:306页8徐建民. C 语言程序设计.2002年版.北京:电子工业出版社,2002:275页9李大友. C 语言程序设计.1999年

34、版. 北京. 清华大学出版社.1999:326页10 方少卿. C语言程序设计. 2007年版.北京. 中国铁道出版社.2007.216页11刘燕. C 语言程序设计.2008年版.北京. 中国铁道出版社.2008:304页12 赵海廷C语言程序设计04年版.北京:人民邮电出版社,2005:309页13 毕万新. C 语言程序设计.2005年版.大连. 大连理工大学出版社.2005:169页14 谭浩强. C语言程序设计. (第二版).北京.清华大学出版社.2007.314页15 吴文虎. 程序设计基础.2003年版.北京. 清华大学出版社.2003.129页16 刘加海. C语言程序设计基础.2003年版.科学出版社.2003:204页17 张翔. C语言函数大学.2002年版.电子工业出版社.2004:416页17

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1