简介
使用Java实现简易五子棋
规则介绍
游戏使用一个标准的15×15方格的棋盘,双方分别用黑白两种颜色的棋子进行对战。黑子先行,双方轮流在空棋盘的交叉点上落子,每人一次只能落一子。游戏的目标是让自己的五颗棋子连成一线,这条线可以是横线、竖线、对角线或斜线。如果一方的五颗棋子按照上述规则连成一线,这一方就获胜并结束游戏。
(1)对局双方各执一色棋子。
(2)空棋盘开局。
(3)黑先、白后,交替下子,每次只能下一子。
(4)棋子下在棋盘的空白点上,棋子下定后不得移动或拿走。
(5)黑方的第一枚棋子必须下在天元点上,即中心交叉点"
功能设计
- 重新开始
用户操作【重新开始】功能,弹窗询问是否确定重新开始,如果是则将所有数据重新初始化,否则什么也不做。 - 悔棋
用户操作【悔棋】功能,恢复上一步的操作,如果已无上一步操作或者游戏结束,不允许悔棋并弹窗提示。 - 退出游戏
用户操作【退出游戏】功能,关闭该应用程序。 - 帮助
菜单栏添加玩法提示,引导用户使用。 - 坐标校准
由于棋子需下在网格线上,交叉点的坐标很小,故鼠标很难精准点击在符合的坐标上,那么就需要对用户点击的坐标进行校准,将其坐标校准为最贴近的符合坐标。 - 坐标可行性及输赢判断
用户落子时,判断该坐标是否可用(是否已有棋子),如果不可行,弹窗提示,否则,判断输赢并且刷新页面绘制棋子。如果某一方获胜,提示游戏结束,禁止继续落下棋子。 - 输赢判断算法
以落下棋子坐标出发,向上下、左右、左上右下、右上左下四个方向延伸,朝一个方向至多延伸五次,若有同色棋子,则计数器加一,最终判断计数器是否大于等于5,如果是则获得胜利。
实现
附上如下实现代码
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Objects;
import java.util.Stack;
public class Gobang extends JPanel {
boolean op = false; //true-white false black
boolean win = false;
static final int SCREEN_WIDTH = 700;
static final int SCREEN_HEIGHT = 700;
static final int UNIT_SIZE = 50;
static final int GAME_UNITS = SCREEN_WIDTH / UNIT_SIZE;
boolean[][] black;
boolean[][] white;
Graphics g;
Point checkPoint;
Stack<Point> opStack;
MouseListener mouseListener;
JMenuBar menuBar;
Gobang() {
this.setPreferredSize(new Dimension(SCREEN_WIDTH, SCREEN_HEIGHT));
this.setFocusable(true);
this.addKeyListener(new MyKeyAdapter());
init();
}
/**
* 初始化网格
*/
public void initCheckerboard() {
if (Objects.isNull(g)) {
return;
}
g.setColor(Color.BLACK);
for (int i = 0; i < SCREEN_WIDTH; i += UNIT_SIZE) {
g.drawLine(i, 0, i, SCREEN_HEIGHT);
}
for (int i = 0; i < SCREEN_HEIGHT; i += UNIT_SIZE) {
g.drawLine(0, i, SCREEN_WIDTH, i);
}
}
public void initMenu() {
menuBar = new JMenuBar();
JMenu menu = new JMenu("菜单");
JMenuItem restart;
(restart = new JMenuItem("重新开始")).addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int res = JOptionPane.showConfirmDialog(null, "请确定要重新开始吗?", "", JOptionPane.OK_CANCEL_OPTION);
if (res == 0) {
init();
}
}
});
menu.add(restart);
JMenuItem regretChess;
(regretChess = new JMenuItem("悔棋")).addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
regretChess();
}
});
menu.add(regretChess);
JMenuItem exit;
(exit = new JMenuItem("退出游戏")).addActionListener(new ActionListener(