基于Java Swing五子棋小游戏设计和实现
Posted java李阳勇
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于Java Swing五子棋小游戏设计和实现相关的知识,希望对你有一定的参考价值。
订阅专栏获取源码
前言:
五子棋相传起源于四千多年前的尧帝时期,比围棋的历史还要悠久,可能早在“尧造围棋”之前,民间就已有五子棋游戏。有关早期五子棋的文史资料与围棋有相似之处,因为古代五子棋的棋具与围棋是完全相同的。 在上古的神话传说中有“女娲造人, 伏羲做棋”一说,《增山海经》中记载: “休舆之山有石焉, 名曰帝台之棋, 五色而文状鹑卵。 ”善注引三国淳《艺经》 中曰: “棋局,纵横各十七道,合二百八十九道,白黑棋子,各一百五十枚”。这段虽没明讲是何种棋类,但至少知道远古就以漂亮的石头为棋子。因而规则简单的五子棋也可能出自当时,并是用石子作棋子。亦有传说,五子棋最初流行于少数民族地区,以后渐渐演变成围棋并在炎黄子后代中遍及开来。
项目结构:
功能截图:
关键代码:
初始化参数:
private ImageIcon map; //棋盘背景位图
private ImageIcon blackchess; //黑子位图
private ImageIcon whitechess; //白子位图
public int isChessOn [][]; //棋局
protected boolean win = false; // 是否已经分出胜负
protected int win_bw; // 胜利棋色
protected int deep = 3, weight = 7; // 搜索的深度以及广度
public int drawn_num = 110; // 和棋步数
int chess_num = 0; // 总落子数目
public int[][] pre = new int[drawn_num + 1][2]; // 记录下棋点的x,y坐标 最多 (drawn_num + 1) 个
public int sbw = 0; //玩家棋色黑色0,白色1
public int bw = 0; // 当前应该下的棋色 0:黑色(默认), 1:白色
// 边界值,用于速度优化
protected int x_max = 15, x_min = 0;
protected int y_max = 15, y_min = 0;
protected boolean able_flag = true; // 是否选择禁手标志 0:无禁手 1:有禁手(默认
private int h; //棋子长
private int w; //棋子宽
private int insx; //插入棋子的位置
private int insy;
private Point mousePoint; //鼠标当前位置
private int winer; //获胜方
private boolean humanhuman=false; //是否是人人对弈
private int plast=0; //走了几步了,
public int BLACK_ONE; //0表黑子
public int WHITE_ONE; //1表白子
public int NONE_ONE; //2表无子
public int N; //棋盘边长
电脑下棋逻辑处理:
public void putOne(int bwf ) { //bwf 棋色 0:黑色 1:白色
int x, y, mx = -100000000;
x = y = -1;
// 搜索最优下棋点
int[][] bests = getBests( bwf );
for (int k = 0; k < bests.length; k++) {
int i = bests[k][0];
int j = bests[k][1];
// 有成5,则直接下子,并退出循环..没有,则思考对方情况
if (getType(i, j, bwf) == 1) {
x = i;
y = j;
break;
}
if (getType(i, j,1 - bwf) == 1) {
x = i;
y = j;
break;
}
// 预存当前边界值
int temp1=x_min,temp2=x_max,temp3=y_min,temp4=y_max;
// 预设己方下棋,并更新边界值
isChessOn[i][j] = bwf;
resetMaxMin(i,j);
// 预测未来
int t = findMin(-100000000, 100000000, deep);
// 还原预设下棋位置以及边界值
isChessOn[i][j] = 2;
x_min=temp1;
x_max=temp2;
y_min=temp3;
y_max=temp4;
// 差距小于1000,50%概率随机选取
//System.out.println("外 :" + i + "," + j + " mx:" + mx + " t:" + t);
if (t - mx > 1000 || Math.abs(t - mx)<1000 && randomTest(3)) {
x = i;
y = j;
mx = t;
//System.out.println(i + "," + j + " mx:" + mx + " t:" + t);
}
}
System.out.println("x="+x+",y="+y);
// addChess(x,y,(bwf+1)%2,true);
// repaint();
int step=0;
step++;
System.out.println("step "+step+":-----------------------------------------------");
for(int i=0;i<15;i++,System.out.print("\\n"))
for(int j=0;j<15;j++)
{
if(isChessOn[j][i]!=2)System.out.print(isChessOn[j][i]);
else System.out.print(isChessOn[j][i]);
}
// 判断是否已分胜负
boolean flag = haveWin(x, y, bwf);
//记录
update( x, y );
repaint();
// 重设边界值
resetMaxMin(x,y);
// 胜负已分
if (flag)
wined(bwf);
if (!flag && chess_num >= drawn_num) {
win = true;
String str = drawn_num + "步没分胜负,判和棋!";
JOptionPane.showMessageDialog(null,str);
return;
}
}
-搜索当前状态极大值
alpha :祖先节点得到的当前最小最大值,用于alpha 剪枝
beta :祖先节点得到的当前最大最小值,用于beta 剪枝。
step :还要搜索的步数
return: 当前搜索子树极大值
protected int findMax(int alpha, int beta, int step) {
int max = alpha;
if (step == 0) {
return evaluate();
}
int[][] rt = getBests(1 - sbw);
for (int i = 0; i < rt.length; i++) {
int x = rt[i][0];
int y = rt[i][1];
if (getType(x, y, 1 - sbw) == 1) //电脑可取胜
return 100 * ( getMark(1) + step*1000 );
isChessOn[x][y] = 1 - sbw;
// 预存当前边界值
int temp1=x_min,temp2=x_max,temp3=y_min,temp4=y_max;
resetMaxMin(x,y);
int t = findMin(max, beta, step - 1);
isChessOn[x][y] = 2;
// 还原预设边界值
x_min=temp1;
x_max=temp2;
y_min=temp3;
y_max=temp4;
if (t > max)
max = t;
//beta 剪枝
if (max >= beta)
return max;
}
return max;
}
总结:
通过此次课程设计,将我本学期所学的JAVA知识得到巩固和应用,在设计的过程中我遇到了很到问题,不过在老师和同学们的帮助和自己的思考下还是很好的完成了。这此课程设计还让我懂得了写程序不能闭门造车,要努力拓宽知识面,开阔视野,拓展思维。它还让我学会了在网上查阅那些无限的资料。由于自己的分析设计和程序经验不足,该系统设计和实现过程中,还有许多没有完善的地方,比如用户界面设计不够美观等多方面问题,这些都有待进一步完善和提高。对于文中出现的不足和系统中出现的问题敬请老师指导。
订阅专栏获取源码
JavaSwing系列项目推荐:
打卡Java文章更新 19 / 100 天
大家可以点赞、收藏、关注、评论我啦
以上是关于基于Java Swing五子棋小游戏设计和实现的主要内容,如果未能解决你的问题,请参考以下文章