⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gobang.java

📁 java编写的五子棋源代码具有很好的学习价值,对与五子棋的游戏开发
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
}
}
//和棋
String str = "将遇良才,棋逢对手!!!";
mp.setMessage(str);
JOptionPane.showMessageDialog(Gobang.this, str, "五子棋", JOptionPane.INformATION_MESSAGE);
gameOver();
return true;
}
}

/********************************************
函数功能:返回水平方向上的连子数
输入参数:下棋点的行号和列号
输出参数:连子数
*******************************************/
private int sumRow(int row, int col) {
int l = col, r = col;
for (int h = col - 1; h >= 0; h--) {
if (p[row][h].f == p[row][col].f) {
l = h;
} else {
break;
}
}
for (int h = col + 1; h < 15; h++) {
if (p[row][h].f == p[row][col].f) {
r = h;
} else {
break;
}
}
return r - l + 1;
}

/********************************************
函数功能:返回垂直方向上的连子数
输入参数:下棋点的行号和列号
输出参数:连子数
*******************************************/
private int sumCol(int row, int col) {
int l = row, r = row;
for (int h = row - 1; h >= 0; h--) {
if (p[h][col].f == p[row][col].f) {
l = h;
} else {
break;
}
}
for (int h = row + 1; h < 15; h++) {
if (p[h][col].f == p[row][col].f) {
r = h;
} else {
break;
}
}
return r - l + 1;
}

/********************************************
函数功能:返回左上角到右下角方向上的连子数
输入参数:下棋点的行号和列号
输出参数:连子数
*******************************************/
private int sumLr(int row, int col) {
int l = row, r = row;
for (int h = row - 1, h2 = col - 1; h >= 0; h--, h2--) {
if (h2 < 0)
break;
if (p[h][h2].f == p[row][col].f) {
l = h;
} else {
break;
}
}
for (int h = row + 1, h2 = col + 1; h < 15; h++, h2++) {
if (h2 >= 15)
break;
if (p[h][h2].f == p[row][col].f) {
r = h;
} else {
break;
}
}
return r - l + 1;
}

/********************************************
函数功能:返回右上角到左下角方向上的连子数
输入参数:下棋点的行号和列号
输出参数:连子数
*******************************************/
private int sumRl(int row, int col) {
int l = row, r = row;
for (int h = row - 1, h2 = col + 1; h >= 0; h--, h2++) {
if (h2 >= 15)
break;
if (p[h][h2].f == p[row][col].f) {
l = h;
} else {
break;
}
}
for (int h = row + 1, h2 = col - 1; h < 15; h++, h2--) {
if (h2 < 0)
break;
if (p[h][h2].f == p[row][col].f) {
r = h;
} else {
break;
}
}
return r - l + 1;
}
}

/*
* 棋格面板***********************
* 主窗体由15*15个本对象组成
*/
class ToePanel extends JPanel {
private Gobang main; //容纳本面板的主窗体,主要是用来显示消息框的时候作为容器,这样消息框便会居中显示
int flag = 0; //标志位,用来标识应该画黑棋还是白棋,1 黑棋,0 空,-1 白棋
int f = flag; //记录棋子颜色值,用于在提示棋子位置的方法中使用
private int row, col; //本棋子所处的行号和列号
private int w; //棋子的直径
MyStop ms = new MyStop(); //结束下棋的监听器
private Timer tiShiPingLu; //棋子闪烁的时间对象
private Timer tiShiZhouQi; //每一次提示与提示之间的时间对象
private int count = 0; //记录棋子闪烁的次数,闪烁6次之后就停止,

ToePanel(int h, int l, Gobang a) {
row = h;
col = l;
main = a;
//单击鼠标时执行下棋的方法
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
//网络对战--------------------------------------------------------------
//能够下棋的条件:1.当前格子为空 2.该自己下 3.对方没有结束游戏 4.单击的是鼠标左键
if (f == 0 && main.t && main.t2 && e.getButton() == 1) {
if (main.x != -1)
main.p[main.x][main.y].stopTiShi(); //如果不是下第一颗棋,则调用停止棋子闪烁的方法
xiaQi(main.c); //在鼠标点击处下棋
main.mp.setMessage("等待对方落子...");
main.t = false; //下子后必须等对方下子后才能再下

//把下棋的位置传给对方
main.out.println(row);
main.out.println(col);

//判断胜负
main.checkWin(row, col, main.c);
}

//练习模式--------------------------------------------------------------
//能够下棋的条件:1.当前格子为空 2.正处于练习模式 3.单击的是鼠标左键
if (f == 0 && e.getButton() == 1 && main.isExercise) {
if (main.x != -1)
main.p[main.x][main.y].stopTiShi(); //如果不是下第一颗棋,则调用停止棋子闪烁的方法
xiaQi(main.c); //在鼠标点击处下棋
main.x = row;
main.y = col;
tiShi(); //开启提示棋子位置的功能(其实也没多大必要,因为电脑不可能想得到很久)
main.mp.setMessage("电脑正在思考...");

//下面就该电脑下棋了!
if (!main.checkWin(row, col, main.c)) {
int[][] table = new int[15][15];
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
table[i][j] = main.p[i][j].f;
}
}
int[] computer = Computer.think(table); //电脑思考落子点
stopTiShi(); //停止提示玩家落子点
main.x = computer[0];
main.y = computer[1];
main.p[main.x][main.y].xiaQi(-main.c); //在电脑给出的落子点下棋
main.p[main.x][main.y].tiShi(); //开启电脑落子点的提示功能
main.mp.setMessage("该您下了!");
main.checkWin(main.x, main.y, -main.c); //检查电脑是否获胜
}
}
}
});
}

