五子棋人机对战设计任务书
五子棋游戏课程设计说明书

学校代码: 10128学号:************课程设计说明书题目:五子棋****:**学院:理学院班级:信计13-1****:***二〇一六年一月二十一日内蒙古工业大学课程设计(论文)任务书课程名称:面向对象的程序设计学院:理学院班级:信计13-1 学生姓名:杨震学号: 201320905020 指导教师:白莲花摘要随着经济的发展,社会竞争的激烈,现在社会进入了竞争的时代。
上班族为了完成公司业务,每天超负荷的工作;学生为了不落后他人每天早起晚睡不断地学习,压力巨大。
所以为了缓解大家的压力,使大家在工作、学习之余娱乐一下,活跃大脑,提高工作、学习效率,因此益智性游戏越来越受人们的关注,五子棋作为益智类游戏之一,倍受人们的喜爱,所以对于五子棋的开发也有了很多关注。
C++语言即是进行软件开发的直接工具,又是“数据结构”、“操作系统”、“编译原理”以及其他相关课程的先修课程,因此,在整个教学体系中占据十分重要的地位[1]。
本文主要讲的是利用VC++6.0软件开发一个界面简洁、直观、实用性比较高的AI功能的五子棋游戏,游戏程序实现人人对弈,在对弈过程中当用户和用户比赛时电脑利用搜索算法计算出落子的最佳位置,是先人人对弈,而且程序能够完成具有重新开始、认输、提示该轮到哪一方下棋的、游戏、判断胜负、悔棋等功能。
关键词:人工智能;自动处理;五子棋目录第一章任务概述 (1)1.1问题概述 (1)1.2 需求分析 (1)第二章概要设计 (2)2.1功能设计 (2)2.2 程序结构 (2)2.3 基本流程 (3)第三章程序实现 (4)3.1主要变量及函数说明 (4)3.1.1 主要变量 (4)3.1.2 主要函数 (4)3.2 主要功能实现 (4)3.2.1棋盘类的声明 (4)3.2.2玩家类的声明 (4)3.2.3棋盘显示为方形 (5)3.2.4判断棋子显示位置是否合理 (5)3.2.5判断输赢 (5)第四章结果与总结 (6)4.1.运行过程及截图 (6)4.1.1棋盘初始化模块 (6)4.1.2输入错误提示 (8)4.1.3 结局判断模块 .............................. 错误!未定义书签。
五子棋(双人对战) C语言课程设计.doc

C语言程序设计题目五子棋(双人对战)指导教师曹东燕学生姓名夏文龙于文杰邢健学号 201000802032 201000802114 201000802097专业电子信息工程教学单位物理系(盖章)目录1设计内容与设计要求 (1)1.1系统功能简介 (1)1.2系统运行环境 (1)2程序流程图 (1)3运行的运行及说明 (2)3.1系统的运行 (2)3.2运行说明 (4)4课程设计目的………………………………………………….5 程序特色 (5)6总结 (5)附件:源程序清单 (5)1设计内容与设计要求1.1系统功能简介该系统是五子棋的人人对战模式,而非平常的人机对战系统有简单的菜单界面1.2系统运行环境Vc++6.0下运行,硬件基本无要求,现在的计算机系统基本都可以运行该系统。
2程序流程图3系统的运行及说明3.1系统的运行图3-1程序的初始化界面程序初始化的界面,界面简洁明快,便于观察。
图3-2程序的运行界面图3-3程序的介绍界面3-2运行说明A向左 W向上 D向右 S向左空格键确定当结束时按Y重新开始游戏按N退出游戏4课程设计目的五子棋游戏不仅能增强人们的抽象思维能力、逻辑推理能力、空间想象力,提高人们的记忆力、心算能力等,而且深含哲理,有助于修身养性。
五子棋既有现代休闲方式所特有的特征“短、平、快” ,又有中国古典哲学所包含的高深学问“阴阳易理” ;它既有简单易学的特点,为人民群众所喜闻乐见,又有深奥的技巧;既能组织举办群众性的比赛、活动,又能组织举办高水平的国际性比赛;它的棋文化源渊流长,具有东方的神秘和西方的直观,它是中西方文化的交融点,也是中西方文化交流的一个平台。
自从计算机作为游戏对战平台以来,各种棋类游戏如雨后春笋般纷纷冒出。
五子棋是一种受大众广泛喜爱的游戏,其规则简单,变化多端,非常富有趣味性和消遣性。
同时具有简单易学、既动手又动脑的特点。
同时也为锻炼自己的编程能力。
5程序特色本程序简洁明快,采用黑白两色棋,并且本程序为双人对战。
五子棋策划书

