从开始着手做五子棋,到现在已经有一段时间了。这个项目也算告一段落。 从开始做的网络版,再到加入人机元素, 可谓是耗尽精力。 人机水平达到了比较牛逼的程度,可以战胜大多数人(略显夸张。。) 大言不惭的说最好,也是不符合程序猿严谨的风格,在新手中看来这个程序应该是写的可以了。但大牛看来就是乱七八糟(被大牛吐槽过)。。人机写到这个程度感觉再要进一步很难了。所以就先把这个版本发出来。
先看下效果图吧。 还是很漂亮的吧。这个界面也花了我很久的时间。
登陆界面
人机界面
可以更换背景
网络人人版
可下棋聊天
然后说下 一些做的不好的地方吧
1.我做了两个版本 一个是客户端一个是服务端, 必须先启动服务端 然后用客户端去连接客户端。(我想做成就一个版本, 任意打开的两个可以互联,但是一直没成功,求大神指导思路)。
2.棋子直接用画布画的圆圈没有用图片,不太好看。
3.最新下的棋子没有加入闪烁效果,棋子多了 可能分不清对方是在哪里下子
总代码太长了 ,我就发下人机代码了 ,这是核心
电脑下棋思路: 15*15的五子棋盘一共有572种 成“5”组合。我们称这种组合为获胜组合。而保存这572种组合的表称为获胜表。每次下棋后,都要更新所以获胜组合情况(“5”中的棋子个数更改)。而电脑下棋前 扫描每个位置,看包含这个位置的所有组合,根据评估函数打分。分数有两个,一个是这个位置对电脑的得分,一个是对玩家的得分。。 电脑每次选取分数最高的地方下子。 五子棋人机思路及具体做法我做了个PPT ,大家可以下载看看,讲的很详细了。有什么不懂的地方欢迎留言。有什么可以改进的地方也欢迎留言指教!
package client; import java.awt.Point; public class ComputerNormal { static Integer[][][] pTable; // 人的获胜表 static Integer[][][] cTable;// 机器的获胜表 //win[0][k]:表示玩家在第k个获胜组合往其方向有win[0][k]个连续的黑棋。 //win[0][k]取值为9则表示第k个获胜组合被封死了,没有成5的可能。 // win[1][k]:表示计算机在第k个获胜组合往其方向有win[1][k]个连续的白棋。 static Integer win[][]; static int row = 15; static int col = 15; public ComputerNormal() { InitBoard(); } public static Point cPutChess(Integer map[][]) { //机器下子 判断机器分 int maxi = 0,maxj = 0; int max=-999999; for(int i=0;i<row;i++) { for(int j=0;j<col;j++) { if(map[i][j]!=0) continue; int t=GiveScore(1, i, j); if(max<t) { max=t; maxi=i; maxj=j; } } } //机器下子 判断ren分 int mini = 0,minj = 0; int min=0; for(int i=0;i<row;i++) { for(int j=0;j<col;j++) { if(map[i][j]!=0) continue; int t=GiveScore(2, i, j); if(min>t) { min=t; mini=i; minj=j; } } } int lastx=maxi,lasty=maxj; if(max<=Math.abs(min)) { lastx=mini; lasty=minj; } Point p = new Point(lastx,lasty); return p; } //人下子后的状态变化 public static void pboardModify( int x, int y ) { for( int k=0; k<572; k++ ) //修改玩家下子后棋盘状态的变化 { //如果[x][y]位置是玩家第k个"5"中的位置,且第k个"5"没有被封死 if( pTable[x][y][k]==1 && win[0][k]!=9 ) win[0][k]++; //如果[x][y]位置是计算机第k个"5"中的位置,则玩家下子后第k个"5"被封死 if( cTable[x][y][k]==1 ) //○●○○○ { cTable[x][y][k] = 0; win[1][k] = 9; } } }//pboard //计算机下子后的状态变化 public static void cboardModify( int x, int y ) { for( int k=0; k<572; k++ ) //修改计算机下子后,棋盘的变化状况 { //如果[x][y]位置是计算机第k个"5"中的位置,且第k个"5"没有被封死 if( cTable[x][y][k]==1 && win[1][k]!=9 ) { win[1][k]++; } //如果[x][y]位置是玩家第k个"5"中的位置,则计算机下子后第k个"5"被封死 if( pTable[x][y][k]==1 ) //●○●●● { pTable[x][y][k] =0; win[0][k] = 9; } } }//cboard /** * 估值 */ static int GiveScore( int type, int x, int y ) { int k, score = 0; for( k=0; k<572; k++ ) { if( type==1 ) //计算机下 { if( cTable[x][y][k]==1 ) //[x][y]是第k个"5"上的一个位置 { //第k个"5"中已经有win[1][k]个位置了 switch( win[1][k] ) { case 1: score += 5; break; case 2: score += 50; break; case 3: score += 500; break; case 4: score += 5000; break; default: break; } } } else //玩家下 { if( pTable[x][y][k] ==1) //[x][y]是第k个"5"上的一个位置 { //第k个"5"中已经有win[0][k]个位置了 switch( win[0][k] ) { case 1: score-=5; break; case 2: score-=50; break; case 3: score-=500; break; case 4: score-=5000; break; default: break; } } } } return score; } public static void InitBoard() { int i, j, k; pTable=new Integer[15][15][572]; cTable=new Integer[15][15][572]; for (i = 0; i < row; i++){ pTable[i]=new Integer[15][572]; cTable[i]=new Integer[15][572]; for (j = 0; j < col; j++) { pTable[i][j]=new Integer[572]; cTable[i][j]=new Integer[572]; for (k = 0; k < 572; k++) { //pTable[i][j][k]=new Integer(); pTable[i][j][k] = 0; cTable[i][j][k] = 0; } } } int count = 0; int x,y; // 横着的获胜组合 for (x= 0; x < 15; x++) { for (y= 0; y < 11; y++) { for (k = 0; k < 5; k++) { pTable[x][y+ k][count] = 1; cTable[x][y+ k][count] = 1; } count++; } } //竖的获胜组合 for (y = 0;y < 15; y++) { for (x = 0; x < 11; x++) { for (k = 0; k < 5; k++) { pTable[x+k][y][count] = 1; cTable[x+k][y][count] = 1; } count++; } } //主对角线 for( x = 0; x < 11; x++ ) { for( y = 0; y < 11; y++ ) { for( k = 0; k < 5; k++ ) { pTable[x+k][y+k][count] = 1; cTable[x+k][y+k][count] = 1; } count++; } } //次对角线 for( x = 4; x < 15; x++ ) { for( y = 0; y < 11; y++ ) { for( k = 0; k < 5; k++ ) { pTable[x-k][y+k][count] = 1; cTable[x-k][y+k][count] = 1; } count++; } } //初始化win win=new Integer[2][572]; win[0]=new Integer[572]; win[1]=new Integer[572]; for( k = 0; k < 572; k++ ) //初始化win数组 { win[0][k] = 0; win[1][k] = 0; } //初始化结束 }//init 结束 }
自己也知道有很多做的不好的地方,很多需要改进的地方。
欢迎大牛指点!
相关推荐
嵌入式课程设计——基于 STM32 的双人五子棋.zip
五子棋(最简单的)————基于网络的五子棋(最简单的)————基于网络的五子棋(最简单的)————基于网络的
这里设计和实现了一个人机对下的五子棋程序,采用了博弈树的方法,应用了剪枝和最大最小树原理进行搜索发现最好的下子位置。介绍五子棋程序的数据结构、评分规则、胜负判断方法和搜索算法过程。
python项目——五子棋(控制台版).zip python项目——五子棋(控制台版).zip python项目——五子棋(控制台版).zip python项目——五子棋(控制台版).zip python项目——五子棋(控制台版).zip python项目——...
java毕业设计——基于java的五子棋游戏的设计与开发(源代码+论文).zip java毕业设计——基于java的五子棋游戏的设计与开发(源代码+论文).zip java毕业设计——基于java的五子棋游戏的设计与开发(源代码+论文).zip ...
以批处理来调度运行 能进行网络联机 禁手选择 先手选择
五子棋AI算法原理,博弈树、极大极小值搜索算法、α-β剪枝算法
大一下人工智能程序设计课程大作业——五子棋
Python项目案例开发从入门到实战源代码第14章 网络通讯案例——基于UDP的网络五子棋.rar
WuziqiServer课程作业——基于C#和WPF的五子棋对战服务器设计一、五子棋服务器运行环境IDE:Visual Studio 2017(C# + WPF)框架:.NET Framework 4.6.1二、连接服务器ipAddress为五子棋服务器程序运行计算机ipv4地址,...
JAVA入门之五子棋——客户端 很短小的五子棋,初学java的作品 c/s架构,此为客户端
一个简单的五子棋程序 一个简单的人工智能算法
本文所做的主要工作是采用Python语言编写写一个双人对弈的五子棋游戏,要求有GUI界面、能够判断输赢、提示游戏结束,能重新开局且不受计算机环境所限制(即计算机不要求安装Python环境也可以进行五子棋游戏)。...
基于AI的五子棋游戏设计,很不错的毕业论文
JAVA入门之五子棋——服务器 很短小的五子棋,初学java的作品 c/s架构,此为服务器