
求助:C语言五子棋课程设计报告~~
到csdn找找看,应该有的,对于学计算机的很好的网站
用C语言在linux下编写一个五子棋程序
五子棋的核心算法五子棋是一种受大众广泛喜爱的游戏,其规则简单,变化多端,非常富有趣味性和消遣性。
这里设计和实现了一个人机对下的五子棋程序,采用了博弈树的方法,应用了剪枝和最大最小树原理进行搜索发现最好的下子位置。
介绍五子棋程序的数据结构、评分规则、胜负判断方法和搜索算法过程。
一、相关的数据结构 关于盘面情况的表示,以链表形式表示当前盘面的情况,目的是可以允许用户进行悔棋、回退等操作。
CList StepList; 其中Step结构的表示为: struct Step { int m; \\\/\\\/m,n表示两个坐标值 int n; char side; \\\/\\\/side表示下子方 }; 以数组形式保存当前盘面的情况, 目的是为了在显示当前盘面情况时使用: char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE]; 其中FIVE_MAX_LINE表示盘面最大的行数。
同时由于需要在递归搜索的过程中考虑时间和空间有效性,只找出就当前情况来说相对比较好的几个盘面,而不是对所有的可下子的位置都进行搜索,这里用变量CountList来表示当前搜索中可以选择的所有新的盘面情况对象的集合: CList CountList; 其中类CBoardSituiton为: class CBoardSituation { CList StepList; \\\/\\\/每一步的列表 char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE]; struct Step machineStep; \\\/\\\/机器所下的那一步 double value; \\\/\\\/该种盘面状态所得到的分数 } 二、评分规则 对于下子的重要性评分,需要从六个位置来考虑当前棋局的情况,分别为:-,¦,\\\/,\\\\,\\\/\\\/,\\\\\\\\ 实际上需要考虑在这六个位置上某一方所形成的子的布局的情况,对于在还没有子的地方落子以后的当前局面的评分,主要是为了说明在这个地方下子的重要性程度,设定了一个简单的规则来表示当前棋面对机器方的分数。
基本的规则如下: 判断是否能成5, 如果是机器方的话给予100000分,如果是人方的话给予-100000 分; 判断是否能成活4或者是双死4或者是死4活3,如果是机器方的话给予10000分,如果是人方的话给予-10000分; 判断是否已成双活3,如果是机器方的话给予5000分,如果是人方的话给予-5000 分; 判断是否成死3活3,如果是机器方的话给予1000分,如果是人方的话给予-1000 分; 判断是否能成死4,如果是机器方的话给予500分,如果是人方的话给予-500分; 判断是否能成单活3,如果是机器方的话给予200分,如果是人方的话给予-200分; 判断是否已成双活2,如果是机器方的话给予100分,如果是人方的话给予-100分; 判断是否能成死3,如果是机器方的话给予50分,如果是人方的话给予-50分; 判断是否能成双活2,如果是机器方的话给予10分,如果是人方的话给予-10分; 判断是否能成活2,如果是机器方的话给予5分,如果是人方的话给予-5分; 判断是否能成死2,如果是机器方的话给予3分,如果是人方的话给予-3分。
实际上对当前的局面按照上面的规则的顺序进行比较,如果满足某一条规则的话,就给该局面打分并保存,然后退出规则的匹配。
注意这里的规则是根据一般的下棋规律的一个总结,在实际运行的时候,用户可以添加规则和对评分机制加以修正。
三、胜负判断 实际上,是根据当前最后一个落子的情况来判断胜负的。
实际上需要从四个位置判断,以该子为出发点的水平,竖直和两条分别为 45度角和135度角的线,目的是看在这四个方向是否最后落子的一方构成连续五个的棋子,如果是的话,就表示该盘棋局已经分出胜负。
具体见下面的图示: 四、搜索算法实现描述 注意下面的核心的算法中的变量currentBoardSituation,表示当前机器最新的盘面情况, CountList表示第一层子节点可以选择的较好的盘面的集合。
核心的算法如下: void MainDealFunction() { value=-MAXINT; \\\/\\\/对初始根节点的value赋值 CalSeveralGoodPlace(currentBoardSituation,CountList); \\\/\\\/该函数是根据当前的盘面情况来比较得到比较好的可以考虑的几个盘面的情况,可以根据实际的得分情况选取分数比较高的几个盘面,也就是说在第一层节点选择的时候采用贪婪算法,直接找出相对分数比较高的几个形成第一层节点,目的是为了提高搜索速度和防止堆栈溢出。
pos=CountList.GetHeadPosition(); CBoardSituation* pBoard; for(i=0;ivalue=Search(pBoard,min,value,0); Value=Select(value,pBoard->value,max); \\\/\\\/取value和pBoard->value中大的赋给根节点 } for(i=0;ivalue) \\\/\\\/找出那一个得到最高分的盘面 { currentBoardSituation=pBoard; PlayerMode=min; \\\/\\\/当前下子方改为人 Break; } } 其中对于Search函数的表示如下:实际上核心的算法是一个剪枝过程,其中在这个搜索过程中相关的四个参数为:(1)当前棋局情况;(2)当前的下子方,可以是机器(max)或者是人(min);(3)父节点的值oldValue;(4)当前的搜索深度depth。
double Search(CBoardSituation& board,int mode,double oldvalue,int depth) { CList m_DeepList; if(deptholdvalue))== TRUE) { if(mode==max) value=select(value,search(successor Board,min,value,depth+1),max); else value=select(value,search(successor Board,max,value,depth+1),min); } return value; } else { if ( goal(board)<>0) \\\/\\\/这里goal(board)<>0表示已经可以分出胜负 return goal(board); else return evlation(board); } } 注意这里的goal(board)函数是用来判断当前盘面是否可以分出胜负,而evlation(board)是对当前的盘面从机器的角度进行打分。
下面是Select函数的介绍,这个函数的主要目的是根据 PlayerMode情况,即是机器还是用户来返回节点的应有的值。
double Select(double a,double b,int mode) { if(a>b && mode==max)¦¦ (a< b && mode==min) return a; else return b; } 五、小结 在Windows操作系统下,用VC++实现了这个人机对战的五子棋程序。
和国内许多只是采用规则或者只是采用简单递归而没有剪枝的那些程序相比,在智力上和时间有效性上都要好于这些程序。
同时所讨论的方法和设计过程为用户设计其他的游戏(如象棋和围棋等)提供了一个参考。
参考资料:
求一个用C语言编写五子棋游戏的全部代码.
这个程序还需要两个,告诉我箱,我发给你源程序前半部分\\\/*加载头文件*\\\/#include
C语言总结问题
《c语言从入门到精通》还可以 我们教授说谭浩强的那本里面有些不好的编程习惯,不过也没有阻止我们课外看,我们的教材是清华大学出版社的那本。
谭浩强的通俗易懂,不过我推荐的《c语言从入门到精通》也是比较简单的,我一直在拿这本自学,教授给我们上课的时候我再看我们的教材。
我想,你一边学一边做题目就行了。
多编编小程序,慢慢积累。
我是软件工程大一的,学完C语言不久,书本上的内容看的比较透了,但是现在导师叫我们去做五子棋的游戏。
。
我给你一个c++五子棋的程序mian.cpp#include 这是编程学习视频教程网址 首先你要学会一种编程语言 编程语言有: 工控程序:c ,c++,vc 管理系统:vb,delphi,pb 做网页B\\\/S: html,jsp,php,asp,asp.net,java,C# 初学者建议学习VB,可视化的软件开发工具. 要看一些相关的书,多听一些讲座网上有很多视频教程,要多读别人写的程序.在以上的基础上自己可以试着多写代码,在加上自己的思维和创意. 貌似我的这个游戏包含了一些三角概念,可以看看。 比如扫雷的思维和五子棋的矩阵代码如下: #include for(i=0;i 需要重新初始化 j=y-'A'; state[i][j]='*'; printState(); printf(\\\ 观棋不语真君子,落子不悔大丈夫!\\\ ); isBlack=!isBlack; continue; } if(!strcmp(temp,LOSE)) \\\/\\\/认输... LOSE { printf(\\\ \\\潇洒菠菜提示:%s方认输,%s方胜 \\\ \\\ ,isBlack?黑:白,isBlack?白:黑); return; } x=temp[0]; \\\/\\\/取前两个字符做处理。 y=temp[1]; if(x<'A'||x>'S'||y<'A'||y>'S') \\\/\\\/避免下面相减的数组越界。 { printf(\\\输入有误,请输入属于 \\\ ); continue; } i=x-'A'; \\\/\\\/相减得到的差量正好是数组对应的元素 j=y-'A'; if(state[i][j]!='*'){ \\\/\\\/该位置已经有子 printf(\\\提示:该位置已经有子,请重新指定坐标 ); continue; } c=isBlack?'1':'2'; state[i][j]=c; \\\/\\\/设置坐标子为当前下定子 printState(); \\\/\\\/显示当前棋盘 \\\/\\\/检查是否获胜。 待续... 第二阶段完毕 isBlack=!isBlack; }}void help(){ system(cls); printf(\\\ 潇洒菠菜关于本程序说明:\\\ \\\ ); printf(\\\考虑到C语言图形用户界面的难度。 \\\ \\\ ); printf(\\\本程序采用19*19的游戏格式\\\ \\\ ); printf(\\\输入格子的坐标下子: 先横坐标后纵坐标。 比如输入:GG\\\ \\\ ); printf(\\\在游戏中有外挂:out(退回主菜单)、back(悔棋)、lose(认输)\\\ \\\ ); printf(\\\ 程序棋盘(网上信息) :\\\ ); printf(\\\ 与围棋的棋盘一样。 \\\ \\\ ); printf(基本规则 : \\\ \\\ 1) 黑先、白后,从天元开始相互顺序落子。 \\\ \\\ ); printf(2) 白棋第一手应在天元为界自己一侧布子,之后双方可任意行子。 \\\ \\\ ); printf(3) 最先在棋盘横向、竖向、斜向形成连续的相同色五个棋子的一方为胜。 \\\ \\\ ); printf(4) 黑棋禁手判负、白棋无禁手。 ); printf(黑棋禁手包括“三、三” “四、四” “长连”。 黑方只能“四、三”胜。 \\\ \\\ ); printf(5) 如分不出胜负,则定为平局。 \\\ \\\ ); printf(6) 对局中中途退场均判为负。 \\\ \\\ ); printf(7) 五连与禁手同时形成,先五为胜。 \\\ \\\ ); printf(棋型说明 : \\\ \\\ ); printf(1) 长连:在一条直线或斜线上,连续下成五个以上的棋型\\\ \\\ ); printf(2) 活三:在一条直线或斜线上,由三个子构成的,必须防守否则将成为“活四”); printf(导致速胜的棋型。 三只有下面两种棋型结构:\\\ \\\ ); printf(3) 活四:指在一条直线或斜线上,由连续的四个字所构成的,); printf(无论对方怎样防守,只要再走一手棋将必定成为五连的棋型:\\\ \\\ ); printf(4) 四:在一条直线或斜线上,由四个同色子构成的,); printf(必须防守否则下一步立刻成为“五连”导致速胜的棋型。 活四也是四之一。 \\\ \\\ ); printf(特殊规则 : \\\ \\\ ); printf(黑棋先行的优势很大。 因此,在五子棋中,对黑棋做了禁手限制。 \\\ \\\ ); printf(禁手:对局中禁止使用的着法,黑棋禁手包括“三三禁手”); printf(“四四禁手”和“长连禁手”,白棋无禁手。 \\\ \\\ ); printf(禁手的判断 : \\\ \\\ ); printf(1) 长连禁手:当黑棋走一步棋,形成长连棋型,则此点为“禁手”\\\ \\\ ); printf(2) 三三禁手:当黑棋走一步棋,同时形成两个或); printf(两个以上的“活三”且没有形成“五连”时,那一步棋就是黑棋禁手。 \\\ \\\ ); printf(3) 四四禁手:当黑棋走一步棋,同时形成两个或); printf(两个以上的“四”且没有形成“五连”时,那一步棋就是黑棋禁手。 \\\ \\\ ); printf(胜负判断 : \\\ \\\ ); printf(胜局 :\\\ \\\ ); printf(1) 最先在棋盘上形成五连,并得到系统认可的一方为胜。 白棋长连视同五连。 \\\ \\\ ); printf(2) 黑方五连与禁手同时形成,禁手失效,黑方胜。 \\\ \\\ ); printf(3) 黑方被迫形成禁手,黑方输。 \\\ \\\ ); printf(4) 对局中,一方出现下列情况之一,系统判对方胜。 \\\ \\\ ); printf((1)超过规定时限者;\\\ \\\ ); printf((2)一方宣布认输者;\\\ \\\ ); printf((3)中途退出比赛者即逃跑者。 \\\ \\\ ); printf(和局 :\\\ \\\ ); printf(1)对局双方一致同意和棋。 \\\ \\\ ); printf(2)对局双方同一回合均放弃行棋权。 \\\ \\\ ); printf(3)全盘均下满,已无空白交叉点。 \\\ \\\ ); printf(提和 :\\\ \\\ ); printf(1)欲提和者应在自己下着前提出。 \\\ \\\ ); printf(2)一方提和,对方可对提和建议表示同意,也可以拒绝。 \\\ \\\ ); printf(3)在一局中,一方提和次数不能超过对方三次\\\ \\\ );printf(选材说明地址:中国游戏中心\\\ ( )\\\ \\\ ); printf(\\\\\\\\\说明完毕...\\\ \\\ );}void aboutThanks(){ system(cls); printf(\\\ 菠菜鸣谢:\\\ \\\1.我的C语言老师:叶煜老师。 ); printf(\\\ \\\2.成都金海洋教育。 ); printf(\\\ \\\3.所有关心我的兄弟姐妹。 \\\ \\\ );}int main(){ system(color f1); while(1) { printf(\\\ \\\-----潇洒菠菜五子棋C语言练习-----\\\ \\\ ); printf(\\\\\\ 1.开始游戏。 \\\ ); printf(\\\\\\ 2.游戏说明。 \\\ ); printf(\\\\\\ 3.游戏鸣谢。 \\\ ); printf(\\\\\\ 4.退出程序。 \\\ ); printf(\\\ \\\请选择:); L:k=scanf(%d,&i); if(k==0) \\\/\\\/遇到异常,做健壮性处理... { printf(\\\ \\\潇洒菠菜提示:输入非格式选项 \\\ 请重新输入:); fflush(stdin); \\\/\\\/清空缓冲内存区... goto L; \\\/\\\/goto语句破坏程序结构,请慎用... } switch(i) { case 1: startGame(); break; case 2: help(); break; case 3: aboutThanks(); break; case 4: printf(\\\ \\\您的建议是我成功制胜的关键。 \\\ ); printf(\\\\\\\\\\\\再会...08ACCP菠菜\\\ \\\ \\\ \\\); return 0; \\\/\\\/结束整个程序。 default:printf(\\\潇洒菠菜提示 : 无此选项\\\ );break; } }}void printState() \\\/\\\/显示当前棋盘的状态 { char p='A'; system(cls); printf(\\\棋盘如下:\\\ \\\ ); printf(\\\ ); \\\/\\\/输出第一行开头的空格 for(i=0;i } printf(%c \\\ \\\,p+i); \\\/\\\/右侧的坐标 } printf( ); for(i=0;i 总结:\\\/\\\/循环的控制和循环的设计是编程人员的一个砍 printf(\\\ );}怎么学习C语言?
求C语言经典三角程序