五子棋策划书一、项目背景。
五子棋是一种古老的策略棋类游戏,深受广大玩家喜爱。
随着互联网的发展,五子棋游戏也逐渐成为了一种受欢迎的线上游戏。
本策划书旨在开发一款优质的五子棋游戏,为玩家提供高品质的游戏体验。
二、项目目标。
1. 开发一款界面友好、操作简单的五子棋游戏,吸引更多玩家参与。
2. 提供多种游戏模式,包括人机对战、在线对战等,满足玩家不同的游戏需求。
3. 设计精美的游戏界面和音效,增强游戏的趣味性和可玩性。
三、项目内容。
1. 游戏开发,开发一款支持Android和iOS平台的五子棋游戏,包括游戏规则、界面设计、人机对战和在线对战功能等。
2. 美术设计,设计游戏界面、棋子样式、动画效果等,提升游戏的视觉体验。
3. 音效设计,制作游戏背景音乐、音效等,增强游戏的听觉体验。
四、项目进度。
1. 游戏开发,预计开发周期为3个月,包括规则设计、程序编码、测试调试等。
2. 美术设计,预计设计周期为2个月,包括界面设计、棋子样式设计、动画效果设计等。
3. 音效设计,预计设计周期为1个月,包括背景音乐制作、音效制作等。
五、项目预算。
1. 游戏开发,预计开发成本为30万人民币。
2. 美术设计,预计设计成本为15万人民币。
3. 音效设计,预计设计成本为8万人民币。
六、项目营销。
1. 游戏上线后,通过线上广告、社交媒体推广等方式,吸引玩家下载游戏。
2. 定期举办线上比赛、活动,增加玩家互动和参与度。
3. 不断更新游戏内容,保持玩家的兴趣和活跃度。
七、项目风险。
1. 开发周期延长,可能会受到技术难题、人员变动等因素影响,导致开发周期延长。
2. 竞争压力,市场上已有多款五子棋游戏,竞争压力较大。
3. 用户反馈,游戏可能存在bug、不足之处,需要及时修复和改进。
八、项目收益。
1. 游戏下载量增加,带来一定的广告收入和游戏内购买收入。
2. 举办线上比赛、活动,吸引更多玩家参与,增加游戏的知名度和用户粘性。
3. 不断更新游戏内容,增加玩家的留存率,为游戏带来稳定的收益。
五子棋人机博弈实验报告

