java中五子棋_Java简单五子棋的实现

本文介绍了用Java实现简单五子棋游戏的过程。先绘制棋盘和实现落子,考虑落子位置、顺序等问题;接着实现按钮功能和人人对战,通过判断八个方向是否有五子相连确定胜负;最后用权值算法实现人机对战。还分享了编程中解决细节问题的经验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在经过了几天的学习后,已经可以实现一个简单的五子棋游戏了,下面我就写一下编写程序 的过程和自己在这个过程中的心得体会。

第一步:绘制棋盘和实现落子

具体的过程就不写了,我是绘制了一个15*15的棋盘,在棋盘的右侧添加了几个按钮分别是“开始游戏”、“悔棋”、“认输”、“人人对战”、“人机对战”。这里用到的API类主要有JFrame、JPanel、BorderLayout、JButton、JRadioButton、ButtonGroup、Dimension、MouseAdapter(MouseListener)、MouseEvent、ActionListener、ActionEvent、Graphics2D、Color。在实现落子的时候主要要考虑这几个问题。如何让棋子落在交叉点上,如何让一个交叉点只安放一个棋子,让黑棋和白旗按照顺序落下。因为鼠标点击的位置不可能每次都正好在交叉点上,所以要设置一个范围,只要在交叉点的这个范围内点击就能落子。创建一个保存棋子位置的二维数组,只要落了子就保存在数组中,这样一个点就只能下一个棋子了。最后设置一个计数器count,只要count=0就下黑棋,count=1下白棋即可。这里主要还有一个问题,因为每次添加JPanel面板时画笔就会重绘一次,这样会覆盖掉画好的棋子和棋盘,如果将窗口最小化再打开,就什么都没有了。这时候需要重写JPanel里的paint方法,将绘制棋盘和棋子的方法写入就可以了。

第二步:实现按钮功能和人人对战

“开始游戏”:将存放棋子位置的二位数组全部清零之后调用paint方法重绘棋盘即可。

“认输”:读取计数器count,如果是1则黑棋获胜,0则白棋获胜。

“悔棋”:我认为悔棋有两种方式,一种是刚刚下棋的一方悔一次棋,另一种是能够不断悔棋。我使用的是第二种方法。创建两个数组存放每次落子的横坐标和纵坐标,当点击按钮时将这一位置清零然后重绘棋盘即可。

人人对战的算法比较好实现,只要判断左右,上下,y=x,y=-x这八个方向上有没有连续的相同颜色的五个棋子就行。

public int checkrow(int x, int y){

int count1=0;//存放连续的相同颜色的棋子数for(int i=x+1;i<15;i++){

if(chess[i][y]==chess[x][y]){

count1++;

}

else {

break;

}

}

for(int i=x;i>=0;i--){

if(chess[i][y]==chess[x][y]){

count1++;

}

else {

break;

}

}

return count1;

}

这是左右方向的算法,其他方向的以此类推。这样,只要每次下完棋都判断一次,就能知道那方获胜。

第三步:实现人机对战

查看了网上的资料后,发现五子棋的AI主要有两个算法,一个是博弈树,另一个是权值算法。因为博弈树算法比较复杂 ,所以我使用的是权值算法。权值算法就是在每次落子之后,在落子的周围空位上生成权值,哪个空位的权值大,就让AI下在那个位置。这就需要我们创建一个哈希表,将每一种棋子相连的情况对应一个权值.

HashMap hm = new HashMap();

public void hxb(){

hm.put("2", 30);

hm.put("1", 10);

hm.put("22", 1000);

hm.put("21", 20);

hm.put("11", 1500);

hm.put("12", 15);

hm.put("222", 10000);

hm.put("221", 150);

hm.put("112", 100);

hm.put("111", 3000);

hm.put("1111", 20000);

hm.put("2222", 100000);

hm.put("1112", 2000);

hm.put("2221", 1900);

hm.put("22221", 50000);

hm.put("11112", 15000);

}

这里我使用字符串来保存棋子相连的情况,1对应黑棋,2对应白棋,12就是一个黑棋和一个白棋相连。对应的权值大小可以自行调整。

在创建好哈希表后,接下来要做的就是写一个方法,给予每一个空位权值。

public void AI(){

for(int i=0;i<15;i++){

for(int j=0;j<15;j++){

if(chess[i][j]==0){

//搜索该空位八个方向上棋子相连情况//定义:chess变量记录棋子相连情况,color记录棋子颜色String czf="";

int color=0;

for(int k=i+1;k<15;k++){

if(chess[k][j]==0){

break;

}else{ if(color==0){

czf+=chess[k][j];

color=chess[k][j];

}else if(color==chess[k][j]){

czf+=chess[k][j];

}else{

czf+=chess[k][j];

break;

}

}

}

//根据棋子相连情况取出对应的权值累加Integer value = hm.get(czf);

if(value!=null){

chessValue[i][j]+=value;

}

czf="";

color=0;

//向左 }

}

}

}

这里的是根据左右方向给予权值,其他方向以此类推。之后就是根据权值让AI落子。要注意的是每一次AI落子后都要讲存放空位权值的数组chessValue清零。剩下的就是把一些细节部分给完善,这样,一个简单的五子棋游戏就完成了。

在写这个游戏的过程中出现了许许多多的错误,也收获了很多的东西。真正写起来,算法的部分其实不是很难完成,主要是细节方面的错误太多了,也浪费了很多时间。写程序的时候,一个清晰的思路十分重要,脑海里还要有一个大概的框架。在出现问题时,要仔细分析问题,寻找问题的源头。与同伴的交流也十分的重要,因为每个人的看法不同,所以和同伴沟通能够提供新的思路,碰撞出新的火花,解决问题的时候也能大大提升效率。最重要的,和同伴一起完整一项工作是一件挺开心的事:-D。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值