public void paintComponent(Graphics g) {
super.paintComponent(g);//刷新
this.setBackground(Color.green);//设置背景色

//画网格线
if (row > 0)
g.drawLine(getWidth() / 2, 0, getWidth() / 2, getHeight() / 2);
if (row < 14)
g.drawLine(getWidth() / 2, getHeight() / 2, getWidth() / 2, getHeight());
if (col > 0)
g.drawLine(0, getHeight() / 2, getWidth() / 2, getHeight() / 2);
if (col < 14)
g.drawLine(getWidth() / 2, getHeight() / 2, getWidth(), getHeight() / 2);

//画中心点
if (row == 3 && col == 3)
g.fillRect(getWidth() / 2 - 2, getHeight() / 2 - 2, 5, 5);
if (row == 3 && col == 7)
g.fillRect(getWidth() / 2 - 2, getHeight() / 2 - 2, 5, 5);
if (row == 3 && col == 11)
g.fillRect(getWidth() / 2 - 2, getHeight() / 2 - 2, 5, 5);
if (row == 7 && col == 3)
g.fillRect(getWidth() / 2 - 2, getHeight() / 2 - 2, 5, 5);
if (row == 7 && col == 7)
g.fillRect(getWidth() / 2 - 2, getHeight() / 2 - 2, 5, 5);
if (row == 7 && col == 11)
g.fillRect(getWidth() / 2 - 2, getHeight() / 2 - 2, 5, 5);
if (row == 11 && col == 3)
g.fillRect(getWidth() / 2 - 2, getHeight() / 2 - 2, 5, 5);
if (row == 11 && col == 7)
g.fillRect(getWidth() / 2 - 2, getHeight() / 2 - 2, 5, 5);
if (row == 11 && col == 11)
g.fillRect(getWidth() / 2 - 2, getHeight() / 2 - 2, 5, 5);

//设置棋子的直径
w = (getWidth() < getHeight()) ? getWidth() : getHeight();
w = (int) (w * 0.8);

//画棋子
switch (flag) {
case 1:
g.setColor(Color.black);
g.fillOval((getWidth() - w) / 2, (getHeight() - w) / 2, w, w);
break;
case -1:
g.setColor(Color.white);
g.fillOval((getWidth() - w) / 2, (getHeight() - w) / 2, w, w);
break;
}
}

/********************************************
函数功能:在本面板上显示出输入颜色值的棋子
输入参数:棋子颜色
输出参数:无
*******************************************/
void xiaQi(int f) {
flag = f;
this.f = flag; //记录棋子的颜色
repaint();
}

/********************************************
函数功能:每隔5秒钟闪烁显示本面板上的棋子
输入参数:无
输出参数:无
*******************************************/
void tiShi() {
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent e) {
tiShiZhouQi.stop();
count = 0;
tiShiPingLu.start();
}
};
ActionListener al2 = new ActionListener() {
public void actionPerformed(ActionEvent e) {
flag = flag != 0 ? 0 : f;
repaint();
if (count++ == 5) {
tiShiPingLu.stop();
tiShiZhouQi.start();
}
}
};

tiShiZhouQi = new Timer(5000, al); //提示的间隔周期:5秒
tiShiPingLu = new Timer(200, al2); //棋子闪烁的频率:0.2秒
tiShiZhouQi.start();
}