五子棋人机博弈实验报告目录一(课程设计目的............................................. 2 二(课程设计要求............................................. 2 三(课程设计内容............................................. 2 四(课程设计思想............................................. 2 五(系统实现 (2)设计平台 (2)数据结构设计 (3)程序流程图设计 (3)主要算法设计 (4)程序调试及运行结果.............................. 4 六(课程设计总结............................................. 5 七(参考资料................................................... 6 八(附录:五子棋博弈算法源代码 (7)1一( 课程设计目的通过上学期学习的《人工智能》学科,运用推理技术、搜索方法和决策规划和博弈树设计五子棋人机博弈系统,以此进一步深化对理论知识技术的了解,培养学生编程能力以及实践水平。
二(课程设计要求通过本次课程设计要求学生掌握以下内容:1.深入了解博弈树和alpha-beta剪枝算法。
2.设计出适合五子棋算法的启发式函数。
3.熟练掌握启发式的搜索方法。
三(课程设计内容本系统实现的是五子棋博弈算法,运用java语言实现了图形用户界面,方便用户使用。
算法采用了博弈算法和启发式函数进行搜索,人机对弈可自动判断输赢,结束后可重新开局。
四(课程设计思想本系统实现的是五子棋博弈算法,为了方便用户的使用,采用的是java图形用户界面技术。
为了记录棋盘的每一个下棋点,定义数组array[19][19]。
毕业设计(论文)-五子棋人机对弈程序设计[管理资料]
![毕业设计(论文)-五子棋人机对弈程序设计[管理资料]](https://img.taocdn.com/s3/m/a1ff81dacfc789eb162dc8ea.png)
五子棋人机对弈程序摘要:五子棋程序由两个主要部分组成:一个估值函数和一个树状搜索算法。
而程序依靠估值函数来判断对于一方来说什么局面是好而什么局面是坏,后者是用来搜索几乎全部可能的棋步次序,目的是为了找出对于程序来说是最佳的一条路线。
人工智能电脑下棋模拟的是人类的智能,它的启发式搜索是边走边试探,即极大极小法。
关键词:五子棋人工智能估值函数树状搜索算法极大极小法The program for Renju in man vs computerAbstract:The program for Renju is composed of two parts: a evaluation function and a hashtable tree-searching algorithm. The evaluation function is used to judge the advantage or disadvantage situation for each part, the hashtabletree-searching algorithm is used to search almost all the possible steps and find out the best pathway for the program. The computer of Artificial Intelligence (AI) imitate the intelligence of human, its inspiring search way is Go and Explore, namely, Minimax.Key words:Renju Artificial Intelligence (AI)evaluation function hashtable tree-searching algorithmMinimax五子棋人机对弈程序目录中文摘要英文摘要第一章引言 (5) (5)、内容及作者的任务 (5)第二章研究现状及设计目标 (7) (7) (7) (8)第三章要解决的几个关键问题 (9) (9) (9) (9) (13) (13) (13) (14)第四章系统结构与模型 (16) (16) (16) (16)(Minimax Algorithm) (18)Alpha-Beta剪枝(Alpha-Beta Purning) (19) (21) (21) (22)第五章系统实现技术 (25) (25) (25) (28) (29) (31) (31) (33) (37)第六章性能测试与分析 (41)、硬件环境 (41) (41) (41) (42) (42)第七章结束语 (47)参考文献 (48)附录:程序清单(附光盘)第一章引言五子棋是起源于中国古代的传统黑白棋种之一。
五子棋人机对战设计任务书

五子棋人机对战设计任务书目录1.系统需求分析 ............................................................................................................... 错误!未定义书签。
2.总体设计 ....................................................................................................................... 错误!未定义书签。
3.详细设计 ....................................................................................................................... 错误!未定义书签。
4.系统调试 ....................................................................................................................... 错误!未定义书签。
5.使用说明 ....................................................................................................................... 错误!未定义书签。
6.编程体会 ....................................................................................................................... 错误!未定义书签。
安卓欢乐五子棋人机大战报告

实验报告
( 2015 / 2016学年第2学期)
课程名称
实验名称安卓五子棋人机大战
实验时间2016 年 4 月13 日指导单位
指导教师
学生姓名学号
学院(系) 专业
一、实验目的
1.在棋盘上任意落下一颗子,计算机调用AI算法,能判断出最佳的落子位置并落子。
2.程序能判断出输赢,结束游戏,停止落子。
二、实验环境(实验设备)
Eclipse ADT
三、AI难点解析
1.赢法数组:记录五子棋所有的赢法,三维数组
2.每一种赢法的统计数组,一维数组
3.如何判断胜负
4.计算机落子规则
四、实验结果
开局前:
比赛一游戏结束:比赛二游戏结束:
11。
五子棋源码实验报告及人机对战说明

1.五子棋对战说明2.实验报告3.源代码五子棋作品特点:C语言程序五子棋作品功能:五子棋人机对战,人人对战。
目录:1 五子棋介绍。
2五子棋棋型介绍。
3人人对战的实现。
4电脑下子的实现。
5棋型价值的计算。
6胜利及棋型的判断。
7补充说明1五子棋介绍。
五子棋是一种两人对弈的纯策略型棋类游戏。
只要任意一方在棋盘上且同一个回合上连为五子为胜。
还有禁手规则,在本程序中不作讨论。
2五子棋棋型介绍。
本程序中的棋型均为本人自定义。
本程序总共设计35种棋型。
●表示玩家的棋子,◎表示电脑的棋子。
以下称电脑方为己方,玩家方为对方。
从一空点向某一方向判断该方向的棋型。
某一方向指1-8方向从右顺时针开始数。
(1)空棋型。
从一空点向一方向看连续2个为空的棋型。
空棋型共1种。
如图,从左端的空点向右看会发现有连续2个空点。
(2)活棋型。
2端无挡的棋型为活棋型。
活棋型共8种:己方4种,对方4种。
左图为己活3 。
从左端的空点向右看会发现己方有连续的3个子,且右端无挡。
故该点的1方向为己活3。
左图为对活2(3)冲棋型。
1端无挡的棋型为冲棋型。
冲棋型共9种:己方4种,对方4种,边界1种。
左图为边界冲棋型。
空点的右端为边界。
或左图为己冲2。
从左端的空点向右看会发现己方有连续的2个子,且右端有挡(此处有挡表示有对方的子或为边界)。
故该点的1方向为己冲2。
左图为对冲4。
(4)空活棋型。
从一空点向一方向看有1个空点,继续看有己方或对方的活棋型。
空活棋型共8种:己方4种,对方4种。
左图为己空活2。
从左端的空点向右看有1个空点,继续看会发现己方有连续的2个子,且右端无挡。
故该点的1方向为己空活2。
左图为对空活1。
(5)空冲棋型。
从一空点向一方向看有1个空点,继续看有己方或对方或边界冲棋型。
空冲棋型共9种:己方4种,对方4种,边界1种。
左图为边界空冲棋型。
空点的右端为空点再右看为边界。
或左图为己空冲2。
从左端的空点向右看有1个空点,继续看会发现己方有连续的2个子,且右端有挡。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
五子棋人机对战设计任务书目录1.系统需求分析 (1)2.总体设计 (1)3.详细设计 (2)4.系统调试 (4)5.使用说明 (5)6.编程体会 (6)7.源程序清单 (7)1.系统需求分析五子棋是我国古代传统的黑白棋种之一,又称作连珠棋。
五子棋游戏首先需要棋盘,并绘制棋子,若希望人机对战还要为计算机设置一定的算法,以使其能够自动判断落棋的位置,此外,还需要有一定的判断系统来判定胜负,还有悔棋功能。
综上,五子棋人机对战游戏需要提供以下功能:(1)使用图形界面,绘制棋盘,并能够提供虚拟棋盘来作为计算机运算的依据。
(2)判断玩家的落子位置,并相应的画出对应颜色的棋子,判断落子位置时误差要很小。
另外,需要记录玩家的落子情况。
(3)通过运算判定电脑的落子位置,如防范玩家连成五子,或进攻使自己连成五子取得胜利,并相应的显示对应颜色的棋子。
另外,需要记录电脑的落子情况。
(4)根据规则判断出胜负,先连成五子者获得胜利,并显示出胜利的一方,之后可以按任意键再来一局。
(5)当玩家落棋出现重大失误时,可进行悔棋,清除棋子。
2.总体设计五子棋人机对战游戏包括四个方面的功能,分别是绘制棋盘和棋子等图形化显示功能,获取玩家落子功能,计算并判断得到电脑落子位置的功能以及判断胜负的功能。
图形化显示功能方面,运用easyx图形库进行图形的绘制,可以进行背景色的设置,线条的绘制,文字的显示和字体的设置。
通过initgraph初始化界面,设置坐标,用setbkcolor函数设置背景色,用settextcolor函数设置文本颜色,用settextstyle函数设置文本字体,用outtextxy函数显示文字,用line 和fillcircle 函数进行棋盘的绘制,用fillcircle 函数进行棋子的绘制。
通过HWND 句柄可以弹出选项框。
建立二维数组作为虚拟棋盘。
玩家落子方面,首先需要判断鼠标所点击的位置,然后需要在链表上建立新的节点,在虚拟棋盘上设置玩家落子,并在棋盘上绘制出玩家的棋子。
电脑落子方面,需要遍历所有位置,分别对玩家在该处落子和电脑在该处落子进行评分,找出玩家或电脑落子评分最高的位置作为落子的位置,在虚拟棋盘上落子,并在棋盘上绘制出电脑的棋子。
判定胜负功能方面,在玩家及电脑每次落子之后,都通过调用判定函数来判断某一方是否连成五子,若一方胜利,显示游戏结果,跳出当前棋局的循环,并按任意键重新布置棋盘,开始新的一局。
悔棋方面,需要沿着链表的结构进行前一步棋子的清除。
五子棋游戏中的功能模块图:3. 详细设计五子棋人机对战程序中的类的层次图为:chessboard (棋盘类)piece (棋子类)piece_playerpiece_computerplayer_listcomputer_list设置棋盘模块显示界面,绘制棋盘,设置虚拟棋盘五子棋人机对战游戏判断模块判断某一方是否连成五子,显示结果电脑落子模块判定最佳落子处,建立链表新节点玩家落子模块玩家落子捕捉,建立链表的新节点悔棋模块清除原棋子五子棋人机对战游戏中各功能模块的实现:1.布置棋盘模块2.玩家落子模块3.电脑落子模块4.判定胜负模块5.悔棋模块五子棋人机对战游戏中六个类的UML 图:布置棋盘功能绘制15*15棋盘 设置虚拟棋盘玩家落子功能捕捉鼠标信息建立新的链表节点 设置与绘制棋子电脑落子功能运算判断最佳落子位置建立新的链表节点 设置与绘制棋子判定胜负功能判定是否连为五子显示结果,清空缓存,跳出循环开始界面布置棋盘玩家落子 电脑落子判定胜负悔棋悔棋功能清除玩家棋子清除电脑棋子4.系统调试由于使用了图形界面,很多功能的调试只能在程序基本编译完成后进行。
对于棋盘等方面的调试,我是先将程序写为两个玩家的对战进行调试,开始的错误主要是语法错误,例如两次声明全局数组extern int a[16][16],却没有对其进行定义,导致了LNK2001错误。
另外的一个错误是电脑自动先下时,未将数组坐标转化为图形界面上的坐标,使得棋子所在的位置与其应当出现的位置出现了较大的偏差。
接下来的调试主要是算法方面的调试。
开始时,电脑下棋会出现一些致命的错误,例如:玩家执白旗,电脑执黑棋,玩家已在c8,d9,e10连成三珠,但电脑下棋时去选择了f4的位置,而不是b7或f11来堵住玩家,从而导致电脑输下此局,根据这个情况,我判断是f4左上方三颗棋子影响了电脑的判断,另外d4到f4处还可形成进攻,因而修改程序的过程中,我增大了连成三珠且两边没有另一方棋子堵住情况的权重。
经过修改,电脑下棋便不再犯这样的低级错误,但不得不说,电脑下棋的方式也变得比之前保守。
此外,之前还出现过电脑没有注意边界,而依然在边界处下棋企图连成三子的情况,为此,我在程序中另加了判断语句,若连接的棋子数目小于5且一边已到达边界,则不在边界处着棋,另外如果对方棋子已在距边界小于等于五的距离处将该方向堵住,也扣除一定的权重。
经过上述的处理,最佳落棋处的分数会比那些受限制的落棋处的分数高,而不是因为可能的分数相同而造成电脑判断的失误。
在进行悔棋功能的调试时,我先是处理了循环结构造成的问题,然后在棋盘上清除棋子图案的程序经过了两三次的修改,终于使得棋子的图案完全被清除。
此外在悔棋直到没有棋子时,刚开始的时候程序会发生崩溃,原因是我没有添加头指针是否为空的判断,添加该判断后,棋盘上没有棋子时不再发生变化。
5.使用说明启动游戏后,首先会进入开始界面。
此时按任意键(指键盘)即可进入游戏。
进入游戏后首先需要选择是否让电脑先下,另外,游戏中永远是玩家执白棋,电脑执黑棋,游戏中没有禁手的规则。
游戏的窗口大小不能改变,故高度较小、屏幕较小的电脑需要调节分辨率来显示全部的棋盘,否则可能有一部分棋盘(一半是棋盘的最下方)在屏幕中无法显示。
若想要棋盘显示完全,请保证屏幕的竖直方向像素至少为800,水平方向的像素至少为900.点击确定电脑先下,点击取消则玩家先下。
电脑先下时,会自动选择天元的位置。
玩家获得胜利或电脑胜利时时,棋盘的上方会出现玩家胜利或玩家失利的的信息。
此时按任意键(键盘)可以重新布置棋盘,开始新的一局。
请注意,下棋时鼠标是有一定的点击范围的,起一定要点击到交点的中央区域附近,否则程序不会认为玩家已下棋,也不会在玩家认为自己下过棋的地方显示棋子,故一定要点击准确,下棋前一定要三思,点击一定要准确。
此外,游戏设置了悔棋功能,点击右键即可悔棋。
若希望结束游戏,直接点击右上方的关闭按钮关闭程序即可退出游戏。
此外,游戏编译通过是建立在有easyx C++图形库的基础上。
故而没有安装easyx图形库的情况下,头文件graphics.h中是没有相关函数的,会使编译不通过。
程序在VS2008下编译成功。
6.编程体会这是我第一次应用图形界面编程,通过这个游戏程序的编写,我初步了解了MFC,easyx等图形化编程的工具,并初步学会使用easyx C++图形库进行编程。
除了图形界面编程,此程序中还应用了构造函数的重载,类的继承与抽象基类,动态内存分配与链表结构的建立等知识。
这个程序中包含六个类,其中玩家棋子类与电脑棋子类属性与方法相似,通过棋子基类进行派生,各个类的功能分配等方面比我之前的编程也更加明晰。
使用链表结构使得每一步棋间都通过链表进行了关联,既贴合实际,也是程序进一步完善的需要。
通过链表的结构,每一步棋都可以追溯到上一步棋,通过为玩家和电脑双方各建立一个链表,方便了悔棋功能的设置。
使用链表的同时还进行内存的动态分配,每一次添加棋子都通过调用list类的添加函数,使得主程序更加简洁。
判断胜负与对电脑应该下的位置进行打分通过两个函数实现。
判断胜负的函数较简单,只需对当前所下位置处各个方向的连珠情况进行比较,返回游戏是否结束或某一方获胜的结果即可。
难点在于计算机下棋算法的设计,在给计算机下棋的位置进行评估时,需要考虑四个方向,还需考虑一些其他的情况,想得越周到便意味着计算机算法越完善,同时还需要由不同的方面根据不同的情况对某一位置赋予不同的分数,分数的确定也是一个困难所在。
在我的算法中,更多的考虑的是如何让电脑避免失败,同时也有一定的进攻能力。
对每一位置程序都会对电脑下在该处和玩家下在该处同时进行评分,然后选择分数最高处,这样玩家最有威胁的位置和电脑最有威胁的位置都在程序的考虑之内。
在这个评分函数中,取的是四个方向中的最大值,这样的设置虽然在一定程度上能够实现不同方向上的综合考虑(在某一方向评分已经较高的情况下还有另一方向评分更高,当然是一个好位置),但是还不足,因为有些位置落棋后可能对多个方向都有好处,此时仅仅取其中的最高值当然是不够的,可以在函数中增加其他方向加分的功能,但这对分数权重的分配和细节考虑上无疑有更高的要求,否则可能会导致多方向的小利战胜了某一方向上的大利,直接影响电脑的输赢。
这是我的程序还需完善的地方。
总之,这个程序满足了五子棋人机对战游戏的基本要求,同时也可以被改编为双人对战游戏。
游戏还有添加功能的空间,算法也可以更加完善。
以此作为我应用程序编程、电脑算法及图形界面编程的初步尝试。
7.源程序清单1.chessboard.h文件#include<iostream>#include<graphics.h>#include<conio.h>using namespace std;class chessboard{public:chessboard(); //开始界面void initboard(); //布置棋盘};2.chessboard.cpp文件#include"chessboard.h"chessboard::chessboard() //开始界面{initgraph(900,800); //初始化为横向个点,纵向个点setbkcolor(WHITE);cleardevice();settextcolor(RED);settextstyle(60, 0, _T("楷体"));outtextxy(220, 100, _T("五子棋人机对战"));settextstyle(30, 0, _T("宋体"));outtextxy(300,300,_T("按任意键开始游戏"));getch();}void chessboard::initboard(){int i;initgraph(900,800);setbkcolor(BROWN);cleardevice(); //清除屏幕和图形缓冲区settextcolor(RED);settextstyle(120, 0, _T("隶书"));outtextxy(780, 80, _T("五"));outtextxy(780, 200, _T("子"));outtextxy(780, 320, _T("棋"));settextstyle(30,0, _T("楷体"));outtextxy(780,500,_T("按右键"));outtextxy(800,530,_T("悔棋"));for(i=50;i<=750;i=i+50) //绘制棋盘{setlinecolor(BLACK);line(50,i,750,i);line(i,50,i,750);}setfillcolor(BLACK); //绘制天元和星fillcircle(200,200,4);fillcircle(200,600,4);fillcircle(600,200,4);fillcircle(600,600,4);fillcircle(400,400,4);}3.piece.h文件#include<iostream>#include<graphics.h>using namespace std;class piece //棋子基类{public:piece();virtual ~piece();int getx();int gety();virtual void print() const=0; //绘制棋子函数protected:int x; //棋盘上的坐标int y;};class piece_player:public piece //玩家棋子类{public:piece_player();piece_player(int,int);virtual ~piece_player();virtual void print() const; //绘制玩家棋子函数piece_player *p_next; //链表结构};class piece_computer:public piece //电脑棋子类{public:piece_computer();piece_computer(int,int);virtual ~piece_computer();virtual void print() const; //绘制电脑棋子piece_computer *c_next;};class player_list //玩家棋子链表{public:player_list();~player_list();bool insert(int,int); //插入节点函数bool Delete(int a[16][16]);protected:piece_player *p_head;};class computer_list //电脑棋子链表{public:computer_list();~computer_list();bool insert(int,int); //插入节点函数bool Delete(int a[16][16]);protected:piece_computer *c_head;};extern int judge(int,int,int,int a[][16]); //判定胜负函数extern int score(int,int,int,int a[][16]); //打分函数4.FiveChess.cpp文件#include"piece.h"piece::piece(){x=0;y=0;}piece::~piece(){}int piece::getx(){return x;}int piece::gety(){return y;}piece_player::piece_player(){x=0;y=0;}piece_player::piece_player(int a, int b){x=a;y=b;p_next=NULL;}piece_player::~piece_player(){}void piece_player::print() const{setfillcolor(WHITE); //画一个白色的棋子fillcircle(x,y,20);}piece_computer::piece_computer(){x=0;y=0;}piece_computer::piece_computer(int a, int b){x=a;y=b;c_next=NULL;}piece_computer::~piece_computer(){}void piece_computer::print() const{setfillcolor(BLACK); //画一个黑色的棋子fillcircle(x,y,20);}player_list::player_list(){p_head=NULL;}player_list::~player_list(){piece_player *p=p_head; //链表析构函数,直到所有节点都被清除for(;p!=NULL;){p_head=p->p_next;delete p;p=p_head;}}bool player_list::insert(int a, int b) //插入新的节点{piece_player *ptemp=new piece_player(a,b);if(ptemp==NULL)return false;ptemp->p_next=p_head;p_head=ptemp;ptemp->print();return true;}bool player_list::Delete(int a[16][16]) {int x,y;if(p_head==NULL)return false;piece_player *p;x=p_head->getx();y=p_head->gety();a[x/50][y/50]=0;setfillcolor(BROWN);fillcircle(x,y,20);setcolor(BROWN);circle(x,y,20);setcolor(BLACK);line(x-20,y,x+20,y);line(x,y-20,x,y+20);p=p_head->p_next;delete p_head;p_head=p;return true;}computer_list::computer_list(){c_head=NULL;}computer_list::~computer_list(){piece_computer *p=c_head;for(;p!=NULL;){c_head=p->c_next;delete p;p=c_head;}}bool computer_list::insert(int a, int b){piece_computer *ctemp=new piece_computer(a,b);if(ctemp==NULL)return false;ctemp->c_next=c_head;c_head=ctemp;ctemp->print();return true;}bool computer_list::Delete(int a[16][16]){int x,y;if(c_head==NULL)return false;piece_computer *p;x=c_head->getx();y=c_head->gety();a[x/50][y/50]=0;setfillcolor(BROWN);fillcircle(x,y,20);setcolor(BROWN);circle(x,y,20);setcolor(BLACK);line(x-20,y,x+20,y);line(x,y-20,x,y+20);p=c_head->c_next;delete c_head;c_head=p;return true;}extern int a[16][16];extern int judge(int x,int y,int s,int a[][16]){int i,j; //坐标int p,q; //记录连珠数int vertical,horizon,rincline,lincline; //记录四个方向的连珠数for(i=x,p=0;(i<x+5)&&(i<16);i++) //水平连珠数{if(a[i][y]!=s)break;elsep++;}for(i=x-1,q=0;(i>x-5)&&(i>0);i--){if(a[i][y]!=s)break;elseq++;}horizon=p+q;for(j=y,p=0;(j<y+5)&&(j<16);j++) //竖直连珠数{if(a[x][j]!=s)break;elsep++;}for(j=y-1,q=0;(j>y-5)&&(j>0);j--){if(a[x][j]!=s)break;elseq++;}vertical=p+q;for(i=x,j=y,p=0;(i<x+5)&&(j<y+5)&&(i<16)&&(j<16);i++,j++) //右斜方向连珠数{if(a[i][j]!=s)break;elsep++;}for(i=x-1,j=y-1,q=0;(i>x-5)&&(j>y-5)&&(i>0)&&(j>0);i--,j--){if(a[i][j]!=s)break;elseq++;}rincline=p+q;for(i=x,j=y,p=0;(i>x-5)&&(j<y+5)&&(i>0)&&(j<16);i--,j++) //左斜方向连珠数{if(a[i][j]!=s)break;elsep++;}for(i=x+1,j=y-1,q=0;(i<x+5)&&(j>y-5)&&(i<16)&&(j>0);i++,j--){if(a[i][j]!=s)break;elseq++;}lincline=p+q;if((vertical>=5)||(horizon>=5)||(rincline>=5)||(lincline>=5)) //判断某一方是否胜利{if(s==1)return 1;else if(s==2)return 2;elsereturn 0;}else return 0;}extern int score (int m,int n,int s,int a[][16]) //打分函数{int i1,j1,i2,j2; //坐标记录int i;int p=0,q=0; //计算连子数int score[4]={0,0,0,0}; //记录四个方向的一串连子的两头的情况,是否被另一方堵上int x=0; //分数int vertical,horizon,lincline,rincline; //四个方向的连子数for(i1=m;(i1<m+5)&&(i1<16);i1++){if(a[i1][n]!=s){if(a[i1][n]==0) score[0]++;else if(i1<=5) //棋盘大小限制score[0]--;break;}elsep++;}for(i2=m-1;(i2>m-5)&&(i2>0);i2--){if(a[i2][n]!=s){if(a[i2][n]==0) score[0]++;else if(i2>=10) //棋盘大小限制score[0]=0;break;}elseq++;}horizon=p+q;if((horizon<=4)&&((m==1)||(m==15))) //棋盘边界位置score[0]=0;if((horizon>=4)&&(a[i2][n]==0)&&(a[i1][n]==0)) //防止四连珠或形成四连珠{if(s==2)score[3]+=3;score[3]+=2;}for(j1=n,p=0;(j1<n+5)&&(j1<16);j1++){if(a[m][j1]!=s){if(a[m][j1]==0)score[1]++;else if(j1<=5)score[1]--;break;}elsep++;}for(j2=n-1,q=0;(j2>n-5)&&(j2>0);j2--){if(a[m][j2]!=s){if(a[m][j2]==0)score[1]++;else if(j2>=10)score[1]--;break;}elseq++;}vertical=p+q;if((vertical<=4)&&((n==1)||(n==15)))score[1]=0;if((vertical>=4)&&(a[m][j2]==0)&&(a[m][j1]==0)){if(s==2)score[1]+=3;score[1]+=2;}for(i1=m,j1=n,p=0;(i1<16)&&(i1<m+5)&&(j1<16);i1++,j1++) {if(a[i1][j1]!=s){if(a[i1][j1]==0) //{score[2]++;}else if(i1<=5)score[2]--;break;}elsep++;}for(i2=m-1,j2=n-1,q=0;(i2>0)&&(i2>m-5)&&(j2>0);i2--,j2--) {if(a[i2][j2]!=s)if(a[i2][j2]==0){score[2]++;}else if(i2>=10)score[2]--;break;}elseq++;}rincline=p+q;if((rincline<=4)&&((n==1)||(n==15)||(m==1)||(m==15))) score[2]=0;if((rincline>=4)&&(a[i2][j2]==0)&&(a[i1][j1]==0)){if(s==2)score[2]+=3;score[2]+=2;}for(i1=m,j1=n,p=0;(i1>0)&&(i1>m-5)&&(j1<16);i1--,j1++) {if(a[i1][j1]!=s){if(a[i1][j1]==0)score[3]++;else if(j1<=5)score[3]--;break;}elsep++;}for(i2=m+1,j2=n-1,q=0;(i2<16)&&(i2<m+5)&&(j2>0);i2++,j2--) {if(a[i2][j2]!=s){if(a[i2][j2]==0)score[3]++;else if(j2>=10)score[3]--;break;elseq++;}lincline=p+q;if((lincline<=4)&&((n==1)||(n==15)||(m==1)||(m==15)))score[3]=0;if((lincline>=4)&&(a[i2][j2]==0)&&(a[i1][j1]==0)){if(s==2)score[3]+=3;score[3]+=2;}if(horizon>4||vertical>4||lincline>4||rincline>4)x=100;else{for(i=0;i<4;i++){if(score[i]<=0)score[i]=-20;}x=horizon+score[0];if(vertical+score[1]>x)x=vertical+score[1];if(lincline+score[2]>x)x=lincline+score[2];if(rincline+score[3]>x)x=rincline+score[3];}return x; //返回最大的分数}5.main.cpp文件#include"chessboard.h"#include"piece.h"int a[16][16]; //15*15棋盘,只用至的数组int main(){chessboard board1;MOUSEMSG m;int i,j; //棋盘数组坐标bool p=0; //记录player是否下过int score_player[16][16],score_computer[16][16]; //判断电脑的落子处int score_max; //记录打分的最大值int max_x,max_y; //记录打分最大值的坐标int x;while(1){board1.initboard();player_list *player=new player_list; //建立玩家链表computer_list *computer=new computer_list; //建立电脑链表for(i=1;i<16;i++) //初始化棋盘,代表没有棋子,代表player,代表computerfor(j=1;j<16;j++)a[i][j]=0;HWND wnd=GetHWnd(); //获取玩家选择if (MessageBox(wnd, _T("大神,您要让电脑先下吗?"), _T("选项"),MB_OKCANCEL | MB_ICONQUESTION) == IDOK){i=8;j=8;a[i][j]=2;computer->insert(i*50,j*50); //点击确定,电脑先下}while(1){while(p==0){m=GetMouseMsg(); //获取玩家落子位置switch(m.uMsg){case WM_LBUTTONDOWN:{for(i=50;i<=750;i=i+50){for(j=50;j<=750;j=j+50){if((m.x<i+10)&&(m.x>i-10)&&(m.y<j+10)&&(m.y>j-10)&&(a[i/50][j/50]==0)) // 判断是否能下及下好位置{player->insert(i,j);p=1;a[i/50][j/50]=1;break;}}if(p)break;}}break;}case WM_RBUTTONDOWN: //右键悔棋{computer->Delete(a);player->Delete(a);b=1;break;}}if(b) //若悔棋直接跳到玩家出棋{b=0;continue;}p=0;if(judge(i/50,j/50,1,a)==1) //判断玩家是否胜利{settextcolor(YELLOW);settextstyle(30, 0, _T("华文行楷"));outtextxy(200, 0, _T("---恭喜您,您胜利了!按任意键继续---"));delete computer;delete player;getch();break;}for(i=1;i<16;i++) //初始化棋盘各个位置分数for(j=1;j<16;j++){score_computer[i][j]=0;score_player[i][j]=0;}for(i=1;i<16;i++){for(j=1;j<16;j++){if(a[i][j]==0){a[i][j]=1;x=score(i,j,1,a);score_player[i][j]+=x; // 记录如果玩家下在此处,得到多少分a[i][j]=2;x=score(i,j,2,a);score_computer[i][j]+=x; // 记录如果电脑下在此处,得到多少分a[i][j]=0;}}}// 找到能下棋的空位置中,假设电脑和人下在此处,得到分数中最大值for(i=1,score_max=score_computer[1][1];i<16;i++){for(j=1;j<16;j++){if(score_computer[i][j]>score_max){score_max=score_computer[i][j];max_x=i;max_y=j;}}}for(i=1;i<16;i++){for(j=1;j<16;j++){if(score_player[i][j]>score_max){score_max=score_player[i][j];max_x=i;max_y=j;}}}//玩家与电脑的评分标准是一样的,故而电脑既能判断出如何下接近胜利或如何下避免输棋a[max_x][max_y]=2; // 在最高分处落子computer->insert(max_x*50,max_y*50);if(judge(max_x,max_y,2,a)==2){settextcolor(YELLOW);settextstyle(30, 0, _T("华文行楷"));outtextxy(200, 0, _T("---您输了,不太走运哦~按任意键继续---"));delete computer;delete player;getch();break;}} //内部的while} //外部的whilereturn 0;}。