利用matlab的GUI功能编写五子棋的玩法规则游戏

学习 嵌入式&软件
十四步实现拥有强大AI的五子棋游戏
又是本人一份人工智能作业……首先道歉,从Word贴到Livewrter,好多格式没了,也没做代码高亮……大家凑活着看……想做个好的人机对弈的五子棋,可以说需要考虑的问题还是很多的,我们将制作拥有强大AI五子棋的过程分为十四步,让我来步步介绍。
第一步,了解禁手规则
做一个五子棋的程序,自然对五子棋需要有足够的了解,现在默认大家现在和我研究五子棋之前了解是一样多的。以这个为基础,介绍多数人不大熟悉的方面。五子棋的规则实际上有两种:有禁手和无禁手。由于无禁手的规则比较简单,因此被更多人所接受。其实,对于专业下五子棋的人来说,有禁手才是规则。所以,这里先对“有禁手”进行一下简单介绍:
五子棋中“先手必胜”已经得到了论证,类似“花月定式”和“浦月定式”,很多先手必胜下法虽然需要大量的记忆,但高手确能做到必胜。所以五子棋的规则进行了优化,得到了 “有禁手”五子棋。五子棋中,黑棋必然先行。因此“有禁手”五子棋竞技中对黑棋有以下“禁手”限制:“三三禁”:黑棋下子位置同时形成两个以上的三;“四四禁”:黑棋下子位置同时形成两个以上的四;“长连禁”:六子以上的黑棋连成一线。黑棋如下出“禁手“则马上输掉棋局。不过如果“连五”与“禁手”同时出现这时“禁手”是无效的。所以对于黑棋只有冲四活三(后面会有解释)是无解局面。反观白棋则多了一种获胜方式,那就是逼迫黑棋必定要下在禁点。
为了迎合所有玩家,五子棋自然需要做出两个版本,或者是可以进行禁手上的控制。
第二步,实现游戏界面
这里,我制作了一个简单的界面,但是,对于人机对弈来说,绝对够用。和很多网上的精美界面相比,我的界面也许略显粗糙,但,开发速度较高,仅用了不到半天时间。下面我们简单看下界面的做法。
界面我采用了WPF,表现层和逻辑层完全分开,前台基本可以通过拖拽完成布局,这里就不做过多介绍。根据界面截图简单介绍
1处实际上市两个渐变Label的拼接,2、3是两个label,4、5实际上是两个Button,但是没有做事件响应。通过按钮6、7、8、9 的控制,修改label和Button的Content属性。也许有人会奇怪,为什么Button会丝毫看出不出有Button的影子,这里战友whrxiao写过一个Style如下
&Style x:Key="ButtonStyle1" TargetType="{x:Type Button}"&
&Setter Property="Template"&
&Setter.Value&
&ControlTemplate TargetType="{x:Type Button}"&
&ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True"/&
&/ControlTemplate&
&/Setter.Value&
这里我们把这个Style称为Style1。界面逻辑上,将是否开始、是否禁手和是否电脑先行作为两个全局变量的布尔型值,通过设置和判断bool型值进行逻辑上的控制。中间的棋盘是个canvas,一个15*15的Grid放满Button并将每个Button应用Style1开始时候透明度设为0,也就是根本看不到,在下棋的时候改变Button的背景和透明度,实现落子的效果,因为Grid的位置关系,所以可看起来好像是下在横竖的交线处。
第三步,进行输赢判断:
因为规则不同,“无禁手”和“有禁手”的输赢判断自然不同。先看无禁手:这个比较简单,遍历每个位置,然后从这个位置开始,分别判断它的四个方向:即横、竖、左上到右下、左下到右上。每个方向从中间点开始,往两边数连子数,然后将两个方向的连字数加和再加一(中间的棋子)。如果得到大于等于5,那么就说明下子方赢棋。
对于有禁手的五子棋,输赢判断还需要判断禁手,禁手的判定较为复杂。将待判断点放入黑棋子。然后搜索待判断点周边棋盘;还原棋盘;利用搜索结果依次对各方向进行分析,判断黑棋放入后所产生的棋型是否形成长连或形成某种四连或三连的的棋型。若形成长连,判定为禁手,返回长连禁手标识。若形成某种四连或三连的棋型,该棋型统计数加1,再对下一个方向进行判断,直到各个方向分析结束。若四连棋型或三连棋型的统计数大于1,则返回为禁手。其余情况返回非禁手。
第四步:构造棋型估分
“有禁手”规则比较复杂,涉及到比较多下棋方面的技巧,而且对算法的思路没有丝毫影响,所以下面我们主要考虑无禁手规则下的AI设计。若设计好无禁手AI,只需要让AI执黑时坚决不下到禁手点,就可以很快构造有禁手的AI。虽然这种方式没有利用有禁手规则下的技巧,但这些技巧只需要修改下面所讲到的估分函数即可。
我们可以将五子棋的连珠可以分为以下几种:
成5:即构成五子连珠
活4:即构成两边均不被拦截的四子连珠。
死4:一边被拦截的四子连珠
活3:两边均不被拦截的三字连珠
死3:一边被拦截的三字连珠
活2:两边均不被拦截的二子连珠
死2:一边被拦截的二子连珠
单子:四周无相连棋子
根据五子棋的技巧,可以将五子棋的棋型用连珠进行分类,分类过后我们按照威力给每种棋型打分。因为五子棋一次只落一子,因此很容易理解,双活三和三活三的威力是一样的,类似情况不多做解释。程序中,我以100分为满分,对棋型进行了以下打分:
成5, 100分
活4、双死4、死4活3, 90分
双活3, 80分
死3活3, 70分
死4, 60分
活3, 50分
双活2, 40分
死3, 30分
活2, 20分
死2, 10分
有了估分方法,就有了五子棋AI的基础,接下来就是一些博弈的方法了。
第五步:得到位置估分AI
单纯应用棋谱以及对五子棋当前局势的分析,对每步进行估分,程序中做如下工作:将每个位置进行分析,假设AI落子在该位置,用以上打分规则为AI打分,并将得到的分数加一。然后,假设玩家落子在该点,为玩家打分,然后将所有的分值汇总。取最高分作为这个位置的估分,接下来就是取分数最高的位置下棋了。“位置估分”,下棋的时候,既可以考虑到自己攻击对手,又能考虑到对对手的防御,可以说,很多时候可以顶上考虑两步的AI。作实验,从网上下载了一个用博弈做的AI,和“位置估分”对下,结果是一胜一负。谁先子,谁赢得胜利。而且一步估分毫无疑问是最快的,即使遍历所有位置,也能很快的做出决策。
第六步:应用博弈树,提高AI智能
做五子棋的博弈,自然会用到博弈树,这里我说下自己的思路。在对弈中,根据下一步由谁来走,AI对任何一个局面根据前面估分方法给出一个分数,我们把这个估分方法汇总成一个评估函数,并返回分值。据此来选择下一步的走法。由于人和AI是轮流落子,可以将人的估分也算入,并将前面加负号。那么,估值越大表明对AI越有利,估分越小则表明对AI越不利。那么每次AI选择都是从它可能的走法树的某层节点,返回评估值中最大点。而用户总是从走法树的某层节点中选择最小点,从而形成一棵极大极小搜索树,然后根据深度优先搜索,可以最后得到固定搜索深度下的一个最好的走法。我做了下试验,单纯应用博弈树,可以在100ms之内让AI考虑完整的两步,由于组合爆炸,当需要考虑三步的时候,就需要6s左右,4步就需要1分钟。拿两步来和一步估分作比较,虽然比较慢,但是确实有了一定智能。
第七步:考虑层数,提高AI智能
上面的设计对于返回值是统一处理的,但是,层数是个很重要的信息.因为下棋时如果能2步获胜,不应选择4步获胜。对于输的棋型层数就更重要,AI必须尽可能拖延输的时间,就有更大的可能让AI化险为夷。这样,可以通过设置一个dep值。深度约浅,dep越大,用dep和得到的得分相乘,得到搜索节点的得分,再进行以上算法,进一步提高AI的智能。
第八步:应用α-β剪枝,提高AI速度
在搜索博弈树的过程中,实际上搜索有很多点是多余的,例如下图
图中,方形框节点是该AI走,圆形框节点是该人走.比如C节点,它需要从E和F当中选取最大的值。目前已经得出E为2,当搜索F节点时,因为F是人走的节点,那么F需要从K L M中选取最小的,因为K已经是1,也就是说F&=1,那么L,M就不需要搜索,因此就发生了α剪枝。然后看A节点,该人走了,需要从C和D中选取最小值,因为C节点是2,而G是7,那么D至少是7。因此,D的其他节点不必再考虑,就发生如上图所示的β剪枝。总结上面规律,我们可以得到剪枝方法如下:
当前为AI下棋节点:
α剪枝:如果当前节点的值不比父节点的前兄弟节点的大值大,则舍弃此节点。
β剪枝:如果当前节点子节点的值不比当前节点的前兄弟节点中的最小值小,则舍弃该子节点和该子节点的所有后兄弟节点。
当前为用户下棋节点:
α剪枝:如果当前节点的某子节点的值不比当前节点的前兄弟节点中的最大值大,则舍弃该子节点和该子节点的所有后兄弟节点。
β剪枝:如果当前节点的子节点的值不比当前的父节点的前兄弟节点中的最小值小则舍弃此节点。
经过α-β剪枝,可以极大的减少搜索的数量,很多时候,能把几十亿的搜索数量,缩小到几亿,那么,就可以把搜索深度增1。
第九步:应用下棋范围,提高AI速度
当前节点的子节点的数量和排列顺序对于搜索的速度起着至关重要的影响。根据五子棋的特点,可以产生一个棋面搜索范围。记录当前棋面所有棋子的最左最右最上最下点构成的矩形,我们认为下一步棋的位置不会脱离这个框3步以上。这样在棋子较少的时候,搜索节点的数量大大减少。可以将AI的速度提高一倍左右。
第十步:利用棋型得分,提高AI速度
因为每种下法都对应一种得分,所以,可以每次只考虑当前得分前十的节点进行下一步搜索,大大减少了搜索范围,可以进一步增加搜索的深度。
第十一步:利用置换表,提高AI速度
我们一般用递归的方法实现博弈树,但是,递归的效率是低的,而且很明显,有很多重复搜索的节点,所以,我们可以用一个表,记录下所有搜索过节点的情况,然后只要遇到搜索到的节点,就可以直接得到结果。置于这个“表”是什么,就是一个置换表,利用Zobrist算法,进行Hash处理,使在表中查找的时间大大缩短,这样AI的速度又能提高一个数量级。
第十二步:利用多线程,提高AI速度
我们其实可以利用多核技术,利用多个线程,让算法实现并行计算,提高AI的速度。我们在第一层用一个线程分配器把第二层的候选节点分配给多个线程,每个线程包含着从第二层一个候选节点开始的搜索,然后等所有线程结束后,将所有线程的结果进行汇总,选出最大值。并行的程序,可以将速度提高一倍左右。
第十三步:利用随机化算法,让确定方法不能必胜
由于AI算法的固定性,所以一担玩家一次获胜,按照相同的走法,必然会再次获胜。但除了必杀招或者必防招,一个局面很多时候没有绝对最好的走法。而是有一些都不错的走法,那么可以把这些评分差不多走法汇集起来,然后随机选择它们中的一种走法,避免AI的走法的固定.这样最简单的方法避免固定方法AI必输。
第十四步:让AI自学习,不再同一个地方犯错
上面的算法还没有自学习的能力,这样AI在下棋时还可能会重蹈覆辙。因此在每盘棋结束时,如果AI输,则进行大于搜索深度的步数回退。可以把倒数为搜索深度数目的局面定为目标局面,从倒数深度加一步局面进行预测,找到不会导出必败目标局面的局面。然后记录下这个局面和前面的局面,并据此修改评分函数。这样AI就不会犯曾经犯过的错误,达到自学习的效果。
做到以上十四步,一个拥有强大AI的五子棋游戏即可诞生!
转自:http://www.cnblogs.com/goodness/archive//1745756.html
没有更多推荐了,五子棋游戏的设计与实现毕业论文_百度文库
您的浏览器Javascript被禁用,需开启后体验完整功能,
享专业文档下载特权
&赠共享文档下载特权
&10W篇文档免费专享
&每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
五子棋游戏的设计与实现毕业论文
总评分4.0|
用知识赚钱
试读已结束,如果需要继续阅读或下载,敬请购买
定制HR最喜欢的简历
你可能喜欢您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
毕业论文-JavaGUI实现五子棋游戏-后台设计子系统.doc 36页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
你可能关注的文档:
··········
··········
JavaGUI实现五子棋游戏
博弈论是二人在平等的对局中各自利用对方的策略变换自己的对抗策略,达到取胜的目的。博弈论最初主要研究象棋、桥牌、赌博中的胜负问题,人们对博弈局势的把握只停留在经验上,没有向理论化发展博弈论考虑游戏中的个体的预测行为和实际行为,并研究它们的优化策略。五子棋是一种两人对弈的纯策略型棋类游戏,棋具与围棋通用,是起源于中国古代的传统黑白棋种之一。棋子分为黑白两色,棋盘为15×15,棋子放置于棋盘线交叉点上Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言,图形用户界面(G)是指采用图形方式显示的计算机操作用户界面。与早期计算机使用的命令行界面相比,图形界面对于用户来说在视觉上更易于接受。人工智能AI是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。极大极小博弈树阿尔法 贝塔剪枝算法Negascout搜索算法二十世纪七十年代以来人工智能被称为世界三大尖端技术之一 JavaGUI Realized Gobang Game
Game theory is the two on an equal game in their use of each other's strategy to transform himself confrontation strategy to achieve victory purposes. Game theory first major study chess, bridge, gambling in the outcome of the problem, people of game situation grasp only stay in terms of experience, failed to theory development. Game theory considering the game's individual forecast behavior and actual behavior, and to study their optimization strategies. Backgammon is a two games of pure strategy based board games, chess and Go GM, is originated in ancient China's traditional Othello one species. Pieces into black and white, the board of 15 × 15, pieces placed on the board line intersection. Java is a way to write cross-platform applications, object-oriented programming language, graphical user interface (GUI) is a graphical display of the computer operating the user interface. With early computers using the command line interface as compared to the graphical interface for the user to visually easier to accept. With the development of the Internet, online PK has been generally, players can without geographical restrictions, freedom of choice opponents, through the socket to achieve client and server connections and communications. Artificial Intelligence AI is the research, development for simulation, extension and expansion of human intelligence theories, methods, techniques and applications of a new technical sciences. Players can and computers showdown. Computer can analyze chessboard situation, give
正在加载中,请稍后...求MATLAB编的五子棋游戏!!_百度知道
求MATLAB编的五子棋游戏!!
我有更好的答案
直接上程序吧://wuziqi.java import java.applet.Aimport java.awt.Bimport java.awt.Cimport java.awt.CheckboxGimport java.awt.Cimport java.awt.Gimport java.awt.Limport java.awt.event.ActionEimport java.awt.event.ActionLimport java.awt.event.ItemEimport java.awt.event.ItemLimport java.awt.event.MouseEimport java.awt.event.MouseLimport java.awt.event.MouseMotionL
@SuppressWarnings(&serial&)public class wuziqi extends Applet implements ActionListener,MouseListener,MouseMotionListener,ItemListener { int color_Qizi=0;//旗子的颜色标识 0:白子 1:黑子 int intGame_Start=0;//游戏开始标志 0未开始 1游戏中 int intGame_Body[][]=new int[16][16]; //设置棋盘棋子状态 0 无子 1 白子 2 黑子 Button b1=new Button(&游戏开始&); Button b2=new Button(&重置游戏&); Label lblWin=new Label(& &); Checkbox ckbHB[]=new Checkbox[2]; CheckboxGroup ckgHB=new CheckboxGroup(); public void init() { setLayout(null); addMouseListener(this); add(b1); b1.setBounds(330,50,80,30); b1.addActionListener(this); add(b2); b2.setBounds(330,90,80,30); b2.addActionListener(this); ckbHB[0]=new Checkbox(&白子先&,ckgHB,false); ckbHB[0].setBounds(320,20,60,30); ckbHB[1]=new Checkbox(&黑子先&,ckgHB,false); ckbHB[1].setBounds(380,20,60,30); add(ckbHB[0]); add(ckbHB[1]); ckbHB[0].addItemListener(this); ckbHB[1].addItemListener(this); add(lblWin); lblWin.setBounds(330,130,80,30); Game_start_csh(); } public void itemStateChanged(ItemEvent e) { if (ckbHB[0].getState()) //选择黑子先还是白子先 { color_Qizi=0; } else { color_Qizi=1; } } public void actionPerformed(ActionEvent e) { @SuppressWarnings(&unused&)Graphics g=getGraphics(); if (e.getSource()==b1) { Game_start(); } else { Game_re(); } } public void mousePressed(MouseEvent e){} @SuppressWarnings(&unused&)public void mouseClicked(MouseEvent e) { Graphics g=getGraphics(); int x1,y1; x1=e.getX(); y1=e.getY(); if (e.getX()&20 || e.getX()&300 || e.getY()&20 || e.getY()&300) {
} if (x1%20&10) { x1+=20; } if(y1%20&10) { y1+=20; } x1=x1/20*20; y1=y1/20*20; set_Qizi(x1,y1); } public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){} public void mouseReleased(MouseEvent e){} public void mouseDragged(MouseEvent e){} public void mouseMoved(MouseEvent e){} public void paint(Graphics g) { draw_qipan(g); } public void set_Qizi(int x,int y) //落子 { if (intGame_Start==0) //判断游戏未开始 {
} if (intGame_Body[x/20][y/20]!=0) {
} Graphics g=getGraphics(); if (color_Qizi==1)//判断黑子还是白子 { g.setColor(Color.black); color_Qizi=0; } else { g.setColor(Color.white); color_Qizi=1; } g.fillOval(x-10,y-10,20,20); intGame_Body[x/20][y/20]=color_Qizi+1; if (Game_win_1(x/20,y/20)) //判断输赢 { lblWin.setText(Get_qizi_color(color_Qizi)+&赢了!&); intGame_Start=0; } if (Game_win_2(x/20,y/20)) //判断输赢 { lblWin.setText(Get_qizi_color(color_Qizi)+&赢了!&); intGame_Start=0; } if (Game_win_3(x/20,y/20)) //判断输赢 { lblWin.setText(Get_qizi_color(color_Qizi)+&赢了!&); intGame_Start=0; } if (Game_win_4(x/20,y/20)) //判断输赢 { lblWin.setText(Get_qizi_color(color_Qizi)+&赢了!&); intGame_Start=0; } } public String Get_qizi_color(int x) { if (x==0) { return &黑子&; } else { return &白子&; } } public void draw_qipan(Graphics G) //画棋盘 15*15 { G.setColor(Color.lightGray); G.fill3DRect(10,10,300,300,true); G.setColor(Color.black); for(int i=1;i&16;i++) { G.drawLine(20,20*i,300,20*i); G.drawLine(20*i,20,20*i,300); } } public void Game_start() //游戏开始 { intGame_Start=1; Game_btn_enable(false); b2.setEnabled(true); } public void Game_start_csh() //游戏开始初始化 { intGame_Start=0; Game_btn_enable(true); b2.setEnabled(false); ckbHB[0].setState(true); for (int i=0;i&16 ;i++ ) { for (int j=0;j&16 ;j++ ) { intGame_Body[i][j]=0; } } lblWin.setText(&&); } public void Game_re() //游戏重新开始 { repaint(); Game_start_csh(); } public void Game_btn_enable(boolean e) //设置组件状态 { b1.setEnabled(e); b2.setEnabled(e); ckbHB[0].setEnabled(e); ckbHB[1].setEnabled(e); } public boolean Game_win_1(int x,int y) //判断输赢 横 { int x1,y1,t=1; x1=x; y1=y; for (int i=1;i&5 ;i++ ) { if (x1&15) {
} if (intGame_Body[x1+i][y1]==intGame_Body[x][y]) { t+=1; } else {
} } for (int i=1;i&5 ;i++ ) { if (x1&1) {
} if(intGame_Body[x1-i][y1]==intGame_Body[x][y]) { t+=1; } else {
} } if (t&4) {
} } public boolean Game_win_2(int x,int y) //判断输赢 竖 { int x1,y1,t=1; x1=x; y1=y; for (int i=1;i&5 ;i++ ) { if (x1&15) {
} if (intGame_Body[x1][y1+i]==intGame_Body[x][y]) { t+=1; } else {
} } for (int i=1;i&5 ;i++ ) { if (x1&1) {
} if(intGame_Body[x1][y1-i]==intGame_Body[x][y]) { t+=1; } else {
} } if (t&4) {
} } public boolean Game_win_3(int x,int y) //判断输赢 左斜 { int x1,y1,t=1; x1=x; y1=y; for (int i=1;i&5 ;i++ ) { if (x1&15) {
} if (intGame_Body[x1+i][y1-i]==intGame_Body[x][y]) { t+=1; } else {
} } for (int i=1;i&5 ;i++ ) { if (x1&1) {
} if(intGame_Body[x1-i][y1+i]==intGame_Body[x][y]) { t+=1; } else {
} } if (t&4) {
} } public boolean Game_win_4(int x,int y) //判断输赢 左斜 { int x1,y1,t=1; x1=x; y1=y; for (int i=1;i&5 ;i++ ) { if (x1&15) {
} if (intGame_Body[x1+i][y1+i]==intGame_Body[x][y]) { t+=1; } else {
} } for (int i=1;i&5 ;i++ ) { if (x1&1) {
} if(intGame_Body[x1-i][y1-i]==intGame_Body[x][y]) { t+=1; } else {
} } if (t&4) {
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。因为无知,更显谦卑!
javaGUI自制五子棋-实践周大作业
我的项目在eclipse中的目录结构:img中是图片目录lib中是外部导入的关于music的jar包programFile里面关于我的存档操作保存的文件sound中就是用到的音频文件一个开始加载时的splash。运行截图:代码部分:主函数所在类:/*
Copyright (C) 2017 mzy
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.
If not, see &https://www.gnu.org/licenses/&.
package com.
import java.awt.C
* @author mzy
* @version 1.0
import java.awt.C
import java.awt.D
import java.awt.F
import java.awt.event.ActionE
import java.awt.event.ActionL
import java.io.FileInputS
import java.io.FileOutputS
import java.io.IOE
import java.util.LinkedL
import javax.swing.ImageI
import javax.swing.JD
import javax.swing.JF
import javax.swing.JL
import javax.swing.JM
import javax.swing.JMenuB
import javax.swing.JMenuI
import javax.swing.JOptionP
import javax.swing.JTextA
@SuppressWarnings("serial")
public class FiveChess extends JFrame implements ActionListener{
C // 底层的Frame容器
FiveChessBord chessP // 绘制网格,下棋的期盼
static FiveChess fiveC
private char[] num = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O'};
public FiveChess() {
this.setIconImage(new ImageIcon("img/start.jpg").getImage());
this.setTitle("五子棋");
// 为了让内部的panel接近正方形,Frame的大小要考虑上面的菜单栏20像素
因为加了选项栏,再加20
this.setSize(574, 624);
this.setResizable(false);
this.setLocationRelativeTo(null);
要在棋盘上显示
行号,列号
不能在Panel上直接添加,必须在Frame上做,因为在Panel上的组建过多,会影响,panel上鼠标对下棋位置的监听
也会影响Frame的关闭操作,具体实现,是把panel设置为透明的,只要能显示Frame上的内容就好了
// ----------------------
drawLineNumber();
// ----------------------
cp = this.getContentPane();
chessPanel = new FiveChessBord();
cp.add(chessPanel);
chessPanel.setOpaque(false);
initMyUI();
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
private void initMyUI() {
String[] captions = { "开始(S)", "音效(M)", "难度(D)", "设置(B)", "帮助(H)" };
String[][] titles = { { "重新游戏", "读档",
"存档", "-", "悔棋", "-", "退出" }, { "开启音效", "-", "关闭音效" }, {"简单", "中级", "困难"}, {"切换背景"},
{ "帮助", "-", "关于本游戏" } };
// JMenuBar -&
JMenuBar menuBar = new JMenuBar();
for (int i = 0; i & captions. i++) {
menu = new JMenu(captions[i]);
menu.setFont(new Font("黑体", Font.PLAIN, 15));
menuBar.add(menu);
for (int j = 0; j & titles[i]. j++) {
String caption = titles[i][j];
if ("-".equals(caption)) {
menu.addSeparator(); // 给menuItem加一个分隔符
item = new JMenuItem(titles[i][j]);
item.setPreferredSize(new Dimension(80, 35));
item.setFont(new Font("黑体", Font.PLAIN, 13));
// item.setBorder(BorderFactory.createLineBorder(Color.black,3));
menu.add(item);
item.addActionListener(this);
this.setJMenuBar(menuBar);
public void drawLineNumber() {
int offset = FiveChessBord.getOffset();
int width = FiveChessBord.getGridWidth();
for(int i = 0; i&15;i++){
int x = offset + width*14;
int y = offset + width*i;
int n = 15-i;
JLabel label = new JLabel(String.valueOf(n));
if(8 == n)
label.setForeground(Color.RED);
this.add(label);
* 微调:距离棋盘的距离再增加8个像素
* 为了视觉上看着行号和网格对齐,再减少3个像素
label.setBounds(x+8, y-3, 15, 15);
for(int i = 0; i&15;i++){
int y =offset + width*14;
int x = offset + width*i;
char n = num[i];
JLabel label = new JLabel(String.valueOf(n));
if('H' == n)
label.setForeground(Color.RED);
this.add(label);
* 微调:距离棋盘的距离再增加8个像素
* 为了视觉上看着行号和网格对齐,再减少3个像素
label.setBounds(x-3, y+8, 15, 15);
// 画棋盘上的小圆点
private int count = 0;
* 关于菜单栏的操作
public void actionPerformed(ActionEvent e) {
String s = e.getActionCommand();
if ("重新游戏".equals(s)) {
// System.out.println("");
chessPanel.reset();
if ("读档".equals(s)) {
FileInputStream fis =
fis = new FileInputStream("programFile/data");
int[][] temp = new int[FiveChessBord.getLineCount()][FiveChessBord.getLineCount()];
int len = fis.available();
byte[] data = new byte[len];
fis.read(data);
String string = new String(data);
int num = 0;
for(int i=0; i&FiveChessBord.getLineCount(); i++){
for(int j=0; j&FiveChessBord.getLineCount(); j++){
temp[i][j] = string.charAt(num) - 48;
// 转了之后是
System.out.print(temp[i][j]);
System.out.println();
chessPanel.setChess(temp);
JOptionPane.showMessageDialog(null, "读档成功!");
} catch (IOException e1) {
e1.printStackTrace();
} finally {
if(null != fis) {
fis.close();
} catch (IOException e1) {
e1.printStackTrace();
if ("存档".equals(s)) {
FileOutputStream fos =
fos = new FileOutputStream("programFile/data");
int[][] temp = chessPanel.getChess();
StringBuilder stringBuilder = new StringBuilder();
for(int i=0; i&FiveChessBord.getLineCount(); i++)
for(int j=0; j&FiveChessBord.getLineCount(); j++){
stringBuilder.append(temp[i][j]);
String t = stringBuilder.toString();
byte[] data = t.getBytes();
fos.write(data, 0, data.length);
JOptionPane.showMessageDialog(null, "存档成功!");
} catch (IOException e1) {
e1.printStackTrace();
} finally {
if(null != fos) {
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
if ("退出".equals(s)) {
this.dispose();
if ("简单".equals(s)) {
chessPanel.setLevel(1);
JOptionPane.showMessageDialog(null, "已切换成简单!");
if ("中级".equals(s)) {
chessPanel.setLevel(2);
JOptionPane.showMessageDialog(null, "已切换成中级!");
if ("困难".equals(s)) {
chessPanel.setLevel(3);
JOptionPane.showMessageDialog(null, "已切换成困难!");
if ("开启音效".equals(s)) {
chessPanel.setSoundswitch(true);
JOptionPane.showMessageDialog(null, "音效已开启!");
if ("关闭音效".equals(s)) {
chessPanel.setSoundswitch(false);
JOptionPane.showMessageDialog(null, "音效已关闭!");
if ("切换背景".equals(s)) {
String[] temp = chessPanel.getImgArr();
chessPanel.setImgBack(new ImageIcon(temp[count]).getImage());
if(count == 2)
count = -1;
fiveChess.setVisible(false);
long startTime = System.currentTimeMillis();
long endTime = startTime + 1000;
while(System.currentTimeMillis()&endTime);
fiveChess.setVisible(true);
JOptionPane.showMessageDialog(null, "切换背景成功!");
if ("帮助".equals(s)) {
new AboutHelp();
if ("关于本游戏".equals(s)) {
new AboutAuthor();
if ("悔棋".equals(s)) {
Chess pre =
LinkedList&Chess& stack = chessPanel.getStack();
if(!stack.isEmpty()){
pre = stack.pop();
int[][] chess = chessPanel.getChess();
int trans = FiveChessBord.getTrans();
chess[pre.x1][pre.y1] =
chess[pre.x2][pre.y2] =
chessPanel.setChess(chess);
public static void main(String[] args) {
fiveChess = new FiveChess();
Splash splash = new Splash();
long startTime = System.currentTimeMillis();
long endTime = startTime + 3000;
while(System.currentTimeMillis()&endTime);
splash.dispose();
fiveChess.setVisible(true);
@SuppressWarnings("serial")
class AboutHelp extends JDialog {// 关于窗口
AboutHelp() {
this.setIconImage(new ImageIcon("img/start.jpg").getImage());
this.setTitle("帮助");
JTextArea t = new JTextArea();
t.setFont(new Font("微软雅黑", 1, 16));
String s = "五子连珠:\n操作:只要能够横向,纵向,正45度,负45度连5颗棋子,即为赢";
t.setText(s);
t.setEditable(false);
setSize(480, 100);
setVisible(true);
setLocationRelativeTo(null);
setResizable(false); // 设置为大小不可变的
@SuppressWarnings("serial")
class AboutAuthor extends JDialog {// 关于窗口
AboutAuthor() {
this.setIconImage(new ImageIcon("img/start.jpg").getImage());
this.setTitle("关于五子棋");
JTextArea t = new JTextArea();
t.setFont(new Font("微软雅黑", 1, 16));
String s = "
作者:半步疯子
版本号:version 1.0";
t.setText(s);
t.setEditable(false);
setSize(400, 100);
setVisible(true);
setLocationRelativeTo(null);
setResizable(false); // 设置为大小不可变的
关于开始加载最先出现的splash:package com.
import java.awt.G
import java.awt.image.BufferedI
import java.io.F
import java.io.IOE
import javax.imageio.ImageIO;
import javax.swing.JF
@SuppressWarnings("serial")
public class Splash extends JFrame{
BufferedImage startImg =
public Splash() {
startImg = ImageIO.read(new File("img/start.jpg"));
} catch (IOException e) {
e.printStackTrace();
setUndecorated(true);
setSize(startImg.getWidth(), startImg.getHeight());
setLocationRelativeTo(null);
setVisible(true);
public void paint(Graphics g) {
g.drawImage(startImg, 0, 0, this);
关于音乐加载的music:/*
Copyright (C) 2017 mzy
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.
If not, see &https://www.gnu.org/licenses/&.
package com.
import java.io.F
import java.io.FileInputS
import java.io.InputS
import sun.audio.AudioP
import sun.audio.AudioS
* @author 半步疯子
* @version 1.0
public class Music {
private static String[] choice = { "sound/put.wav", "sound/win.wav", "sound/lost.wav" }; // 声音文件名数组
static File file1;
static File file2;
static File file3;
file1 = new File(choice[0]);
file2 = new File(choice[1]);
file3 = new File(choice[2]);
* 落子声音
public void putVoice() {
InputStream sound = new FileInputStream(file1);
AudioStream as= new AudioStream(sound);
AudioPlayer.player.start(as);
} catch (Exception e) {
e.printStackTrace();
* 获胜声音
public void winVoice() {
InputStream sound = new FileInputStream(file2);
AudioStream as= new AudioStream(sound);
AudioPlayer.player.start(as);
} catch (Exception e) {
e.printStackTrace();
* 失败声音
public void lostVoice() {
InputStream sound = new FileInputStream(file3);
AudioStream as= new AudioStream(sound);
AudioPlayer.player.start(as);
} catch (Exception e) {
e.printStackTrace();
对于棋盘和棋子的绘制的类和协调算法操作和具体功能实现的类:/*
Copyright (C) 2017 mzy
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.
If not, see &https://www.gnu.org/licenses/&.
package com.
* @author 半步疯子
* @version 1.0
import java.awt.G
import java.awt.I
import java.awt.event.MouseA
import java.awt.event.MouseE
import java.util.LinkedL
import javax.swing.ImageI
import javax.swing.JOptionP
import javax.swing.JP
* 错误的想法:
* 需要替换 其中的mouseAdapter为 mouseMotionAdapter
* 因为这样才能更好的解决响应速度的问题
* 正确的原因:
* 是因为在开始FiveChessBord.this.repaint(); 将棋盘全部重绘速度问题
* 解决方法一:
在repaint(new Rectangle(x-36, y-36, 50, 50)); 中全部部分绘制,为什么不行?
将Graphics g设置为全局为什么不行
为什么只能在监听器里面repaint,不能在画完棋子之后进行repaint,drawItem里面
// 504 * 504
再有15条线
考虑10像素
514 + 30 + 30
@SuppressWarnings("serial")
public class FiveChessBord extends JPanel{
private static final int WHITE = 2;
private static final int BLACK = 1;
// /** 透明
private static final int TRANS = 0;
/** 背景图片数组
private String[] imgArr = {"img/background.png", "img/backgroundChess.png", "img/timg.jpg"};
/** 背景图片 */
private Image imgBack = new ImageIcon(imgArr[0]).getImage();
/** 每一个格子的大小为36 */
private static final int GRID_WIDTH = 36;
/** 偏移量为二分之一格子
private static final int OFFSET = 30; // GRID_WIDTH/2;
/** 常量:行数和列数 */
private static final int LINE_COUNT = 15;
/** 棋盘数组 */
private int[][] chess = new int[LINE_COUNT][LINE_COUNT];
// /** 获取当前的 Graphics对象
// private Graphics g = this.getGraphics();
/** 关于音效
Music music = new Music();
关于音效的开关
private boolean soundswitch =
/** 电脑下棋的难度级数 */
private int level = 3;
黑棋的评价指标
private String[] blackKey = { "11111", "011110", "11110", "01111", "01110",
"1110", "0111", "1101", "1011", "0110", "11", "1" };
/** 白棋的评价指标
private String[] whiteKey = { "22222", "022220", "22220", "02222", "02220",
"2220", "0222", "2202", "2022", "0220", "22", "2" };
/** 每个指标的评分
private int[] keyValues = {100, 90, 80, 80, 80, 70, 60, 60, 60, 60, 50, 30, 5};
/** 悔棋栈
private LinkedList&Chess& stack = new LinkedList&&();
public FiveChessBord() {
this.setLayout(null);
new ImageIcon("img/background.png").getImage();
Image img = new ImageIcon("img/backgroundChess.png").getImage();
this.addMouseListener(new ChessListener());
// 对于监听器的选择,此监听器响应过慢
public class ChessListener extends MouseAdapter{
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
// 确定 对应的行
// 这里除下来的结果应该进行一个四舍五入
int rowTemp1 = (y - OFFSET)/36;
int colTemp1 = (x - OFFSET)/36;
int rowTemp2 = (y - OFFSET)%36;
int colTemp2 = (x - OFFSET)%36;
System.out.println("rowTemp2 = "+rowTemp2+"; colTemp2 = "+colTemp2);
if( rowTemp2 - rowTemp1 &= 18 ) {
row = rowTemp1 + 1;
row = rowTemp1;
if( colTemp2 - colTemp1 &= 18 ) {
col = colTemp1 + 1;
col = colTemp1;
System.out.println("row = "+row+"; col = "+col);
测量出 x 和
System.out.println("x = "+x+"; y = "+y);
// 有效落子的位置
if(chess[row][col] == 0) {
Chess pre = new Chess();
chess[row][col] = BLACK;
if(soundswitch){
music.putVoice();
// 整个棋盘重新绘制
// FiveChessBord.this.repaint();
// repaint(new Rectangle(x-36, y-36, 50, 50));
repaint();
// 判断胜负
boolean playerResult = checkWin(chess[row][col], row, col);
if(playerResult) {
JOptionPane.showMessageDialog(null, "you win!");
if(soundswitch){
music.winVoice();
// computerPlayRandom();
// computerPlayByAI();
int[] res = controlComputerPlay(level);
pre.x2 = res[0];
pre.y2 = res[1];
boolean computerResult = checkWin(WHITE, res[0], res[1]);
if(computerResult) {
JOptionPane.showMessageDialog(null, "you lost!");
if(soundswitch){
music.lostVoice();
// repaint();
stack.push(pre);
public int[] controlComputerPlay(int level) {
if(1 == level) {
res = new Calculation01(chess).computerPlay();
} else if(2 == level) {
res = new Calculation02(chess).computerPlay();
res = new Calculation03(chess).computerPlay();
算法未优化
// 检查是否胜利
public boolean checkWin(int color, int row, int col) {
if(checkWinCount(color, row, col, 0, 1)) // 横向
if(checkWinCount(color, row, col, 1, 0)) // 纵向
if(checkWinCount(color, row, col, 1, 1)) // 正斜下
if(checkWinCount(color, row, col, 1, -1)) // 翻斜下
private boolean checkWinCount(int color, int row, int col, int rowInc, int colInc) {
int count = 1;
int r = row + rowI
int c = col + colI
while(r&15 && r&=0 && c&15 && c&=0 && chess[r][c] == color ) {
r = row - rowI
c = col - colI
while(r&15 && r&=0 && c&15 && c&=0 && chess[r][c] == color ) {
if(count &= 5)
* 随机电脑下棋
private void computerPlayRandom() {
Random r = new Random(System.currentTimeMillis());
int row = r.nextInt(15);
int col = r.nextInt(15);
for(int i=0; i&15; i++) {
for(int j=0; j&15; j++) {
if(chess[row][col] == 0) {
chess[row][col] = WHITE;
col = (col + 1) % 15;
row = (row + 1) % 15;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// this.g =
g.drawImage(imgBack, 0, 0, this.getWidth(), this.getHeight(), this); // 绘制背景
for(int i = 0; i&15;i++){
int x1 = OFFSET;
int x2 = OFFSET + GRID_WIDTH*14;
int y = OFFSET + GRID_WIDTH*i;
g.drawLine(x1, y, x2, y);
Color color = g.getColor();
System.out.println(color);
for(int i = 0; i&15;i++){
int y1 = OFFSET;
int y2 =OFFSET + GRID_WIDTH*14;
int x = OFFSET + GRID_WIDTH*i;
g.drawLine(x, y1, x, y2);
/* 因为这个是左上角的坐标,为了对齐还要减去圆的半径
* 画棋盘上的实心小圆
g.fillOval(OFFSET+3*GRID_WIDTH - 6, OFFSET+3*GRID_WIDTH - 6, 12, 12);
g.fillOval(OFFSET+3*GRID_WIDTH - 6, OFFSET+11*GRID_WIDTH - 6, 12, 12); // 左下
g.fillOval(OFFSET+11*GRID_WIDTH - 6, OFFSET+3*GRID_WIDTH - 6, 12, 12);
g.fillOval(OFFSET+11*GRID_WIDTH - 6, OFFSET+11*GRID_WIDTH - 6, 12, 12); // 右下
g.fillOval(OFFSET+7*GRID_WIDTH - 6, OFFSET+7*GRID_WIDTH - 6, 12, 12);
// 绘制棋子
drawChessItem(g);
* 绘制棋子的方法,在paintComponent中重复调用
* 遍历其中的值,根据其中的值,进行棋子的绘制
* @param g
private void drawChessItem(Graphics g) {
for(int row=0; row&chess. row++) {
for(int col=0; col&chess[row]. col++) {
if(chess[row][col] == BLACK) {
// drawItem(row, col, BLACK);
drawItem(row, col, BLACK, g);
} else if(chess[row][col] == WHITE) {
// drawItem(row, col, WHITE);
drawItem(row, col, WHITE, g);
* 在指定位置绘制指定颜色的棋子
* @param row 行,从0开始
* @param col 列,从0开始
* @param color 颜色
* @param g
private void drawItem(int row, int col, int color, Graphics g) {
// private void drawItem(int row, int col, int color) {
int x = col*GRID_WIDTH + OFFSET - GRID_WIDTH/2;
int y = row*GRID_WIDTH + OFFSET - GRID_WIDTH/2;
Image img =
if(color == BLACK){
img = new ImageIcon("img/blackchess.GIF").getImage();
img = new ImageIcon("img/black.png").getImage();
img = new ImageIcon("img/whitechess.GIF").getImage();
img = new ImageIcon("img/white.png").getImage();
g.drawImage(img, x, y, GRID_WIDTH, GRID_WIDTH, this);
// repaint(new Rectangle(x-40, y-40, 50, 50));
repaint();
为什么在这儿repaint没有意义
public void reset() {
// 清空棋子
for(int i=0; i&LINE_COUNT; i++) {
for(int j=0; j&LINE_COUNT; j++) {
chess[i][j] = TRANS;
repaint();
public int[][] getChess() {
public void setChess(int[][] chess) {
this.chess =
repaint();
public String[] getBlackKey() {
return blackK
public void setBlackKey(String[] blackKey) {
this.blackKey = blackK
public String[] getWhiteKey() {
return whiteK
public void setWhiteKey(String[] whiteKey) {
this.whiteKey = whiteK
public int[] getKeyValues() {
return keyV
public void setKeyValues(int[] keyValues) {
this.keyValues = keyV
public static int getWhite() {
return WHITE;
public static int getBlack() {
return BLACK;
public static int getLineCount() {
return LINE_COUNT;
public Image getImgBack() {
return imgB
public void setImgBack(Image imgBack) {
this.imgBack = imgB
public Music getMusic() {
public void setMusic(Music music) {
this.music =
public boolean isSoundswitch() {
public void setSoundswitch(boolean soundswitch) {
this.soundswitch =
public static int getTrans() {
return TRANS;
public String[] getImgArr() {
return imgA
public void setImgArr(String[] imgArr) {
this.imgArr = imgA
public int getLevel() {
public void setLevel(int level) {
this.level =
public static int getGridWidth() {
return GRID_WIDTH;
public static int getOffset() {
return OFFSET;
public LinkedList&Chess& getStack() {
public void setStack(LinkedList&Chess& stack) {
this.stack =
class Chess {
}算法部分:简单的算法(偏向于防守):package com.
* 防御优先
* @author mzy
public class Calculation01 {
FiveChessBord f = new FiveChessBord();
private static final int LINE_COUNT = FiveChessBord.getLineCount();
private static final int WHITE = FiveChessBord.getWhite();
private int[][] // = f.getChess(); // 为什么直接使用get不行
private int[] gkey = f.getKeyValues();
private String[] bkey = f.getBlackKey();
private String[] wkey = f.getWhiteKey();
int[] res = new int[2];
public Calculation01(int[][] items) {
this.chesses =
public int[] computerPlay() {
int tmax = 0, wmax = 0;
int r = 0, c = 0;
for (int i = 0; i & LINE_COUNT; i++) {
for (int j = 0; j & LINE_COUNT; j++) {
if (chesses[i][j] != 0) {
tmax = getValue(0, i, j);
if (tmax & wmax) {
chesses[r][c] = WHITE;
public String chessString(int chessColor, int row, int col, int rowInc, int colInc) {
StringBuilder strB = new StringBuilder("A");
int i = 0;
while (i & 4) {
r = r + rowI
c = c + colI
if (r & LINE_COUNT && r &= 0 && c & LINE_COUNT && c &= 0) {
strB.append(chesses[r][c]);
while (i & 4) {
r = r - rowI
c = c - colI
if (r & LINE_COUNT && r &= 0 && c & LINE_COUNT && c &= 0)
strB.insert(0, chesses[r][c]);
return strB.toString();
public int getValue(int chessColor, int row, int col) {//// 获取周围空处的值,取价值最大的点
int bmax = 0, wmax = 0;
String[] t = new String[4];
t[0] = chessString(chessColor, row, col, 0, 1);
t[1] = chessString(chessColor, row, col, 1, 0);
t[2] = chessString(chessColor, row, col, 1, 1);
t[3] = chessString(chessColor, row, col, 1, -1);
for (int i = 0; i & 4; i++) {
String b = t[i].replaceAll("A", String.valueOf(1));
String w = t[i].replaceAll("A", String.valueOf(2));
for (int j = 0; j & bkey. j++) {
if (b.indexOf(bkey[j]) &= 0) {
if (gkey[j] & bmax) {
bmax = gkey[j];
for (int j = 0; j & wkey. j++) {
if (w.indexOf(bkey[j]) &= 0) {
if (gkey[j] & wmax)
wmax = gkey[j];
return bmax & wmax ? bmax :
中级的算法(偏向于进攻):package com.
* 攻击优先
public class Calculation02 {
FiveChessBord f = new FiveChessBord();
private static final int LINE_COUNT = FiveChessBord.getLineCount();
private static final int WHITE = FiveChessBord.getWhite();
private int[][] // = f.getChess(); // 为什么直接使用get不行
private int[] keyValues = f.getKeyValues();
private String[] blackKey = f.getBlackKey();
private String[] whiteKey = f.getWhiteKey();
int[] res = new int[2];
public Calculation02(int[][] chess) {
this.chess =
* 电脑下棋+算法
public int[] computerPlay() {
int max = 0;
int row = 0;
int col = 0;
int temp = 0;
for (int i = 0; i & LINE_COUNT; i++)
for (int j = 0; j & LINE_COUNT; j++) {
if (chess[i][j] != 0)
temp = getMaxValue(i, j);
if (temp & max) {
// System.out.println(max);
chess[row][col] = WHITE;
// repaint();
private int getMaxValue(int row, int col) {
int AttackMax = 0;
int DefendMax = 0;
String[] tempStr = new String[4];
System.out.print("横向:");
tempStr[0] = chessString(row, col, 0, 1); // 横向
System.out.print("纵向:");
tempStr[1] = chessString(row, col, 1, 0); // 纵向
System.out.print("正45:");
tempStr[2] = chessString(row, col, 1, 1); // 左下
tempStr[3] = chessString(row, col, 1, -1); // 左上
for (int i = 0; i & 4; i++) {
// 237 - 250 注意
String attack = tempStr[i].replace("T", String.valueOf(1));
String defend = tempStr[i].replace("T", String.valueOf(2));
System.out.println(attack);
System.out.println(defend);
for (int j = 0; j & blackKey. j++) {
if (attack.indexOf(blackKey[j]) &= 0) {
if (keyValues[j] & AttackMax)
AttackMax = keyValues[j];
if (AttackMax == 100)
for (int j = 0; j & whiteKey. j++) {
if (defend.indexOf(whiteKey[j]) &= 0) {
if (keyValues[j] & DefendMax)
DefendMax = keyValues[j];
if (DefendMax == 100)
return Math.max(AttackMax + 5, DefendMax);
// 攻击优先
private String chessString(int row, int col, int rowInc, int colInc) {
StringBuilder temp = new StringBuilder();
int count = 0;
while (r & LINE_COUNT && r &= 0 && c & LINE_COUNT && c &= 0) {
if (0 & r || 0 & c || 14 & r || 14 & c)
if(count &= 4)
temp.append(chess[r][c]);
temp = temp.reverse();
temp.append("A");
count = 0;
while (r & LINE_COUNT && r &= 0 && c & LINE_COUNT && c &= 0) {
if (0 & r || 0 & c || 14 & r || 14 & c)
if(count &= 4)
temp.append(chess[r][c]);
System.out.println(temp);
return temp.toString();
困难的算法(攻防兼备):package com.
* 攻防兼备
* @author mzy
public class Calculation03 {
FiveChessBord f = new FiveChessBord();
private static final int LINE_COUNT = FiveChessBord.getLineCount();
private static final int PLAYER_BLACK = FiveChessBord.getBlack();
private static final int PLAYER_WHITE = FiveChessBord.getWhite();
private int[][] //
= f.getChess();
// 为什么直接使用get不行
private int[] scores = f.getKeyValues();
private String[] keyBlack = f.getBlackKey();
private String[] keyWhite = f.getWhiteKey();
int[] res = new int[2];
public Calculation03(int[][] items) {
this.items =
* 电脑下棋
public int[] computerPlay() {
// 遍历棋盘上所有的空位,计算每个位置的进攻指数和防守指数,选择指数最大的位置下棋
int _row = -1, _col = -1;
int maxValue = 0;
for (int i = 0; i & LINE_COUNT; i++) {
for (int j = 0; j & LINE_COUNT; j++) {
if (items[i][j] & 0)
// 非空位,跳过
int maxAttck = checkMax(i, j, PLAYER_BLACK);// 进攻指数
int maxDedend = checkMax(i, j, PLAYER_WHITE);// 防守指数
int maxCurrentPosition = Math.max(maxAttck, maxDedend);
// 如果当前位置的指数大于其他位置的最大指数,则重新设置应该落子的位置和指数
if (maxCurrentPosition & maxValue) {
maxValue = maxCurrentP
if (maxValue == 100) {
if (maxValue == 100) {
items[_row][_col] = PLAYER_WHITE;
// repaint();
res[0] = _
res[1] = _
* 计算机指定位置的相关指数
* @param row
* @param col
* @param player
棋子的颜色
private int checkMax(int row, int col, int player) {
String[] keys = (player == PLAYER_BLACK ? keyBlack : keyWhite);
StringBuilder[] builder = new StringBuilder[4];
// 注意:这里创建引用类型变量要再new一次
builder[0] = new StringBuilder();
builder[1] = new StringBuilder();
builder[2] = new StringBuilder();
builder[3] = new StringBuilder();
int maxAll = 0, max = 0;
// 判断-45度方向
for (int i = -4; i &= 4; i++) {
int _row = row +
int _col = col +
if (_row & 0 || _row &= LINE_COUNT) {
if (_col & 0 || _col &= LINE_COUNT) {
builder[0].append(i == 0 ? player : items[_row][_col]);
for (int i = 0; i & keys. i++) {
String key = keys[i];
if (builder[0].indexOf(key) &= 0) {
max = scores[i];
if (max == 100) {
if (max & maxAll) {
// 判断45度方向
for (int i = -4; i &= 4; i++) {
int _row = row -
int _col = col +
if (_row & 0 || _row &= LINE_COUNT) {
if (_col & 0 || _col &= LINE_COUNT) {
builder[1].append(i == 0 ? player : items[_row][_col]);
for (int i = 0; i & keys. i++) {
String key = keys[i];
if (builder[1].indexOf(key) &= 0) {
max = scores[i];
if (max == 100) {
if (max & maxAll) {
// 判断水平方向
for (int i = -4; i &= 4; i++) {
int _row =
int _col = col +
if (_row & 0 || _row &= LINE_COUNT) {
if (_col & 0 || _col &= LINE_COUNT) {
builder[2].append(i == 0 ? player : items[_row][_col]);
for (int i = 0; i & keys. i++) {
String key = keys[i];
if (builder[2].indexOf(key) &= 0) {
max = scores[i];
if (max == 100) {
if (max & maxAll) {
// 判断竖直方向
for (int i = -4; i &= 4; i++) {
int _row = row +
int _col =
if (_row & 0 || _row &= LINE_COUNT) {
if (_col & 0 || _col &= LINE_COUNT) {
builder[3].append(i == 0 ? player : items[_row][_col]);
for (int i = 0; i & keys. i++) {
String key = keys[i];
if (builder[3].indexOf(key) &= 0) {
max = scores[i];
if (max & maxAll) {
return maxA
资源下载地址:http://download.csdn.net/download/qq_83024
没有更多推荐了,}

我要回帖

更多关于 五子棋口诀表 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信