版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Ⅰ摘要人工智能是一门正在迅速发展的新兴的,综合性很强的交叉科学。它与生物工程、空间技术一起被并列为二十一世界三大尖端技术。它的中心任务是研究如何使计算机去做那些过去只能靠人的智力才能做的工作。目前各发达国家都把人工智能作为重点项目,列入本国的高科技发展计划当中,投入巨大的人力和物力。计算机人机对弈也是其中之一。作为人智能研究的一个重要分支,计算机博弈是检验人工水平的一个重要方面。它的研究为人工智能带来了很多重要的方法和理论,产生了广泛的社会影响和学术影响。五子棋人机对弈是计算机博弈中的一种。研究其计算机算法,可以让我们看到人工智能的稚形,也有助于我们人脑的开发。五子棋是我国发明的,研究它可以让更多的外国人了解五子棋,这有助于我国优秀文化的推广。关键词:人工智能,计算人机对弈,五子棋,算法ⅡAbstractArtificialintelligenceisarapidlydevelopingnew,integratedastrongFrontierScience.Itiswithbio-engineering,spacetechnologyhasbeenlistedas21intheworldalongwiththethreecutting-edgetechnology.Itscentraltaskistostudyhowtomakethecomputerdothatinthepasttorelyonhumanintelligencetodo.AIiscurrentlyregardedasthefocusofthedevelopedcountriesincludedinthiscar'shigh-techdevelopmentprojectsinvestedtremendoushumanandmaterialresources.
Man-machinechesscomputerisoneofthem.Asahumanstudyofanimportantbranchofintelligence,thecomputergametotestthelevelofanimportantaspectofthemanual.Itsresearchinartificialintelligencehasresultedinmanyimportantmethodsandtheoriestoproduceawiderangeofsocialimpactandacademicimpact.
Man-machinechessgameRenjuinoneofthecomputer.Tostudythecomputeralgorithm,wecanseethebeginningofartificialintelligenceshadow,butalsohelpustohumanbraindevelopment.BackgammoninventedinChina,andtheresearchitcanallowmoreforeignerstounderstandandhelptopromoteChina'straditionalculture.
Keywords:ArtificialIntelligence,Man-machineCchessComputer,Man-machineChess,AlgorithmⅢ目录TOC\o"1-2"\h\u24733摘要 Ⅰ2055Abstract Ⅱ目录Ⅲ绪论1需求分析22.1业务需求22.2性能需求22.3系统平台需求2五子棋相关基础43.1五子棋解释43.2五子棋的基本规则43.3五子棋的常用术语5开发工具、环境及其技术74.1Java简介74.2Java编程环境9程序设计思路与实现105.1程序设计思路105.2程序设计13结论33参考文献致谢附录第一章:绪论1.1前言电脑已经深入到日常工作和生活的方方面面,比如文字处理、信息管理、辅助设计、图形图像处理、教育培训以及游戏娱乐等。Windows系统的推出使电脑从高雅的学术殿堂走入了寻常百姓家,各行各业的人们无须经过特别的训练就能够使用电脑完成许许多多复杂的工作。然而,虽然现在世界上已经充满了花样繁多的各种软件,但它们依然不能满足用户的各种特殊需要,人们还不得不开发适合自己特殊需求的软件。Java语言作为一种面向对象的编程语言,具有分布式,可移植,高性能,多线程等特点。通过系统的学习,人们就可以使用它开发出功能齐全,满足特殊需求的应用程序。Java语言易学易用,对学习者掌握技能,开拓思维都有很大的帮助。我作为一名学生,在系统的学习了Java语言之后,经常用它搞一些小程序。这次毕业设计,正好将学过的Java语言中的各种技术综合起来,用Jbuilder2006开发工具编写一个小游戏,既对自己学过的技能进行一次检验,也能系统地将学过的知识复习巩固。 随着计算机技术的不断发展,网络技术的普及范围越来越广,网络能够提供的服务多样、便捷,已经成为人们生产生活中不可缺少的重要组成部分。如今网络休闲游戏发展迅速,它凭借健康、方便、互动性强、益智等诸多优点,成为大部分现代人休闲娱乐的首选。网络五子棋游戏是使用Java语言开发的一款游戏。它使用SOCKET建立连接,多线程处理数据,以及可嵌入网络浏览器的ALET作为客户端,这些特点使这款游戏无论是服务器还是客户端的实现都相对容易。通过对该软件的编写,还可以巩固我们对以上各种知识的掌握和理解。 第二章需求分析为了开发出真正满足用户需求量的软件产品,首先必须知道用户的需求。软件需求中包括了多个方面来说明用户需求。在这一章中,主要从以下几方面来说明系统的需求。2.1业务需求2.1.1此系统使用范围要求此系统为智力游戏,适合于各类游戏爱好者。由于其经典性及其游戏的简单性,各类人士都可以也都爱玩。人们在与电脑对战享受娱乐的同时,也会体会到自己的智力也会有所提升。2.1.2功能要求该款游戏主要由一下几个模块组成:五子棋游戏五子棋游戏人机对弈模式人人对弈模式具有悔棋功能更换棋盘背景图2—1五子棋功能模块图人机对弈模式:选择该模式可以实现人与电脑之间的对弈,电脑会智能的选择该在哪处下子,并会在每次下棋结束后判断是否有哪方已经获胜,如果获胜则结束本局游戏,并提示玩家游戏结束。人人对弈模式:选择该模式可以实现人与人之间的对弈,系统会提示哪方先下,然后玩家之间交替的下棋,同样系统会在下完每次棋后判断是否有哪方已经获胜,如果获胜则结束本局游戏,并提示玩家游戏结束。悔棋功能:这个功能也是根据游戏的实际需求而存在的,在现实生活中难免有失误下错了棋,那么就需要悔棋。此功能提供了悔棋功能,使得下棋的灵活性有所提高。玩家若想悔棋,则只需选择悔棋按钮便可以重新下过刚才的棋。更换棋盘背景:次功能可以根据玩家的爱好任意更换棋盘的背景颜色,由于每个人对颜色的喜好不一样,因此这个功能也是非常必需的。也行更换一种玩家所喜欢的颜色,玩家能发挥得更好。2.2性能需求该款五子棋游戏功能虽然简单,但最主要的还是实现了人人对弈模式和人机对弈两种模式,所以从这个角度来说,该款游戏需要能很好的在两种模式间良好的转换。虽然系统不大,但要在满足玩家的基本要求的情况下,电脑有一定的智能,能给于新手一定的帮助。2.3系统平台需求编程语言:JAVA操作系统:Windowsxp系列开发工具:Myeclipse第三章五子棋的相关基础3.1五子棋解释 引用《辞海》中所言,五子棋是“棋类游戏,棋具与围棋相同,两人对局,轮流下子,先将五子连成一行者为胜。”。五子棋的名称:日文亦有“连五子、五子连、串珠、五目、五目碰、五格、五石、五法、五联、京棋”等多种称谓,英文则称之为FIR(FiveInARow的缩写)、Gomoku(日语“五目”的罗马拼音)、Gobang、connect5、mo-rphion。捷克语piskvorky,韩语omok、韩国人还称之为情侣棋。3.2五子棋基本规则1.五子棋行棋时,黑棋先下第一子,由天元开始,后白棋在黑棋周围的交叉点的落子。接着黑方再以天元中心的25个交叉点的范围内落盘面的第三子,之后黑白双方相互顺序子。
2.最先在棋盘线交点横向,纵向,斜向形成已方的五个棋子连续的一方为胜。
3.出现禁手对方指出后将判负,其中包括两个或两个以上的活三,活四,长连均称之为禁手。
4.禁手只对黑棋有效,白棋无禁手。
5.黑方禁手形成时,白方需立即指出,黑方将被判负。若白方未发现黑方禁手存在而继续应子,其后指出黑方禁手不能判黑方负。
6.黑方连五与禁手同时形成,因黑方已连成五即黑方已获胜,故禁手规则失效。
7.在对局中,在盘上落下的子又拿起来,此动作称为拔子,若拔子将被判为负。
8.在对局中棋子掉落在棋盘上将被判负。若推子或蹭子,以盘面第一落点为准。用手将棋子推正不算违犯规则。
9.在对局中,一方自行中止比赛如:中途退场,将被判负。
10.在对局中对方宣布认输,本局获胜。
11.超过比赛规定所用时间限制,将被判为负:正式比赛期间,迟到时间超过比赛容许时间将被判负。
12.如下至最终一子仍不分胜负则定为平局。
13.中盘期间双方同意和局提议,判定为平局。 3.3五子棋常用术语1.着:也称“步”。对局中把一个棋子按照规则放到某一交叉点,称之为一着棋。一着是否完成有两种规则:
(1)在执行落子无悔规则是,以行棋者的手离开棋子为一着已完成。
(2)在执行限时规则时,以行棋者按下棋钟作为一着已完成。
2.PASS:五子棋中引入的英文名称,即应该行棋的一方主动放弃此次行棋的机会,由对方继续行棋。
3.先手:对方必须应答的着法,如对方形成活三必须阻止其形成活四。
4.绝对先手:相对先手而言,即形成同色连四或嵌五,对方必须应着,就是绝对先手。绝对先手又叫“冲”。
5.VCF:(VictoryofContinusFour的缩写)意思是利用连续冲四取胜之意。利用连续不断的冲四或嵌五的绝对先手,制止形成连五获得胜利的一种方法。在对局接近尾声或排局解题中一种常见的取胜技巧。
6.追下取胜:是指白棋利用黑棋禁手取胜的战术。白1冲四,迫使黑2形成“四、四”禁手(即冲四,活四禁手),这种取胜方法叫做追下取胜。
7.自由取胜:追下取胜以外的取胜方法,即未利用黑棋禁手战术而取胜。
8.一子双杀:是指对局中一方落子后出现两个叫杀点即两个获胜点,而使对方无法防守的情形。一般是有两个冲四活三点,白棋的双活三,双四均可称为一子双杀。
9.阳线:棋盘上可见的横线与直线的总称。
10.阴线:也称“斜线”。是棋盘上不可见的斜行线。
11.“四、三”:指同时具备两个先手,其中一个四,另一个是活三。
12.“活三”、“嵌五”、“冲四”:参见五子棋重要棋形讲座。
13.禁手:对局中禁止使用的战术或被判为负的行棋手段。14.开局:也称“布局”。布局阶段大体为七至十几着之内。种类繁多,职业连珠五子棋有二十四种开局。
15.局面:亦称“局势”。为对局中某一段时间内双方子力的配置情况。
16.优势:是指足以取胜的优势局面,其对方即为败势。
17.妙着:对局中走出的一步精妙的着法。既合乎逻辑又出人意料,有使局面顿时改观的效果,对局势的发展及对局的质量都有重大影响。
18.好着:也称“佳着”。对局中成功的某一步。
19.正着:对局的某一局面中的正确着法。
20.劣着:对局中,导致严重不利后果的一步错误着法。
21.败着:也称“失着”“漏着”。对局中造成局面恶化的一步严重错误着法。
22.等着:对局中具有等待性的一步着法,主要意图是等待有利时机。
23.废着:也称“空着”。对局中不起作用的着法。实际上指浪费时间毫无疑义的错着。
24.抢先:对局中利用反活三或冲四的强制手段夺取主动权的着法。
25.打谱:按照棋谱演练着法,是提高棋艺水平的重要方法之一。26.复局:也叫“复着”。对局结束又重演对局的过程。一般用以研究、比较双方的成败得失和着法的优劣。第四章开发工具、环境及其技术4.1JAVA简介JAVA技术介绍: Java技术是一门编程语言,也是一个平台,它基于Java虚拟机技术,借助这个东西建立了跨平台的优势。(题外话:Java热门的原因之一就是一个跨平台的概念,和跨平台类似跨浏览器的好处也是如此,这也是现在AJAX技术流行的原因之一。另外现在热炒的RIA富客户端的概念下的技术除了AJAX外还有Adobe的Flash/Flex,微软的SilverLight,SUN的JavaFX等,个人更看好FLash/Flex,原因是Flash插件在浏览器端占用率很高) Java技术的重要性就不讲了,从最近流行的一个统计数据上来说,目前世界上编程语言Java、C、VB、C++依次排名前4位,这排名本身不说明什么,至少也是工业界对编程语言使用上一个侧面的反映吧。 Java编程语言与众不同之处在于:Java程序既是编译型的(转换为一种称为Java字节码的中间语言),又是解释型的(JVM对字节码进行解析和运行)。编译只进行一次,而解释在每次运行程序时都会进行。编译后的字节码采用一种针对JVM优化过的机器码形式;解释器是JVM的实现。这段是摘自网上的,编译原理学的不是很好,对这门语言的背后运行机制理解到这样了。 Java平台是一种纯软件平台,它有三个版本JavaSE、JavaEE、JavaME。 JavaSE(JavaPlatform,StandardEdition)这个版本以前叫做J2SE,后来版本号从1.4直接跳到5.0,其实也就是1.5,所以就叫成JavaSE5.0。目前Java开发人员使用较多的版本是5.0,当然还有JavaSE6.0这个更新的版本。它允许开发和部署在桌面、服务器、嵌入式环境和实时环境中使用的Java应用程序。JavaSE还包含了支持JavaWeb服务开发的类,并为JavaEE这个版本提供基础。 虽说桌面应用程序,Java一直不被看好,但也稍微提一下,负责桌面GUI开发的类库我知道的有:JDK自带的主要是AWT/SWING这个Java原生类库;也可以使用IBM的SWT/JFace这个第三方类库。开发工具我了解的有:NetBeans(最近已经是6.0final版了,做GUI有使用VB的感觉),Eclipse(SWT/JFace这个项目其实就是做Eclipse项目时扩展出来的,所以对SWT/JFace支持的也不错)。 JavaEE(JavaPlatform,EnterpriseEdition)这个版本以前叫做J2EE,也就是大家可能听得比较多的,也是Java比较流行的领域,Java的企业级版本。JavaEE下有很多流行的开发框架,像Struts、Spring、Hibernate这种流行的所谓SSH组合等。 根据项目大小、应用领域,技术平台的选择面还是很多的,除了JavaEE,还有.Net,LAMP组合(Linux、Apatch、MySql、PHP组合),相对来说比较新Ruby在RubyonRails的框架应用,后两者可能在相对来说比较轻量级的Web领域运用成功案例比较多,更重量的企业级潜力还有待挖掘。 JavaME(JavaPlatform,MicroEdition)这个版本以前叫做J2ME。应用领域像各种移动设备和嵌入式设备,比如:手机、PDA、电视机顶盒和打印机。 JavaME不是太熟悉,不过移动设备和嵌入式设备的开发个人觉得算是比较有意思的领域,最近比较瞩目的业界新闻有一个就是Google发布开源智能手机操作系统开发平台Android,也就是前一阵子炒得很火的GPhone(原来Google出的不是手机,而是一个手机操作系统开发平台)。这个平台貌似会对JavaME有些冲击,按照网上的消息,Android包括:1、高度定制的Linux操作系统内核及智能手机硬件驱动支持;2、经过Google修改过的Java虚拟机Dalvik,这里的性能比SUN的Hotspot高,支持大部分Java核心类库;3、大量智能手机开发核心类库;4、大量现成的智能手机应用软件;5、基于Eclipse的开发环境。也是按照网上的说法,JavaEE提供了统一的编程平台,但不能调用操作系统的资源;而Android下直达操作系统,上直达应用软件,如:浏览器、日历、地图等。 Java开发工具很多,个人使用的IDE有Eclipse和NetBeans。Eclispe比较流行,各种插件也多,当然用起来也不错;NetBeans现在也是越做越好了,介绍这两个IDE主要是开源的,当然还有其它工具如JBuilder、IntelliJ、JCreator。这些IDE各有优势劣势,根据你开发的项目来选择了。4.2JAVA编程环境:4.2.1环境变量java(TM)SEDevelopmentKits,即JDK。设置环境变量:右击我的电脑->属性->高级->环境变量,这时候可以看到以下的环境变量:Path:系统在任何路径下都可以识别Java命令。classPath:为Java加载类(包括class,lib)的路径,只有类在classPath中,Java命令才能识别。JAVA_HOME:Java的安装路径。这三个变量是必须正确设置的,否则Java命令将可能不会正常运行,具体设置如下:Path:
;C:\ProgranFiles\java\jdk1.6.0_01\binclasspath:
.;ProgranFiles\java\jdk1.6.0_01\lib\dt.jar;ProgranFiles\java\jdk1.6.0_01\lib\tools.jarJAVA_HOME:
ProgranFiles\java\jdk1.6.0_014.2.2Eclipse插件XMLBuddy:编辑xml文件;下载地址为。FatJar:打包插件,可以方便的完成各种打包任务,可以包含外部的包等。Log4E:Log4j插件,提供各种与log4j相关的任务,Log4j专用于为程序输入调试信息。Lomboz:Ecilpse的一个J2EE的插件,可以将很多java应用服务器,J2EE组件和web应用开发集成到Eclipse中,可以帮助Java开发者使用Eclipse建立,测试和部署J2ee应用。支持jsp编写,包括语法着色和语法检查:。MyEclipse:J2EE开发插件,支持jsp,EJB,数据库操作。(6)TomcatPlugin:支持Tomcat插件。第五章程序设计思路与实现5.1程序设计思路 5.1.1.设计思想 1.本程序要实现五子棋的游戏功能,必须先有一个棋盘,所以,通过继承JPanel,然后在JPanel上画出一个17*17的棋盘,另外还有三个按钮:重新开局、请黑方下子和请白方下子,提醒用户进行相应的操作。当然,JPanel必须放在JFrame中,所以,又通过继承JFrame得到一个实例。 2.对于下棋的操作,通过对JPanel增加鼠标事件监听器MouseListener,每次当用户点击鼠标时,先取得点击的坐标值,然后换算成对应棋盘上(即棋盘数组)的位置(数组的下标)。 3.判断此处是否已经有棋子,如果有则提示玩家重新下子,否则通过java里的画图函数在此处画上棋子,重新刷新输出棋盘。 4.判断该颜色棋子的上下左右是否满足连续五个,是的话提醒相应玩家获胜,不是的话,更换玩家下棋。 5.对于玩家的更换是程序自动的,每次用户点击鼠标后,若本局还未结束则会变换玩家,从而画出对应黑方白方的棋子,直到有一方获胜程序技术。5.1.2.程序设计分析 1.本款游戏有“游戏”和“选项”两个选项,其中“游戏”包括开局、重新开始、结束游戏几个选项;选项里边则包括对弈模式、悔棋、更改背景颜色几个选项,玩家可以根据具体需要选择使用。2.绘制棋盘,17条横线,17条竖线,在直线交点处下棋子(实心黑白圆形)。3.首先程序会判断对弈模式是人机对弈还是人人对弈模式,若是人机对弈则是玩家先下,玩家是黑方,电脑是白方。若是人人对弈,则是黑方先下,黑白交替下子。4.棋盘处于鼠标监听状态,当鼠标在棋盘上有点击操作的时候,程序会获得鼠标点击的坐标然后换算成对应的棋盘的位置,再判断此处是否有棋子,假如没有,那么在此处画出对应颜色的实心棋子,假如已经有棋子了,则提示玩家此处已经有棋子请重新下棋。5.当选择的是人机对弈模式的时候,轮到电脑下子时,电脑会通过算法计算每个没有棋子的位置的重要性来选择最重要的位置下子。6.人机对弈算法简介:本款游戏最核心的地方就是算法,因为这是整个程序最难的模块。算法的中心思想是:利用分数代表每个位置的重要程度,越重要的位置的分数值会越高,当电脑下棋时会先将电脑和玩家棋型的分数分别计算一遍,然后选择二者中分数最高的点下子。如果玩家的分数高,那么代表电脑应该防守,如果电脑的分数高,那么代表电脑应该进攻。具体的分数值赋值如下:分数电脑玩家活二6050半活二4035死二1010半死二1010活三950700半活三900650死三100100半死三100100活四60003500半活四50003000死四4000800半死四3600750活五2000015000半活五100003300死五2000015000半死五100003300解释一下其中的活,半活,死,半死:活:代表几个子是相连的,中间没有空格,两端都至少有一个空格。半活:代表几个子不是相连的,几个子中间有一个空格,两端都至少有一个空格。死:代表几个子是相连的,中间没有空格,但有一端紧挨着对方的棋子或有一端正好在棋盘的边界。半死:代表几个子不是相连的,几个子中间有一个空格,而且一端紧挨着对方的棋子或有一端正好在棋盘的边界。每个位置的分数的计算方式是各个方向的分数相加,最后找出电脑棋型和玩家棋型的分数的最高的位置为电脑的下棋点下棋。7.当任何一方有五个棋子沿着横,竖,斜连在一起时,系统自动判断赢棋,并显示黑方或白方胜利。棋局结束后,任何一方均不能继续操作。8.程序流程如下图4-1:图5-1程序流程图5.2程序设计这个游戏程序包含两个类:DrawPanel:棋盘类,用于绘画棋盘及棋子。PlayerVsPC:主程序类,窗口的创建和整个逻辑程序代码。类DrawPanel代码:packageresource;importjava.awt.BasicStroke;importjava.awt.Color;importjava.awt.Graphics;importjava.awt.Graphics2D;importjava.awt.geom.Ellipse2D;importjava.awt.geom.Line2D;importjavax.swing.JPanel;publicclassDrawPanelextendsJPanel{ privateint[][]a; privateintn,m; publicDrawPanel(intk[][],intn1,intm1){ a=k; n=n1; m=m1; } publicvoidpaintComponent(Graphicsg){ super.paintComponent(g); Graphics2Dg2=(Graphics2D)g; Graphics2Dg3=(Graphics2D)g; doubleX=20; doubleY=20; doublewidth=480; doubleheight=480; doublejiange=30; //画棋盘网格 for(inti=0;i<=width/jiange;i++){ g2.draw(newLine2D.Double(X+i*jiange,Y,X+i*jiange,height+Y)); g2.draw(newLine2D.Double(X,Y+i*jiange,width+X,Y+i*jiange)); } //画中间点的标记 g3.setPaint(Color.RED); g3.draw(newLine2D.Double(254,245,254,254)); g3.draw(newLine2D.Double(245,254,254,254)); g3.draw(newLine2D.Double(267,245,267,254)); g3.draw(newLine2D.Double(267,254,275,254)); g3.draw(newLine2D.Double(245,266,254,266)); g3.draw(newLine2D.Double(254,266,254,275)); g3.draw(newLine2D.Double(266,275,266,266)); g3.draw(newLine2D.Double(266,266,275,266)); //画旗子 for(inti=1;i<a.length-1;i++){ for(intj=1;j<a[i].length-1;j++){ Ellipse2Dcircle=newEllipse2D.Double(); circle.setFrame(j*30-25,i*30-25,28,28); if(a[i][j]==1){ g2.setPaint(Color.BLACK); g2.fill(circle); }elseif(a[i][j]==2){ g2.setPaint(Color.WHITE); g2.fill(circle); } } } //画旗子上的标记 if(n>0&&m>0){ g2.setPaint(Color.RED); g2.setStroke(newBasicStroke(1.5f)); g2.draw(newLine2D.Double(30*m-16,30*n-16,30*m-4,30*n-4)); g2.draw(newLine2D.Double(30*m-16,30*n-4,30*m-4,30*n-16)); } } }类PlayerVsPC代码:packageresource;importjava.awt.Color;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.awt.event.MouseAdapter;importjava.awt.event.MouseEvent;importjava.awt.Toolkit;importjava.awt.Dimension;importjavax.swing.JColorChooser;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JMenu;importjavax.swing.JMenuBar;importjavax.swing.JMenuItem;importjavax.swing.JPanel;publicclassPlayerVsPC{ privateJFrameframe; //整个窗口 privateJMenuBarbar; //菜单栏 privateJMenuItem[][]jit;//菜单项数组 privateJMenuItem[]mode;//模式项数组 privateJMenu[]jm; //菜单 publicbooleanisBlack; //是否为黑方下子状态 privateint[][]qipan; //棋盘数组 privateintrow; //当前行 privateintcol; //当前列 privateintprow; privateintpcol; privateColorc=newColor(145,125,62); //棋盘背景颜色 privateDrawPanelpanel; //棋盘面板 privateJLabellabel; //棋盘上方的标签 privateJPanelpanel0; //棋盘上方条形面板 privatebooleanisEnd; privateint[][]qixingPC; privateint[][]qixingPlayer; privatebooleanisPC=true;//记录当前下棋模式 privatebooleancMode=true; //记录选择的对弈模式 publicPlayerVsPC(){ frame=newJFrame("五子棋游戏"); bar=newJMenuBar(); jm=newJMenu[2]; jit=newJMenuItem[2][]; qipan=newint[19][19]; qixingPC=newint[17][17]; qixingPlayer=newint[17][17]; for(inti=0;i<19;i++){ for(intj=0;j<19;j++){ qipan[i][j]=0; } } for(inti=0;i<17;i++){ for(intj=0;j<17;j++){ qixingPC[i][j]=0; qixingPlayer[i][j]=0; } } label=newJLabel("人"+(isPC?"机":"人")+"对弈模式,请按开局开始游戏!"); panel0=newJPanel(); addItems(); addEventAction(); printqipan(0,0); } publicvoidaddItems(){ jm[0]=newJMenu("游戏"); jm[1]=newJMenu("选项"); jit[0]=newJMenuItem[3]; jit[0][0]=newJMenuItem("开局"); jit[0][1]=newJMenuItem("重新开始"); jit[0][2]=newJMenuItem("结束游戏"); jit[1]=newJMenuItem[3]; jit[1][0]=newJMenu("对弈模式"); mode=newJMenuItem[2]; mode[0]=newJMenuItem("人人对弈"); mode[1]=newJMenuItem("人机对弈"); jit[1][0].add(mode[0]); jit[1][0].add(mode[1]); jit[1][1]=newJMenuItem("悔棋"); jit[1][2]=newJMenuItem("背景颜色"); for(inti=0;i<jm.length;i++){ for(intj=0;j<jit[i].length;j++){ jm[i].add(jit[i][j]); } } panel0.add(label); bar.add(jm[0]); bar.add(jm[1]); frame.setJMenuBar(bar); frame.add(panel0,"North"); } //给菜单项设定事件 publicvoidaddEventAction(){ jit[0][0].addActionListener(newActionListener(){ //开局 publicvoidactionPerformed(ActionEvente){ row=prow=0;col=pcol=0; isPC=cMode; isBlack=true; isEnd=false; for(inti=0;i<19;i++){ for(intj=0;j<19;j++){ if(i==0||j==0||i==(qipan.length-1)||j==(qipan.length-1)){ qipan[i][j]=-1; }else{ qipan[i][j]=0; } } } if(isPC){ //人机对弈模式 label.setText("游戏开始,请玩家先下棋!"); }else{ //人人对弈模式 label.setText("游戏开始,请"+(isBlack?"黑":"白")+"方先下棋!"); } printqipan(row,col); addEventHandler(); } }); jit[0][1].addActionListener(newActionListener(){ //重新开始 publicvoidactionPerformed(ActionEvente){ row=prow=0;col=pcol=0; isBlack=true; isEnd=false; for(inti=0;i<19;i++){ for(intj=0;j<19;j++){ if(i==0||j==0||i==(qipan.length-1)||j==(qipan.length-1)){ qipan[i][j]=-1; }else{ qipan[i][j]=0; } } } if(isPC){ //人机对弈模式 label.setText("游戏开始,请玩家先下棋!"); }else{ //人人对弈模式 label.setText("游戏开始,请"+(isBlack?"黑":"白")+"方先下棋!"); } printqipan(row,col); addEventHandler(); } }); //给模式选项添加事件监听 mode[0].addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ cMode=false; label.setText("已选择人"+(cMode?"机":"人")+"对弈模式,重新开局将生效!"); } }); mode[1].addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ cMode=true; label.setText("已选择人"+(cMode?"机":"人")+"对弈模式,重新开局将生效!"); } }); jit[0][2].addActionListener(newActionListener(){ //结束游戏 publicvoidactionPerformed(ActionEvente){ label.setText("游戏结束,请按开局开始游戏!"); isEnd=true; } }); jit[1][1].addActionListener(newActionListener(){ //悔棋 publicvoidactionPerformed(ActionEvente){ if(!isPC){ huiqi(); }else{ pchuiqi(); } } }); jit[1][2].addActionListener(newActionListener(){ //背景颜色 publicvoidactionPerformed(ActionEvente){ Colorcc=JColorChooser.showDialog(frame,"棋盘背景颜色", newColor(226,189,0)); if(cc!=null){ c=cc; panel.setBackground(c); } } }); } // 监听鼠标事件,下棋以及判断本盘是否结束,电脑是白方,玩家是黑方 publicvoidaddEventHandler(){ panel.addMouseListener(newMouseAdapter(){ publicvoidmousePressed(MouseEvente){ if(!isEnd){ intx=(e.getX()-5)/30; inty=(e.getY()-5)/30; if(qipan[y+1][x+1]==0){ load(x+1,y+1); }else{ label.setText("此处已经有棋子,请重新下子!"); } } } }); } //电脑下棋 publicvoidpcLoad(){ qixing(); intcount=0; inthang=0; intlie=0; for(inti=0;i<17;i++){ for(intj=0;j<17;j++){ if(qixingPC[i][j]>count){ count=qixingPC[i][j]; hang=i+1; lie=j+1; } if(qixingPlayer[i][j]>count){ count=qixingPlayer[i][j]; hang=i+1; lie=j+1; } } } if(qipan[hang][lie]==0){ load(lie,hang); return; } } //下棋子 publicvoidload(intx,inty){ col=x; row=y; if(isBlack){ prow=row; pcol=col; qipan[row][col]=1; isBlack=false; }else{ qipan[row][col]=2; isBlack=true; } printqipan(row,col); if(panduan(row-1,col-1)){ if(isPC){ label.setText("本局结束,恭喜"+(isBlack?"电脑":"玩家")+"获胜!"); isEnd=true; }else{ label.setText("本局结束,恭喜"+(isBlack?"黑":"白")+"方获胜!"); isEnd=true; } }else{ if(isPC){ label.setText((isBlack?"电脑":"玩家")+"在("+ row+":"+col+")处下子,"+"现在"+(isBlack?"玩家":"电脑")+"下子!"); }else{ label.setText((isBlack?"白":"黑")+"方在("+ row+":"+col+")处下子,"+"现在"+(isBlack?"黑":"白")+"下子!"); } if(!isBlack){ if(isPC){ pcLoad(); } } } } //刷新棋盘 publicvoidprintqipan(intn,intm){ panel=newDrawPanel(qipan,n,m); panel.setBackground(c); frame.add(panel,"Center"); } //人人对弈悔棋 publicvoidhuiqi(){ if(isEnd){ label.setText("游戏已经结束不能悔棋,请重新开局!"); return; } isBlack=!isBlack; qipan[row][col]=0; printqipan(row,col); label.setText((isBlack?"黑":"白")+"方悔棋,请重新下棋!"); } //人机对弈悔棋 publicvoidpchuiqi(){ if(isEnd){ label.setText("游戏已经结束不能悔棋,请重新开局!"); return; } qipan[row][col]=0; qipan[prow][pcol]=0; printqipan(row,col); label.setText((isBlack?"玩家":"电脑")+"悔棋,请重新下棋!"); } //算出双方的棋形数组 publicvoidqixing(){ for(inti=0;i<17;i++){ for(intj=0;j<17;j++){ if(qipan[i+1][j+1]==0){//说明此处没有棋子 qixingPC[i][j]=heiheng(i,j,2)+heishu(i,j,2)+heizuoxie(i,j,2)+heiyouxie(i,j,2); qixingPlayer[i][j]=heiheng(i,j,1)+heishu(i,j,1)+heizuoxie(i,j,1)+heiyouxie(i,j,1); }else{ qixingPC[i][j]=0; qixingPlayer[i][j]=0; } } } } //算出黑子横方向的棋型数值 publicintheiheng(inthang,intlie,intnum){ intk=0;//记录空白处的个数 intcount=1;//记录可以形成几连 intn=hang+1;//对应棋盘的行 intm=lie+1;//对应棋盘的列 booleanleft=false;//判断左边是否有黑子 booleanliveLeft=false;//判断左边是活还是死 booleanliveRight=false;//判断右边是活还是死 while((qipan[n][m-1]!=-1)&&(qipan[n][m-1]==num||qipan[n][m-1]==0)){ if(qipan[n][m-1]==0&&k<1){//第一个空白 if(qipan[n][m-2]!=num){ liveLeft=true; break; } k++; m--; }elseif(qipan[n][m-1]==num){//黑子 left=true; m--; }else{//第二个空白 liveLeft=true; break; } } if(!left){ k=0; m=lie+1; } while((qipan[n][m+1]!=-1)&&(qipan[n][m+1]==num||qipan[n][m+1]==0)){ intt=qipan[n][m+1]; if(m==lie){ count++; m++; continue; } if(t==0&&k<1){//第一个空白 if(qipan[n][m+2]!=num){ liveRight=true; break; } k++; m++; }elseif(t==0&&k>0){//第二个空白 liveRight=true; break; }else{//黑子 m++; count++; } } returnjieguo(liveLeft,liveRight,count,k,num); } // 算出黑子竖方向的棋型数值 publicintheishu(inthang,intlie,intnum){ intk=0;//记录空白处的个数 intcount=1;//记录可以形成几连 intn=hang+1;//对应棋盘的行 intm=lie+1;//对应棋盘的列 booleantop=false;//判断上边是否有黑子 booleanliveLeft=false; booleanliveRight=false; while((qipan[n-1][m]!=-1)&&(qipan[n-1][m]==num||qipan[n-1][m]==0)){ if(qipan[n-1][m]==0&&k<1){//第一个空白 if(qipan[n-2][m]!=num){ liveLeft=true; break; } k++; n--; }elseif(qipan[n-1][m]==num){//黑子 top=true; n--; }else{//第二个空白 liveLeft=true; break; } } if(!top){ k=0; n=hang+1; } while((qipan[n+1][m]!=-1)&&(qipan[n+1][m]==num||qipan[n+1][m]==0)){ intt=qipan[n+1][m]; if(n==hang){ count++; n++; continue; } if(t==0&&k<1){//第一个空白 if(qipan[n+2][m]!=num){ liveRight=true; break; } k++; n++; }elseif(t==0&&k>0){//第二个空白 liveRight=true; break; }else{//黑子 n++; count++; } } //returnjieguo(k==0,count); returnjieguo(liveLeft,liveRight,count,k,num); } // 算出黑子左斜方向的棋型数值 publicintheizuoxie(inthang,intlie,intnum){ intk=0;//记录空白处的个数 intcount=1;//记录可以形成几连 intn=hang+1;//对应棋盘的行 intm=lie+1;//对应棋盘的列 booleantop=false;//判断上边是否有黑子 booleanliveLeft=false; booleanliveRight=false; while((qipan[n+1][m-1]!=-1)&&(qipan[n+1][m-1]==num||qipan[n+1][m-1]==0)){ if(qipan[n+1][m-1]==0&&k<1){//第一个空白 if(qipan[n+2][m-2]!=num){ liveLeft=true; break; } k++; n++; m--; }elseif(qipan[n+1][m-1]==num){//黑子 top=true; n++; m--; }else{//第二个空白 liveLeft=true; break; } } if(!top){ k=0; n=hang+1; m=lie+1; } while((qipan[n-1][m+1]!=-1)&&(qipan[n-1][m+1]==num||qipan[n-1][m+1]==0)){ intt=qipan[n-1][m+1]; if(n==(hang+2)&&m==lie){ count++; n--; m++; continue; } if(t==0&&k<1){//第一个空白 if(qipan[n-2][m+2]!=num){ liveRight=true; break; } k++; n--; m++; }elseif(t==0&&k>0){//第二个空白 liveRight=true; break; }else{//黑子 n--; m++; count++; } } returnjieguo(liveLeft,liveRight,count,k,num); } // 算出黑子右斜方向的棋型数值 publicintheiyouxie(inthang,intlie,intnum){ intk=0;//记录空白处的个数 intcount=1;//记录可以形成几连 intn=hang+1;//对应棋盘的行 intm=lie+1;//对应棋盘的列 booleantop=false;//判断上边是否有黑子 booleanliveLeft=false; booleanliveRight=false; while((qipan[n-1][m-1]!=-1)&&(qipan[n-1][m-1]==num||qipan[n-1][m-1]==0)){ if(qipan[n-1][m-1]==0&&k<1){//第一个空白 if(qipan[n-2][m-2]!=num){ liveLeft=true; break; } k++; n--; m--; }elseif(qipan[n-1][m-1]==num){//黑子 top=true; n--; m--; }else{//第二个空白 liveLeft=true; break; } } if(!top){ k=0; n=hang+1; m=lie+1; } while((qipan[n+1][m+1]!=-1)&&(qipan[n+1][m+1]==num||qipan[n+1][m+1]==0)){ intt=qipan[n+1][m+1]; if(n==hang&&m==lie){ count++; n++; m++; continue; } if(t==0&&k<1){//第一个空白 if(qipan[n+2][m+2]!=num){ liveRight=true; break; } k++; n++; m++; }elseif(t==0&&k>0){//第二个空白 liveRight=true; break; }else{//黑子 n++; m++; count++; } } returnjieguo(liveLeft,liveRight,count,k,num); } publicintjieguo(booleanleft,booleanright,intcount,intk,intnum){ if(count==1){ return0; }elseif(count==2){ if(left&&right){ if(k==0){ if(num==2){ return60; }else{ return50; } }else{ if(num==2){ return40; }else{ return35; } } }elseif(!left&&!right){ return0; }else{ return10; } }elseif(count==3){ if(left&&right){ if(k==0){ if(num==2){ return950; }else{ return700; } }else{ if(num==2){ return900; }else{ return650; } } }elseif(!left&&!right){ return0; }else{ return100; } }elseif(count==4){ if(left&&right){ if(k==0){ if(num==2){ return6000; }else{ return3500; } }else{ if(num==2){ return5000; }else{ return3000; } } }elseif(!left&&!right){ return0; }else{ if(k==0){ if(num==2){ return4000; }else{ return800; } }else{ if(num==2){ return3600; }else{ return750; } } } }else{ if(k==0){ if(num==2){ return20000; }else{ return15000; } }else{ if(num==2){ return10000; }else{ return3300; } } } } publicvoidshowMe(){ frame.setSize(530,600); Toolkitkit=Toolkit.getDefaultToolkit(); DimensionscreenSize=kit.getScreenSize(); intwidth=screenSize.width; intheight=screenSize.height; intx=(int)(width-600)/2; inty=(int)(height-530)/2-50; frame.setLocation(x,y); frame.setVisible(true); frame.setResizable(false); frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); } publicstaticvoidmain(String[]args){ newPlayerVsPC().showMe(); } publicbooleanpanduan(intn,intm){ if(heng(n,m)||shu(n,m)||zuoxie(n,m)||youxie(n,m)){ returntrue; } returnfalse; } publicbooleanheng(intn,intm){ inti=n+1,j=m+1; intcount=1; while(qipan[i][j-1]==qipan[n+1][m+1]){ j--; } while(qipan[i][j+1]==qipan[n+1][m+1]){ count++; j++; } if(count>4){ returntrue; } returnfalse; } publicbooleanshu(intn,intm){ inti=n+1,j=m+1; intcount=1; while(qipan[i-1][j]==qipan[n+1][m+1]){ i--; } while(qipan[i+1][j]==qipan[n+1][m+1]){ count++; i++; } if(count>4){ returntrue; } returnfalse; } publicbooleanyouxie(intn,intm){ inti=n+1,j=m+1; intcount=1; while(qipan[i-1][j-1]==qipan[n+1][m+1]){ i--; j--; } while(qipan[i+1][j+1]==qipan[n+1][m+1]){ count++; i++; j++; } if(count>4){ returntrue; } returnfalse; } publicbooleanzuoxie(intn,intm){ inti=n+1,j=m+1; intcount=1; while(qipan[i+1][j-1]==qipan[n+1][m+1]){ i++; j--; } while(qipan[i-1][j+1]==qipan[n+1][m+1]){ count++; i--; j++; } if(count>4){ returntrue; } returnfalse; } }基于单片机和DSP的卷绕控制器数据采集和通讯设计基于MSP430单片机的柴油发电机监控器的设计基于CPLD/FPGA和单片机的爆速仪设计基于单片机控制的晶闸管中频感应电源的研制基于十六位单片机的电力设备故障在线监测装置的设计与算法研究基于SPCE061A单片机的语音识别系统的研究基于PIC单片机的生物机能实验装置的研究基于MotorolaMC68HC08系列单片机演示系统的设计与实现基于TCP/IP协议的单片机与INTERNET互连的设计与实现基于嵌入式实时操作系统和TCP/IP协议的单片机测控系统AVR8位嵌入式单片机在车载全球定位系统显示终端中的应用HYPER
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- tea'stone茶饮品牌手册
- 高一体育 背越式跳高教案
- 2024六年级英语上册 Module 6 Unit 2 I've got a stamp from China第4课时教案 外研版(三起)
- 2024-2025学年高中生物 第6章 第1节 杂交育种与诱变育种教案 新人教版必修2
- 2023四年级数学上册 八 垂线与平行线《直线、射线和角》说课稿 苏教版
- 2024-2025版新教材高中语文 第四单元 第一节 记录家乡的人和物教案 新人教版必修上册
- 房地产金融与投资概论教学课件第十二章房地产投资风险
- 防水工程抵房合同(2篇)
- 人教版灯光课件
- 介绍袁隆平课件
- 蓝色商务极简科技风创新发布会ppt模板
- 2022-2033年度秋学期四年级语文上册教学进度表
- 管理学原理第5章案例:沙漠求生游戏课件
- 法国近代教育史课件
- 船舶管理教案
- TCL液晶电视各机芯进工厂模式方法汇总
- 《中国古代文学史——李白》优秀PPT课件
- 危险化学品普查登记表(11张表)
- ISO13485-2016培训教材PPT课件
- 南方CASS9.0教程(手册)
- 焊盘设计标准
评论
0/150
提交评论