/********************************************
函数功能:停止闪烁本面板上的棋子
输入参数:无
输出参数:无
*******************************************/
void stopTiShi() {
flag = f;
repaint();
tiShiZhouQi.stop();
tiShiPingLu.stop();
}

//结束下棋的事件监听器,主要是清空所有的棋子
private class MyStop implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (f != 0) {
f = flag = 0;
repaint();
}
}
}
}

/*
* 消息面板***********************
* 位于主窗体顶部,专门用于显示各种系统消息
*/
class MessagePanel extends JPanel {
private JLabel message = new JLabel(); //显示消息的标签
private Timer showMessageTimer; //渐变显示标签的时间对象
private int messageColor; //记录消息标签的颜色值

MessagePanel() {
setBackground(Color.BLACK);
message.setFont(new Font("宋体", Font.BOLD, 15));
message.setForeground(Color.BLACK); //初始化时设置消息标签的颜色为黑色(这样就看不见了)
add(message);
showMessageTimer = new Timer(1, al); //初始化时间对象
setMessage("五子棋");
}

private ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent e) {
message.setForeground(new Color(messageColor, messageColor, 0));
if (messageColor == 255)
showMessageTimer.stop();
messageColor += 3;
}
};

/********************************************
函数功能:改变消息标签message的内容并进行淡出效果显示
输入参数:消息标签的新内容
输出参数:无
*******************************************/
void setMessage(String newMessage) {
message.setForeground(Color.BLACK);
message.setText(newMessage);
showMessageTimer.stop(); //停止渐变显示
messageColor = 0; //重设颜色初始值
showMessageTimer.start(); //开始渐变显示消息标签
}
}

/*
* 电脑落子根据该点的重要度来判断,重要度规定如下:
* 1.落子后即获胜,重要度=1398101
* 2.落子后防止对方成五星连珠重要度=349525
* 3.落子后形成活四,重要度=87381
* 4.落子后防止对方成活四重要度=21845
* 5.落子后形成双活三,重要度=5461
* 6.落子后防止对方成双活三重要度=1365
* 7.落子后形成冲四重要度=341
* 8.落子后形成活三重要度=85
* 9.落子后防止对方成活三重要度=21
* 10.落子后形成活二重要度=5
* 11.落子后防止对方成活二重要度=1
* 12.落子后成为一个单独点重要度=0 * 
* 
*/

class Computer {
private static int[][] t; //棋型数据表,存储每个格子上的棋子颜色,0表示空,1为黑色,-1为白色
private static int[][] importance = new int[15][15]; //存储每个点的重要度

/********************************************
函数功能:电脑计算落子的位置
输入参数:当前棋型数据表(15x15的二维数组)
输出参数:电脑落子位置的行号和列号(数组)
*******************************************/
static int[] think(int[][] table) {
t = table; //储存当前的棋型表以便其它方法使用
int[] result = new int[2];

int count = -1; //最大的重要度值
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
if (t[i][j] == 0) {
importance[i][j] = getImportance(i, j);
if (count < importance[i][j]) {
count = importance[i][j];
result[0] = i;
result[1] = j;
}
}
}
}

return result;
}

/********************************************
函数功能:返回某一点的重要度
输入参数:下棋点的行号和列号,下棋点的颜色值
输出参数:重要度
*******************************************/
private static int getImportance(int row, int col) {
int g = 0; //重要度数值
int whiteSumRow, whiteSumCol, whiteSumLr, whiteSumRl; //电脑落子后在四个方向上的连子数
int whiteStateRow, whiteStateCol, whiteStateLr, whiteStateRl; //电脑落子后在四个方向上的状态值
int blackSumRow, blackSumCol, blackSumLr, blackSumRl; //玩家落子后在四个方向上的连子数
int blackStateRow, blackStateCol, blackStateLr, blackStateRl; //玩家落子后在四个方向上的状态值

//获得该点在四个方向上的连子数及状态值(包括电脑和玩家)
int[] sum;
sum = sumRow(row, col, -1);
whiteSumRow = sum[0];
whiteStateRow = sum[1];

sum = sumCol(row, col, -1);
whiteSumCol = sum[0];
whiteStateCol = sum[1];

sum = sumLr(row, col, -1);
whiteSumLr = sum[0];
whiteStateLr = sum[1];

sum = sumRl(row, col, -1);
whiteSumRl = sum[0];
whiteStateRl = sum[1];

sum = sumRow(row, col, 1);
blackSumRow = sum[0];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -