Java游戏开发 —— 五子棋

article/2025/9/20 15:53:42

 引言:

        五子棋的代码实现很简单,难的是计算机的AI算法,在网上找了很多资料,费了好半天劲才弄明白其实现的原理,真的挺开阔思路的,很有意思!

思路:

        1、创建主窗口,加载菜单及游戏面板。

        2、在游戏面板中初始化各种参数,并建立各种功能组件。

        3、利用paint()函数开始画棋盘,5个定位点,落子指示器,棋子(并标记最后一个棋子的红矩形框),五子成线。

        4、利用mouseMoved()鼠标移动函数设置落子指示器的位置。

        5、利用mouseClicked()鼠标单击函数来判断是否可以下棋,由哪方来下,判断是否平局或胜利。如果是人机对战要计算电脑要下棋的最佳位置。

        6、游戏结束,收尾,准备下一局。

代码: 

图片位置与包位置平齐,因为我装载图片时是从类路径开始取,取绝对路径是不认可的。

        本游戏用的是JDK1.8,编码UTF-8;

        共有4个类,Gobang.java是游戏入口类。GameFrame.java是主窗口类。GamePanel.java是游戏面板类。GameLogic.java是游戏逻辑类。先一口气把所有的代码贴上来再说。

        1、Gobang.java 游戏入口类

package com.game.gobang;/*** 功能:五子棋<br>* 作者:我是小木鱼(Lag)<br>*/
public class Gobang 
{public static void main(String[] args) {new GameFrame();}}

        2、GameFrame.java 主窗口类。

package com.game.gobang;import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;/*** 功能:游戏窗口<br>* 作者:我是小木鱼(Lag)<br>*/
public class GameFrame extends JFrame implements ActionListener
{private static final long serialVersionUID = 1L;/** 游戏面板 */private GamePanel gamePanel;/*** 功能:构造函数<br>*/public GameFrame(){try{//菜单JMenuBar jmb_gobang = new JMenuBar();JMenu jm_game = new JMenu("游戏");jm_game.setFont(new Font("微软雅黑",Font.PLAIN,12));JMenuItem jmi_game_new = jm_game.add("新游戏");jmi_game_new.setFont(new Font("微软雅黑",Font.PLAIN,12));jmi_game_new.addActionListener(this);jmi_game_new.setActionCommand("new");JMenuItem jmi_game_undo = jm_game.add("悔棋");jmi_game_undo.setFont(new Font("微软雅黑",Font.PLAIN,12));jmi_game_undo.addActionListener(this);jmi_game_undo.setActionCommand("undo");JMenuItem jmi_surrender = jm_game.add("认输");jmi_surrender.setFont(new Font("微软雅黑",Font.PLAIN,12));jmi_surrender.addActionListener(this);jmi_surrender.setActionCommand("surrender");jm_game.addSeparator();JMenuItem jmi_game_exit = jm_game.add("退出");jmi_game_exit.setFont(new Font("微软雅黑",Font.PLAIN,12));jmi_game_exit.addActionListener(this);jmi_game_exit.setActionCommand("exit");jmb_gobang.add(jm_game);JMenu jm_help = new JMenu("帮助");jm_help.setFont(new Font("微软雅黑",Font.PLAIN,12));JMenuItem jmi_help_about = jm_help.add("关于");jmi_help_about.setFont(new Font("微软雅黑",Font.PLAIN,12));jmi_help_about.addActionListener(this);jmi_help_about.setActionCommand("about");jmb_gobang.add(jm_help);this.setJMenuBar(jmb_gobang);//面板this.gamePanel = new GamePanel();this.add(this.gamePanel);//显示this.setTitle("五子棋");this.setLayout(null);this.setSize(760,680);this.setResizable(false);this.setLocationRelativeTo(null);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);}catch(Exception e){JOptionPane.showMessageDialog(this,"程序出现异常错误,即将退出!\r\n\r\n"+e.toString(),"提示",JOptionPane.ERROR_MESSAGE);System.exit(0);}}/*** 功能:事件监听<br>*/@Overridepublic void actionPerformed(ActionEvent e){String command = e.getActionCommand();if("new".equals(command)){this.gamePanel.newGame();}else if("undo".equals(command)){this.gamePanel.undo();}else if("surrender".equals(command)){this.gamePanel.surrender();}else if("exit".equals(command)){System.exit(0);}else if("about".equals(command)){JOptionPane.showMessageDialog(this,"我是小木鱼(Lag)","提示",JOptionPane.INFORMATION_MESSAGE);}}}

        3、GamePanel.java 游戏面板类。

package com.game.gobang;import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Font;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RadialGradientPaint;
import java.awt.RenderingHints;
import java.awt.BasicStroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Ellipse2D;/*** 功能:游戏面板<br>* 作者:我是小木鱼(Lag)<br>*/
public class GamePanel extends JPanel implements MouseListener,MouseMotionListener,ActionListener
{private static final long serialVersionUID = -7450693911538496165L;/** 游戏逻辑 */private GameLogic gameLogic;/** 格子大小 */final int spaceSize = 40;/** 棋子大小(直径) */final int chessSize = 30;/** 棋盘X方向格数 */final int chessBoradXGrids = 15;/** 棋盘Y方向格数 */final int chessBoradYGrids = 15;/** 棋盘左上角X坐标 */final int chessBoradX = 30;/** 棋盘左上角Y坐标 */final int chessBoradY = 30;/** 棋盘宽度 */final int chessBoradWidth = spaceSize * (chessBoradXGrids - 1);/** 棋盘高度 */final int chessBoradHeight = spaceSize * (chessBoradYGrids - 1);/** 黑棋标识 */final int BLACKCHESS = 1;/** 白棋标识 */final int WHITECHESS = 2;/** 对战方式(0-人机对战,1-人人对战) */int fightType ;/** 先手选择(0-玩家先手,1-电脑先手) */int playFirst ;/** 黑白选择(0-玩家执黑,1-玩家执白) */int chessColor ;/** 电脑棋子颜色 */int computerChess = -1 ;/** 玩家棋子颜色 */int playerChess = -1 ;/** 白棋悔棋数 */int whiteUndoNum = 3;/** 黑棋悔棋数 */int blackUndoNum = 3;/** 全部下棋信息 */List<Map<String,Integer>> listChess = new ArrayList<Map<String,Integer>>();/** 白棋下棋信息 */List<Map<String,Integer>> listChessWhite = new ArrayList<Map<String,Integer>>();/** 黑棋下棋信息 */List<Map<String,Integer>> listChessBlack = new ArrayList<Map<String,Integer>>();/** 胜利下棋信息(胜利后要将五子成线的那五个棋子用红线连在一起显示) */List<Map<String,Integer>> listChessWin = new ArrayList<Map<String,Integer>>();/** 落子指示器 */Map<String,Integer> mapPointer = new HashMap<String,Integer>();/** 判断游戏是否结束(true-结束,false-未结束) */boolean isGameOver = true;/** 组合框控件 */private JComboBox<String> jcb_fightType,jcb_playFirst,jcb_chessColor;/** 按钮控件 */private JButton jb_new,jb_undo,jb_surrender;/** 标签控件 */JLabel jlb_blackUndoText,jlb_blackStateText,jlb_whiteUndoText,jlb_whiteStateText;/*** 功能:构造函数<br>*/public GamePanel(){//与主窗口大小保持一致,并设置背景色(去掉菜单高度)this.setSize(760,620);this.setBackground(new Color(209,146,17));//右边功能区布局this.option();//鼠标点击与移动监听this.addMouseListener(this);this.addMouseMotionListener(this);//游戏逻辑this.gameLogic = new GameLogic(this);//初始化游戏this.initGame();}/*** 功能:右边功能区布局<br>*/private void option(){this.setLayout(null);//对战方式JLabel jlb_fightType = new JLabel("对战方式:");jlb_fightType.setFont(new Font("微软雅黑",Font.PLAIN,12));jlb_fightType.setForeground(Color.WHITE);jlb_fightType.setBounds(this.chessBoradX + this.chessBoradWidth + 30,chessBoradY,100,24);this.add(jlb_fightType);this.jcb_fightType = new JComboBox<String>(new String[]{"人机对战","人人对战"});this.jcb_fightType.setFont(new Font("微软雅黑",Font.PLAIN,12));this.jcb_fightType.setBounds(this.chessBoradX + this.chessBoradWidth + 30,chessBoradY + 30,100,24);this.add(this.jcb_fightType);//谁先手JLabel jlb_playFirst = new JLabel("先手选择:");jlb_playFirst.setBounds(this.chessBoradX + this.chessBoradWidth + 30,chessBoradY + 70,100,24);jlb_playFirst.setFont(new Font("微软雅黑",Font.PLAIN,12));jlb_playFirst.setForeground(Color.WHITE);this.add(jlb_playFirst);this.jcb_playFirst = new JComboBox<String>(new String[]{"玩家先手","电脑先手"});this.jcb_playFirst.setFont(new Font("微软雅黑",Font.PLAIN,12));this.jcb_playFirst.setBounds(this.chessBoradX + this.chessBoradWidth + 30,chessBoradY + 100,100,24);this.add(this.jcb_playFirst);//谁执黑JLabel jlb_chessColor = new JLabel("黑白选择:");jlb_chessColor.setBounds(this.chessBoradX + this.chessBoradWidth + 30,chessBoradY + 140,100,24);jlb_chessColor.setFont(new Font("微软雅黑",Font.PLAIN,12));jlb_chessColor.setForeground(Color.WHITE);this.add(jlb_chessColor);this.jcb_chessColor = new JComboBox<String>(new String[]{"玩家执黑","玩家执白"});this.jcb_chessColor.setFont(new Font("微软雅黑",Font.PLAIN,12));this.jcb_chessColor.setBounds(this.chessBoradX + this.chessBoradWidth + 30,chessBoradY + 170,100,24);this.add(this.jcb_chessColor);//按钮this.jb_new = new JButton("开始游戏");this.jb_new.setFont(new Font("微软雅黑",Font.PLAIN,12));this.jb_new.setBounds(this.chessBoradX + this.chessBoradWidth + 30, chessBoradY + 230,100,30);this.jb_new.setActionCommand("newGame");this.jb_new.addActionListener(this);this.add(this.jb_new);this.jb_undo = new JButton("我要悔棋");this.jb_undo.setFont(new Font("微软雅黑",Font.PLAIN,12));this.jb_undo.setBounds(this.chessBoradX + this.chessBoradWidth + 30, chessBoradY + 280,100,30);this.jb_undo.setActionCommand("undo");this.jb_undo.addActionListener(this);this.jb_undo.setEnabled(false);this.add(this.jb_undo);this.jb_surrender = new JButton("我认输了");this.jb_surrender.setFont(new Font("微软雅黑",Font.PLAIN,12));this.jb_surrender.setBounds(this.chessBoradX + this.chessBoradWidth + 30, chessBoradY + 330,100,30);this.jb_surrender.setActionCommand("surrender");this.jb_surrender.addActionListener(this);this.jb_surrender.setEnabled(false);this.add(this.jb_surrender);//黑棋提示JPanel groupBoxBlack = new JPanel();groupBoxBlack.setLayout(null);groupBoxBlack.setBackground(this.getBackground());groupBoxBlack.setBounds(this.chessBoradX + this.chessBoradWidth + 30, chessBoradY + 380,100,80);groupBoxBlack.setBorder(BorderFactory.createTitledBorder("黑棋"));this.add(groupBoxBlack);JLabel jlb_blackUndo = new JLabel("悔棋:");jlb_blackUndo.setFont(new Font("微软雅黑",Font.PLAIN,12));jlb_blackUndo.setForeground(Color.WHITE);jlb_blackUndo.setBounds(10,16,40,30);groupBoxBlack.add(jlb_blackUndo);this.jlb_blackUndoText = new JLabel("剩"+Integer.toString(this.blackUndoNum)+"次");this.jlb_blackUndoText.setFont(new Font("微软雅黑",Font.BOLD,12));this.jlb_blackUndoText.setForeground(Color.darkGray);this.jlb_blackUndoText.setBounds(44,16,50,30);groupBoxBlack.add(this.jlb_blackUndoText);JLabel jlb_blackState = new JLabel("状态:");jlb_blackState.setFont(new Font("微软雅黑",Font.PLAIN,12));jlb_blackState.setForeground(Color.WHITE);jlb_blackState.setBounds(10,44,40,30);groupBoxBlack.add(jlb_blackState);this.jlb_blackStateText = new JLabel("未开始");this.jlb_blackStateText.setFont(new Font("微软雅黑",Font.BOLD,12));this.jlb_blackStateText.setForeground(Color.darkGray);this.jlb_blackStateText.setBounds(44,44,50,30);groupBoxBlack.add(this.jlb_blackStateText);//白棋提示JPanel groupBoxWhite = new JPanel();groupBoxWhite.setLayout(null);groupBoxWhite.setBackground(this.getBackground());groupBoxWhite.setBounds(this.chessBoradX + this.chessBoradWidth + 30, chessBoradY + 480,100,80);groupBoxWhite.setBorder(BorderFactory.createTitledBorder("白棋"));this.add(groupBoxWhite);JLabel jlb_whiteUndo = new JLabel("悔棋:");jlb_whiteUndo.setFont(new Font("微软雅黑",Font.PLAIN,12));jlb_whiteUndo.setForeground(Color.WHITE);jlb_whiteUndo.setBounds(10,16,40,30);groupBoxWhite.add(jlb_whiteUndo);this.jlb_whiteUndoText = new JLabel("剩"+Integer.toString(this.whiteUndoNum)+"次");this.jlb_whiteUndoText.setFont(new Font("微软雅黑",Font.BOLD,12));this.jlb_whiteUndoText.setForeground(Color.darkGray);this.jlb_whiteUndoText.setBounds(44,16,50,30);groupBoxWhite.add(this.jlb_whiteUndoText);JLabel jlb_whiteState = new JLabel("状态:");jlb_whiteState.setFont(new Font("微软雅黑",Font.PLAIN,12));jlb_whiteState.setForeground(Color.WHITE);jlb_whiteState.setBounds(10,44,40,30);groupBoxWhite.add(jlb_whiteState);this.jlb_whiteStateText = new JLabel("未开始");this.jlb_whiteStateText.setFont(new Font("微软雅黑",Font.BOLD,12));this.jlb_whiteStateText.setForeground(Color.darkGray);this.jlb_whiteStateText.setBounds(44,44,50,30);groupBoxWhite.add(this.jlb_whiteStateText);}/*** 功能:初始化游戏<br>*/public void initGame(){this.isGameOver = true;//清空下棋列表this.listChess.clear();this.listChessBlack.clear();this.listChessWhite.clear();this.listChessWin.clear();//落子指示器初始化this.mapPointer.put("x",-1);this.mapPointer.put("y",-1);this.mapPointer.put("show",0);	//0-不显示,1-显示//对战方式if("人人对战".equals(this.jcb_fightType.getSelectedItem().toString())){this.fightType = 1;}else{this.fightType = 0;}//先手选择if("电脑先手".equals(this.jcb_playFirst.getSelectedItem().toString())){this.playFirst = 1;}else{this.playFirst = 0;}//黑白选择if("玩家执白".equals(this.jcb_chessColor.getSelectedItem().toString())){this.chessColor = 1;}else{this.chessColor = 0;}//电脑与玩家棋子颜色if(this.fightType == 0){if(this.chessColor == 1){this.playerChess = this.WHITECHESS;this.computerChess = this.BLACKCHESS;}else{this.computerChess = this.WHITECHESS;this.playerChess = this.BLACKCHESS;}}//悔棋数初始化this.whiteUndoNum = 3;this.blackUndoNum = 3;//设置控件状态this.setComponentState(false);}/*** 功能:设置控件状态<br>* 参数:true-新开局;false-未开局<br>*/public void setComponentState(boolean _flag){if(_flag)	//新游戏已经开始了{this.jcb_fightType.setEnabled(false);this.jcb_playFirst.setEnabled(false);this.jcb_chessColor.setEnabled(false);this.jb_new.setEnabled(false);this.jb_undo.setEnabled(true);this.jb_surrender.setEnabled(true);}else	//新游戏还未开始{this.jcb_fightType.setEnabled(true);this.jcb_playFirst.setEnabled(true);this.jcb_chessColor.setEnabled(true);this.jb_new.setEnabled(true);this.jb_undo.setEnabled(false);this.jb_surrender.setEnabled(false);}}/*** 功能:绘图<br>*/@Overridepublic void paint(Graphics g){//调用父类,让其做一些事前的工作,如刷新屏幕等super.paint(g);//清屏g.setColor(this.getBackground());g.fillRect(this.chessBoradX,this.chessBoradY,this.chessBoradWidth,this.chessBoradHeight);//因为要画一些特殊效果,所以要用Graphics2DGraphics2D g2D = (Graphics2D)g;//开始画棋盘(五子棋盘由15条横线与15条竖线交叉形成,共225个点)//String[] tip = {" 0"," 1"," 2"," 3"," 4"," 5"," 6"," 7"," 8"," 9","10","11","12","13","14"};	//横竖线的坐标,有利于编程是查看定位g2D.setColor(Color.BLACK);g.setFont(new Font("微软雅黑",Font.PLAIN,14));for(int i=0;i<this.chessBoradXGrids;i++){g2D.drawLine(this.chessBoradX,this.chessBoradY + i * this.spaceSize,this.chessBoradX + this.chessBoradWidth,this.chessBoradY + i * this.spaceSize);g2D.drawLine(this.chessBoradX + i * this.spaceSize,this.chessBoradY,this.chessBoradX + i * this.spaceSize,this.chessBoradY + this.chessBoradHeight);//g2D.drawString(tip[i],this.chessBoradX - 20,this.chessBoradY + 4 + i * this.spaceSize);//g2D.drawString(tip[i],this.chessBoradX - 2 + i * this.spaceSize,this.chessBoradY - 10);}//画5个定位点g2D.fillArc(this.chessBoradX + 3 * this.spaceSize - 4,this.chessBoradY + 3 * this.spaceSize - 4,8,8,0,360);g2D.fillArc(this.chessBoradX + 11 * this.spaceSize - 4,this.chessBoradY + 3 * this.spaceSize - 4,8,8,0,360);g2D.fillArc(this.chessBoradX + 7 * this.spaceSize - 4,this.chessBoradY + 7 * this.spaceSize - 4,8,8,0,360);g2D.fillArc(this.chessBoradX + 3 * this.spaceSize - 4,this.chessBoradY + 11 * this.spaceSize - 4,8,8,0,360);g2D.fillArc(this.chessBoradX + 11 * this.spaceSize - 4,this.chessBoradY + 11 * this.spaceSize - 4,8,8,0,360);//画落子指示器if(this.mapPointer.get("show") == 1){g2D.setColor(Color.RED);g2D.setStroke(new BasicStroke(2.5f));//先以交叉点为中心取到指示器周围的4个角坐标//中心点坐标int x = this.chessBoradX + this.mapPointer.get("x") * this.spaceSize;int y = this.chessBoradY + this.mapPointer.get("y") * this.spaceSize;//左上角坐标,并向下向右画线int x1 = x - this.chessSize / 2;int y1 = y - this.chessSize / 2;g2D.drawLine(x1,y1,x1,y1 + this.chessSize / 4);g2D.drawLine(x1,y1,x1 + this.chessSize / 4,y1);//右上角坐标,并向下向左画线x1 = x + this.chessSize / 2;y1 = y - this.chessSize / 2;g2D.drawLine(x1,y1,x1,y1 + this.chessSize / 4);g2D.drawLine(x1,y1,x1 - this.chessSize / 4,y1);//左下角坐标,并向上向右画线x1 = x - this.chessSize / 2;y1 = y + this.chessSize / 2;g2D.drawLine(x1,y1,x1,y1 - this.chessSize / 4);g2D.drawLine(x1,y1,x1 + this.chessSize / 4,y1);//右下角坐标,并向上向左画线x1 = x + this.chessSize / 2;y1 = y + this.chessSize / 2;g2D.drawLine(x1,y1,x1,y1 - this.chessSize / 4);g2D.drawLine(x1,y1,x1 - this.chessSize / 4,y1);//System.out.println("("+this.mapPointer.get("x")+","+this.mapPointer.get("y")+")");}//画棋子(就是一个黑色的圆,里面在接近圆心的位置上画一个由白到黑的渐变内圆)for(int i=0;i<this.listChess.size();i++){Map<String,Integer> map = this.listChess.get(i);int lineX = map.get("x");int lineY = map.get("y");int flag = map.get("flag");//将垂直与水平线的数目转化为像素int x = this.chessBoradX + lineX * this.spaceSize;int y = this.chessBoradY + lineY  * this.spaceSize;//做一个由白到黑渐变的圆绘画RadialGradientPaint paint = null;if(flag == this.WHITECHESS){paint = new RadialGradientPaint(x + 5,y + 5,90, new float[]{0f,1f},new Color[]{Color.WHITE,Color.BLACK});}else{paint = new RadialGradientPaint(x + 3,y + 3,10, new float[]{0f,1f},new Color[]{Color.WHITE,Color.BLACK});}g2D.setPaint(paint);//着色微调g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);	//消除画图锯齿g2D.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT);		//追求速度或质量//画圆,里面套一个白到黑渐变的圆Ellipse2D e = new Ellipse2D.Float(x - this.chessSize/2,y - this.chessSize/2,this.chessSize,this.chessSize);g2D.fill(e);//标记最后一个棋子的红矩形框if(i == this.listChess.size() - 1){g2D.setColor(Color.RED);g2D.setStroke(new BasicStroke(2.5f));g2D.drawRect(x - 5,y - 5,10,10);}}//画五子成线if(this.listChessWin.size() > 4){g2D.setColor(Color.RED);g2D.setStroke(new BasicStroke(2.5f));int x1 = 0;int y1 = 0;for(int i=0;i<this.listChessWin.size();i++){Map<String,Integer> map = this.listChessWin.get(i);if(i == 0)	//先得到第一个点{x1 = map.get("x");y1 = map.get("y");}else	//再用第一个点与其他的点连线{g2D.drawLine(this.chessBoradX + x1 * this.spaceSize,this.chessBoradY + y1 * this.spaceSize,this.chessBoradX + map.get("x") * this.spaceSize,this.chessBoradY +map.get("y") * this.spaceSize);}}}}/*** 功能:开始新游戏<br>*/public void newGame(){//初始化游戏this.initGame();//设置控件状态this.setComponentState(true);//设置游戏结束标识this.isGameOver = false;//电脑先手if(this.fightType == 0 && this.playFirst == 1){this.gameLogic.computerPlay();}}/*** 功能:悔棋<br>*/public void undo(){if(this.gameLogic.undo()){this.repaint();}}/*** 功能:投降<br>*/public void surrender(){if(this.isGameOver){return;}JOptionPane.showMessageDialog(null,"啥,认输了,还能再有点出息不!");this.isGameOver = true;this.setComponentState(false);this.jlb_blackStateText.setText("已结束");this.jlb_whiteStateText.setText("已结束");}/*** 功能:鼠标移动监听<br>*/@Overridepublic void mouseMoved(MouseEvent e){this.gameLogic.mouseMoved(e);}/*** 功能:鼠标单击监听<br>*/@Overridepublic void mouseClicked(MouseEvent e) {this.gameLogic.mouseClicked(e);}/*** 功能:功能监听<br>*/@Overridepublic void actionPerformed(ActionEvent e){String command = e.getActionCommand();if("newGame".equals(command)){this.newGame();}else if("undo".equals(command)){this.undo();}else if("surrender".equals(command)){this.surrender();}}@Overridepublic void mousePressed(MouseEvent e) {}@Overridepublic void mouseReleased(MouseEvent e) {}@Overridepublic void mouseEntered(MouseEvent e) {}@Overridepublic void mouseExited(MouseEvent e) {}@Overridepublic void mouseDragged(MouseEvent e) {}}

        4、GameLogic.java 游戏逻辑类。

package com.game.gobang;import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.awt.event.MouseEvent;
import javax.swing.JOptionPane;/*** 功能:游戏逻辑<br>* 作者:我是小木鱼(Lag)<br>*/
public class GameLogic 
{/** 游戏面板 */private GamePanel gamePanel;/*** 功能:构造函数<br>*/public GameLogic(GamePanel _gamePanel){this.gamePanel = _gamePanel;}/*** 功能:判断下一步是白棋下还是黑棋下<br>*/private int getNextChessColor(){int chessColor = -1;//得到上一步信息if(this.gamePanel.listChess.size() > 0){Map<String,Integer> mapLast = this.gamePanel.listChess.get(this.gamePanel.listChess.size() - 1);if(mapLast.get("flag") == this.gamePanel.BLACKCHESS){chessColor = this.gamePanel.WHITECHESS;}else{chessColor = this.gamePanel.BLACKCHESS;}}else{if(this.gamePanel.fightType == 0)	//人机对战{if(this.gamePanel.playFirst == 0)	//玩家先手{if(this.gamePanel.chessColor == 0){chessColor = this.gamePanel.BLACKCHESS;}else{chessColor = this.gamePanel.WHITECHESS;}}else	//电脑先手(这是不想赢啊){if(this.gamePanel.chessColor == 0){chessColor = this.gamePanel.WHITECHESS;}else{chessColor = this.gamePanel.BLACKCHESS;}}}else	//人人对战{if(this.gamePanel.chessColor == 0){chessColor = this.gamePanel.BLACKCHESS;}else{chessColor = this.gamePanel.WHITECHESS;}}}return chessColor;}/*** 功能:得到X像素所对应的竖线下标<br>*/private int getLineX(int x){//先判断靠哪条竖线近些int lineX = (x - this.gamePanel.chessBoradX + this.gamePanel.spaceSize / 2) / this.gamePanel.spaceSize;//再判断是否在有效范围内int posX = this.gamePanel.chessBoradX + lineX * this.gamePanel.spaceSize;if(x > (posX - this.gamePanel.chessSize / 2) && x < (posX + this.gamePanel.chessSize / 2)){}else{lineX = -1;}return lineX;}/*** 功能:得到Y像素所对应的横线下标<br>*/private int getLineY(int y){//先判断靠哪条竖线近些int lineY = (y - this.gamePanel.chessBoradY + this.gamePanel.spaceSize / 2) / this.gamePanel.spaceSize;//再判断是否在有效范围内int posY = this.gamePanel.chessBoradY + lineY * this.gamePanel.spaceSize;if(y > (posY - this.gamePanel.chessSize / 2) && y < (posY + this.gamePanel.chessSize / 2)){}else{lineY = -1;}return lineY;}/*** 功能:对五元组进行评分<br>*/private int getTupleScore(int _computerChessNum,int _playerChessNum){//1、该五元组中既有电脑的棋子又有玩家的棋子,大家一起完蛋,得0分。if(_computerChessNum > 0 && _playerChessNum > 0){return 0;}//2、该五元组为空,没有棋子,得7分。if(_computerChessNum == 0 && _playerChessNum == 0){return 7;}//3、该五元组中只有1个机器的棋子,其他为空,得35分。(电脑才下一个棋子,可以先看看。【优先级第七】)if(_computerChessNum == 1){return 35;}//4、该五元组中只有2个机器的棋子,其他为空,得800分。(电脑下两个棋子了。【优先级第五】)if(_computerChessNum == 2){return 800;}//5、该五元组中只有3个机器的棋子,其他为空,得15000分。(电脑看到赢的希望了,可以下这个点上,进攻进攻。【优先级第三】)if(_computerChessNum == 3){return 15000;}//6、该五元组中只有4个机器的棋子,其他为空,得800000分。(电脑马上就要赢了,无论如何也必须下这个点上,进攻进攻再进攻。【优先级第一】)if(_computerChessNum == 4){return 800000;}//7、该五元组中只有1个玩家的棋子,其他为空,得15分。(玩家才下一个棋子,别理他。【没优先级】)if(_playerChessNum == 1){return 15;}//8、该五元组中只有2个玩家的棋子,其他为空,得400分。(玩家下两个棋子了。【优先级第六】)if(_playerChessNum == 2){return 800;}//9、该五元组中只有3个玩家的棋子,其他为空,得1800分。(玩家看到赢的希望了,如果电脑没有类似的情况就得堵住这个点,防守防守。【优先级第四】)if(_playerChessNum == 3){return 1800;}//10、该五元组中只有4个玩家的棋子,其他为空,得100000分。(玩家马上就要赢了,如果电脑要是不能立刻赢的话就必须下在这个点上,快防守啊,黑山老妖要来了。【优先级第二】)if(_playerChessNum == 4){return 100000;}return 0;}/*** 功能:得到电脑要下棋的位置<br>*/private Map<String,Integer> getComputerLocation(){//= = = = = = = = = = = = = = = = = = = = 原理 = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =////五子棋要赢,必然要有五个棋子在一起成线,那么我们就把这五格相连的线称之为五元组。                                 		////一般情况下棋盘是15×15的,那么应该共有572个五元组。                                                                	////同时,针对五元组中黑子和白子的数量(可以不考虑相对位置)的不同,给每个五元组评不同的分(每组中的5个点都是同样分数)。    ////然后每一个位置的得分就是包含这个位置的所有五元组的得分之和。                                                    		//      //理论上每个落子点最多被包含在20个五元组中,最少被包含在3个五元组中。然后我们循环整个棋盘,找到评分最多且空的那个点,		////就是电脑要落子的那个点。该点可能用于进攻,也可能用于防守。当然以进攻为主,进攻的评分能更高些。							////在本函数中我要对15×15这225个点进行循环,以这个点为龙头,向右、下、45度斜下、135度斜下共4个方向寻找4个五元组				////(边角的点可能在某些方向不构成五元组),并将这些五元组的评分累计到每个五元组中的5个点里。								////由于只是以这个点为龙头去寻找五元组,因此这个点的累计评分不是最终评分,当再以其他点为龙头时可能会包含这个点,会再给这个	////点累计加分,这样全部循环后该点的评分就准了。再循环整个棋盘,找到评分最高且处于空位的那个点就是电脑要下的点。							////问:一共不是有8个方向吗,为什么只找4个方向就行了?																	////答:因为那4个方向是重复计算了。比如说当你以A点为龙头向右寻找五元组时是(A,A+1,A+2,A+3,A+4)这样的五元组。				////	  但当你以A+4这个点位龙头向左寻找五元组时是(A+4,A+3,A+2,A+1,A)这样的五元组,这不就是重复了嘛。						////	  因此我们总结出寻找规律,向右找就别向左找,向下找就别向上找...。													////= = = = = = = = = = = = = = = = = = = = 结束 = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =	//Map<String,Integer> mapComputer = new HashMap<String,Integer>();int computerChessNum;		//五元组中电脑棋子数目累计int playerChessNum ;		//五元组中玩家棋子数目累计int tupleScore;				//五元组评分值int[][] score = new int[this.gamePanel.chessBoradXGrids][this.gamePanel.chessBoradYGrids];	//棋盘中每个落子交叉点的评分数组int[][] chess = new int[this.gamePanel.chessBoradXGrids][this.gamePanel.chessBoradYGrids];	//棋盘中每个落子交叉点的棋子数组//初始化评分与棋子数组for(int i=0;i<this.gamePanel.chessBoradXGrids;i++){for(int j=0;j<this.gamePanel.chessBoradYGrids;j++){score[i][j] = 0;chess[i][j] = 0;}}//为棋子数组赋值,有利于计算且观察。for(int i=0;i<this.gamePanel.listChess.size();i++){Map<String,Integer> map = this.gamePanel.listChess.get(i);chess[ map.get("x")][ map.get("y")] =  map.get("flag");}//开始循环for(int i=0;i<this.gamePanel.chessBoradXGrids;i++){for(int j=0;j<this.gamePanel.chessBoradYGrids;j++){//1、以该点为龙头向右寻找五元组if(i + 4 <= 14)	//这个五元组真的有{//初始化变量computerChessNum = 0;playerChessNum = 0;tupleScore = 0;//得到该五元组中电脑与玩家的棋子数目for(int k=0;k<5;k++){if(chess[i+k][j] == this.gamePanel.computerChess){computerChessNum++;}if(chess[i+k][j] == this.gamePanel.playerChess){playerChessNum++;}}//得到该五元组的评分tupleScore = this.getTupleScore(computerChessNum,playerChessNum);//将该评分赋值给五元组中的5个点for(int k=0;k<5;k++){score[i+k][j] = score[i+k][j] + tupleScore;}}//2、以该点为龙头向下寻找五元组if(j + 4 <= 14)	//这个五元组真的有{//初始化变量computerChessNum = 0;playerChessNum = 0;tupleScore = 0;//得到该五元组中电脑与玩家的棋子数目for(int k=0;k<5;k++){if(chess[i][j+k] == this.gamePanel.computerChess){computerChessNum++;}if(chess[i][j+k] == this.gamePanel.playerChess){playerChessNum++;}}//得到该五元组的评分tupleScore = this.getTupleScore(computerChessNum,playerChessNum);//将该评分赋值给五元组中的5个点for(int k=0;k<5;k++){score[i][j+k] = score[i][j+k] + tupleScore;}}//3、以该点为龙头135度斜下寻找五元组if(i + 4 <= 14 && j + 4 <= 14)	//这个五元组真的有{//初始化变量computerChessNum = 0;playerChessNum = 0;tupleScore = 0;//得到该五元组中电脑与玩家的棋子数目for(int k=0;k<5;k++){if(chess[i+k][j+k] == this.gamePanel.computerChess){computerChessNum++;}if(chess[i+k][j+k] == this.gamePanel.playerChess){playerChessNum++;}}//得到该五元组的评分tupleScore = this.getTupleScore(computerChessNum,playerChessNum);//将该评分赋值给五元组中的5个点for(int k=0;k<5;k++){score[i+k][j+k] = score[i+k][j+k] + tupleScore;}}//4、以该点为龙头45度斜下寻找五元组if(i - 4 >= 0 && j + 4 <= 14)	//这个五元组真的有{//初始化变量computerChessNum = 0;playerChessNum = 0;tupleScore = 0;//得到该五元组中电脑与玩家的棋子数目for(int k=0;k<5;k++){if(chess[i-k][j+k] == this.gamePanel.computerChess){computerChessNum++;}if(chess[i-k][j+k] == this.gamePanel.playerChess){playerChessNum++;}}//得到该五元组的评分tupleScore = this.getTupleScore(computerChessNum,playerChessNum);//将该评分赋值给五元组中的5个点for(int k=0;k<5;k++){score[i-k][j+k] = score[i-k][j+k] + tupleScore;}}}}//从空位置中找到得分最大的位置int maxScore = 0;int maxX = -1;int maxY = -1;for(int i=0;i<this.gamePanel.chessBoradXGrids;i++){for(int j=0;j<this.gamePanel.chessBoradYGrids;j++){if(chess[i][j] == 0){if(maxScore < score[i][j]){maxScore = score[i][j];maxX = i;maxY = j;}}}}mapComputer.put("x",maxX);mapComputer.put("y",maxY);return mapComputer;}/*** 功能:轮到电脑下棋了br>*/public void computerPlay(){Map<String,Integer> mapComputer = this.getComputerLocation();mapComputer.put("flag",this.gamePanel.computerChess);//棋盘下满了,电脑无棋可下了if(mapComputer.get("x") == -1 || mapComputer.get("y") == -1){JOptionPane.showMessageDialog(null,"牛批,你们竟然打平了!");this.gamePanel.isGameOver = true;this.gamePanel.initGame();return;}if(this.gamePanel.computerChess == this.gamePanel.WHITECHESS){this.gamePanel.listChessWhite.add(mapComputer);}else{this.gamePanel.listChessBlack.add(mapComputer);}this.gamePanel.listChess.add(mapComputer);//延时一会再刷新,要不显得电脑太厉害了。try {Thread.sleep(50);} catch(Exception e1){e1.printStackTrace();}this.gamePanel.repaint();}/*** 功能:判断游戏是否结束<br>*/private boolean gameOver(){int hCount = 0;							//水平计数int vCount = 0;							//垂直计数int a45Count = 0;						//斜45度计数int a135Count = 0;						//斜135度计数boolean isFind = false;					//是否找到List<Map<String,Integer>> hChessWin = new ArrayList<Map<String,Integer>>();		//记录水平方向上的5个点连成线List<Map<String,Integer>> vChessWin = new ArrayList<Map<String,Integer>>();		//记录垂直方向上的5个点连成线List<Map<String,Integer>> a45ChessWin = new ArrayList<Map<String,Integer>>();	//记录斜45度方向上的5个点连成线List<Map<String,Integer>> a135ChessWin = new ArrayList<Map<String,Integer>>();	//记录斜135度方向上的5个点连成线if(this.gamePanel.listChess.size() < 1){return false;}//得到最后一步下棋信息Map<String,Integer> mapLast = this.gamePanel.listChess.get(this.gamePanel.listChess.size() - 1);int x = mapLast.get("x");int y = mapLast.get("y");int flag = mapLast.get("flag");List<Map<String,Integer>> listTmp ;if(flag == this.gamePanel.WHITECHESS){listTmp = this.gamePanel.listChessWhite;}else{listTmp = this.gamePanel.listChessBlack;}//水平(先向右数4个)for(int i=1;i<5;i++){isFind = false;for(int j=0;j<listTmp.size();j++){Map<String,Integer> map = listTmp.get(j);if(map.get("x") == (x + i) && map.get("y") == y){hChessWin.add(map);isFind = true;}}if(isFind){hCount++;}else{break;}}//水平(向左数4个)for(int i=1;i<5;i++){isFind = false;for(int j=0;j<listTmp.size();j++){Map<String,Integer> map = listTmp.get(j);if(map.get("x") == (x - i) && map.get("y") == y){hChessWin.add(map);isFind = true;}}if(isFind){hCount++;}else{break;}}//垂直(向上数4个)for(int i=1;i<5;i++){isFind = false;for(int j=0;j<listTmp.size();j++){Map<String,Integer> map = listTmp.get(j);if(map.get("x") == x && map.get("y") == (y - i)){vChessWin.add(map);isFind = true;}}if(isFind){vCount++;}else{break;}}//垂直(向下数4个)for(int i=1;i<5;i++){isFind = false;for(int j=0;j<listTmp.size();j++){Map<String,Integer> map = listTmp.get(j);if(map.get("x") == x && map.get("y") == (y + i)){vChessWin.add(map);isFind = true;}}if(isFind){vCount++;}else{break;}}//45度斜线(向右上方数4个)for(int i=1;i<5;i++){isFind = false;for(int j=0;j<listTmp.size();j++){Map<String,Integer> map = listTmp.get(j);if(map.get("x") == (x + i) && map.get("y") == (y - i)){a45ChessWin.add(map);isFind = true;}}if(isFind){a45Count++;}else{break;}}//45度斜线(向左下方数4个)for(int i=1;i<5;i++){isFind = false;for(int j=0;j<listTmp.size();j++){Map<String,Integer> map = listTmp.get(j);if(map.get("x") == (x - i) && map.get("y") == (y + i)){a45ChessWin.add(map);isFind = true;}}if(isFind){a45Count++;}else{break;}}//135度斜线(向左上方数4个)for(int i=1;i<5;i++){isFind = false;for(int j=0;j<listTmp.size();j++){Map<String,Integer> map = listTmp.get(j);if(map.get("x") == (x - i) && map.get("y") == (y - i)){a135ChessWin.add(map);isFind = true;}}if(isFind){a135Count++;}else{break;}}//135度斜线(向右下方数4个)for(int i=1;i<5;i++){isFind = false;for(int j=0;j<listTmp.size();j++){Map<String,Integer> map = listTmp.get(j);if(map.get("x") == (x + i) && map.get("y") == (y + i)){a135ChessWin.add(map);isFind = true;}}if(isFind){a135Count++;}else{break;}}//开始判断if(hCount >= 4 || vCount >= 4 || a45Count >= 4 || a135Count >= 4){//记录五子连线if(hChessWin.size() == 4){hChessWin.add(mapLast);this.gamePanel.listChessWin = hChessWin;}else if(vChessWin.size() == 4){vChessWin.add(mapLast);this.gamePanel.listChessWin = vChessWin;}else if(a45ChessWin.size() == 4){a45ChessWin.add(mapLast);this.gamePanel.listChessWin = a45ChessWin;}else if(a135ChessWin.size() == 4){a135ChessWin.add(mapLast);this.gamePanel.listChessWin = a135ChessWin;}if(this.gamePanel.fightType == 0)	//人机对战{if(flag == this.gamePanel.computerChess){JOptionPane.showMessageDialog(null,"我去,你怎么连电脑都输啊!","提示",JOptionPane.ERROR_MESSAGE);}else{JOptionPane.showMessageDialog(null,"恭喜,你终于赢电脑一把了!");}return true;}else	//人人对战{if(flag == this.gamePanel.WHITECHESS){JOptionPane.showMessageDialog(null,"恭喜,白棋赢了!");}else{JOptionPane.showMessageDialog(null,"恭喜,黑棋赢了!");}return true;}}return false;}/*** 功能:悔棋<br>*/public boolean undo(){if(this.gamePanel.isGameOver){return false;}if(this.gamePanel.listChess.size() < 1){return false;}//得到最后一步棋信息Map<String,Integer> mapLast = this.gamePanel.listChess.get(this.gamePanel.listChess.size() - 1);int flag = mapLast.get("flag");if(this.gamePanel.fightType == 0)	//人机对战(只有玩家才会悔棋,电脑才不会这么耍赖){if(this.gamePanel.chessColor == 0){if(this.gamePanel.blackUndoNum == 0){JOptionPane.showMessageDialog(null,"悔棋次数已经全部用完了!","提示",JOptionPane.INFORMATION_MESSAGE);return false;}this.gamePanel.listChessBlack.remove(this.gamePanel.listChessBlack.size() - 1);this.gamePanel.listChess.remove(this.gamePanel.listChess.size() - 1);this.gamePanel.listChess.remove(this.gamePanel.listChess.size() - 1);this.gamePanel.blackUndoNum--;}else{if(this.gamePanel.whiteUndoNum == 0){JOptionPane.showMessageDialog(null,"悔棋次数已经全部用完了!","提示",JOptionPane.INFORMATION_MESSAGE);return false;}this.gamePanel.listChessWhite.remove(this.gamePanel.listChessWhite.size() - 1);this.gamePanel.listChess.remove(this.gamePanel.listChess.size() - 1);this.gamePanel.listChess.remove(this.gamePanel.listChess.size() - 1);this.gamePanel.whiteUndoNum--;}}else{if(flag == this.gamePanel.WHITECHESS){if(this.gamePanel.whiteUndoNum == 0){JOptionPane.showMessageDialog(null,"白棋的悔棋次数已经全部用完了!","提示",JOptionPane.INFORMATION_MESSAGE);return false;}this.gamePanel.listChessWhite.remove(this.gamePanel.listChessWhite.size() - 1);this.gamePanel.listChess.remove(this.gamePanel.listChess.size() - 1);this.gamePanel.whiteUndoNum--;}else{if(this.gamePanel.blackUndoNum == 0){JOptionPane.showMessageDialog(null,"黑棋的悔棋次数已经全部用完了!","提示",JOptionPane.INFORMATION_MESSAGE);return false;}this.gamePanel.listChessBlack.remove(this.gamePanel.listChessBlack.size() - 1);this.gamePanel.listChess.remove(this.gamePanel.listChess.size() - 1);this.gamePanel.blackUndoNum--;}}this.gamePanel.jlb_blackUndoText.setText("剩"+gamePanel.blackUndoNum+"次");this.gamePanel.jlb_whiteUndoText.setText("剩"+gamePanel.whiteUndoNum+"次");return true;}/*** 功能:鼠标移动事件<br>*/public void mouseMoved(MouseEvent e){//判断鼠标位置是否在棋盘内int x = e.getX();int y = e.getY();if(x > (this.gamePanel.chessBoradX - this.gamePanel.spaceSize / 2) && x < (this.gamePanel.chessBoradX + this.gamePanel.chessBoradWidth + this.gamePanel.spaceSize/2) && y > (this.gamePanel.chessBoradY - this.gamePanel.spaceSize / 2) && y < (this.gamePanel.chessBoradY + this.gamePanel.chessBoradHeight + this.gamePanel.spaceSize / 2)){if(this.gamePanel.isGameOver){return;}//清除落子指示器(先不显示)this.gamePanel.mapPointer.put("show",0);//将x,y由像素改为相应的水平与垂直线的数目(0~14)int lineX = this.getLineX(x);int lineY = this.getLineY(y);if(lineX >= 0 && lineX < 15 && lineY >= 0 && lineY < 15){//判断该位置是否有棋子boolean isChess = false;for(int i=0;i<this.gamePanel.listChess.size();i++){Map<String,Integer> map = this.gamePanel.listChess.get(i);if(map.get("x") == lineX && map.get("y") == lineY){isChess = true;break;}}if(!isChess)	//可以显示了{this.gamePanel.mapPointer.put("x",lineX);this.gamePanel.mapPointer.put("y",lineY);this.gamePanel.mapPointer.put("show",1);}}this.gamePanel.repaint();}else{if(this.gamePanel.mapPointer.get("show") == 1){this.gamePanel.mapPointer.put("show",0);this.gamePanel.repaint();}}}	/*** 功能:鼠标单击事件<br>*/public void mouseClicked(MouseEvent e) {if(e.getButton() == MouseEvent.BUTTON1)		//鼠标左键点击{//判断鼠标位置是否在棋盘内int x = e.getX();int y = e.getY();if(x > (this.gamePanel.chessBoradX - this.gamePanel.spaceSize / 2) && x < (this.gamePanel.chessBoradX + this.gamePanel.chessBoradWidth + this.gamePanel.spaceSize/2) && y > (this.gamePanel.chessBoradY - this.gamePanel.spaceSize / 2) && y < (this.gamePanel.chessBoradY + this.gamePanel.chessBoradHeight + this.gamePanel.spaceSize / 2)){if(this.gamePanel.isGameOver){return;}//将x,y由像素改为相应的水平与垂直线的数目(0~14)int lineX = this.getLineX(x);int lineY = this.getLineY(y);if(lineX >= 0 && lineX < 15 && lineY >= 0 && lineY < 15){//判断该位置是否有棋子boolean isChess = false;for(int i=0;i<this.gamePanel.listChess.size();i++){Map<String,Integer> map = this.gamePanel.listChess.get(i);if(map.get("x") == lineX && map.get("y") == lineY){isChess = true;break;}}if(!isChess)	//玩家可以下棋了{//清除落子指示器this.gamePanel.mapPointer.put("show",0);//得到下一步是白棋下还是黑棋int chessColor = this.getNextChessColor();//记录玩家下棋Map<String,Integer> mapMan = new HashMap<String,Integer>();mapMan.put("x",lineX);mapMan.put("y",lineY);mapMan.put("flag",chessColor);if(chessColor == this.gamePanel.WHITECHESS){this.gamePanel.listChessWhite.add(mapMan);this.gamePanel.jlb_whiteStateText.setText("已下完");this.gamePanel.jlb_blackStateText.setText("思考中");}else{this.gamePanel.listChessBlack.add(mapMan);this.gamePanel.jlb_blackStateText.setText("已下完");this.gamePanel.jlb_whiteStateText.setText("思考中");}this.gamePanel.listChess.add(mapMan);this.gamePanel.repaint();//判断游戏是否结束if(this.gameOver()){this.gamePanel.isGameOver = true;this.gamePanel.setComponentState(false);this.gamePanel.jlb_blackStateText.setText("已结束");this.gamePanel.jlb_whiteStateText.setText("已结束");return;}//判断双方是否战平(棋盘下满了)if(this.gamePanel.listChess.size() >= 225){JOptionPane.showMessageDialog(null,"牛屁,你们竟然打平了!");this.gamePanel.isGameOver = true;this.gamePanel.initGame();return;}//如果是人机对战,机器要回应啊if(this.gamePanel.fightType == 0)	//人机对战{this.computerPlay();if(this.gamePanel.computerChess == this.gamePanel.BLACKCHESS){this.gamePanel.jlb_blackStateText.setText("已下完");this.gamePanel.jlb_whiteStateText.setText("思考中");}else{this.gamePanel.jlb_whiteStateText.setText("已下完");this.gamePanel.jlb_blackStateText.setText("思考中");}//判断游戏是否结束if(this.gameOver()){this.gamePanel.isGameOver = true;this.gamePanel.setComponentState(false);this.gamePanel.jlb_blackStateText.setText("已结束");this.gamePanel.jlb_whiteStateText.setText("已结束");return;}}}}}}}}

详解: 

待续...

运行: 

        做一个DOS批处理文件,gobang.bat,内容如下:

@echo off
start javaw com.game.gobang.Gobang

 下载: 

        百度网盘链接:https://pan.baidu.com/s/1jMU7es839gLtW6XXVFNMqw 提取码:ibkq

感言: 

待续...


http://chatgpt.dhexx.cn/article/VBZ6fLDc.shtml

相关文章

编程小游戏之三子棋

三子棋是一个民间的益智小游戏&#xff0c;游戏分为双方对战&#xff0c;双方依次在9宫格棋盘上摆放棋子&#xff0c;率先将自己的三个棋子连成一条线的一方则视为胜利者。下面将说明如何利用C语言在我们的计算机上简单的实现三子棋。 1.逻辑框架设计 在vs上创建两个.c文件test…

【C语言】三子棋游戏的实现(玩家VS玩家 or 玩家VS电脑)

目 录 一、三子棋游戏介绍 二、游戏功能函数分析 1 菜单显示函数 2 菜单选择函数 3 选择确认函数 4 显示当前棋盘状态函数 5 棋盘初始化函数 6 玩家下棋函数 7 电脑下棋函数 8 棋局状态判断函数 三、游戏功能函数的整合 四、三子棋游戏的实现 五、游戏…

安卓做的棋类游戏

大方大斜 前言一、直接上图二、游戏主要代码1.界面绘制代码2.游戏触摸事件代码 最后 前言 安卓制作棋类游戏&#xff0c;小时候和发小在地上画棋盘&#xff0c;有树叶或者树枝做棋子。 一、直接上图 二、游戏主要代码 1.界面绘制代码 双人界面绘制&#xff0c;主要代码代码如…

基于java的五子棋游戏设计

技术&#xff1a;Java、JSP等摘要&#xff1a;随着互联网迅速的发展&#xff0c;网络游戏已经成为人们普遍生活中不可或缺的一部分&#xff0c;它不仅能使人娱乐&#xff0c;也能够开发人的智力&#xff0c;就像本文所主要讲的五子棋游戏一样能挖掘人们聪明的才干与脑袋的机灵程…

自己设计的棋类游戏

1、构思&#xff1a; 象棋、国际象棋、井字棋等 我一开始的设计是这个样的&#xff1a;一个5x5的棋盘&#xff08;之后变成7x7&#xff09;&#xff0c;所有棋子摆成一个井字 棋子有两种&#xff0c;一种兵一种王&#xff0c;中间用中立的棋子&#xff0c;就叫box来隔开他们 …

Java围棋游戏的设计与实现

技术&#xff1a;Java等 摘要&#xff1a; 围棋作为一个棋类竞技运动&#xff0c;在民间十分流行&#xff0c;为了熟悉五子棋规则及技巧&#xff0c;以及研究简单的人工智能&#xff0c;决定用Java开发五子棋游戏。主要完成了人机对战和玩家之间联网对战2个功能。网络连接部分为…

【国际象棋】棋盘游戏-微信小程序开发流程详解

与中国象棋类似的&#xff0c;还有国际象棋&#xff0c;知道有人爱玩&#xff0c;于是凭着好奇心&#xff0c;网上研究了一下&#xff0c;跟中国象棋有相似之处&#xff0c;玩法是有些许不一样&#xff0c;不知道象棋最早出于谁之手呢&#xff0c;抽空做一做&#xff0c;最终完…

利用C语言巧妙实现棋类游戏——三子棋

小游戏&#xff1a;三子棋用C语言实现 你是否学完了C语言的函数、数组、选择结构、循环结构苦于没有实战小项目巩固自己所学的知识呢&#xff0c;今天小程序猿就给大家带来了一个游戏的小游戏——三子棋&#xff0c;利用C语言实现的&#xff0c;希望对大家能有所帮助。 我们大家…

基于C#的五子棋游戏设计

目 录 一、 毕业设计内容 3 二、 毕业设计目的 3 三、 工具/准备工作 3 四、 设计步骤和方法 3 &#xff08;一&#xff09; 总体设计 3 1&#xff0e; 总体设计思路及设计图 3 2&#xff0e; 界面设计 4 3&#xff0e; 全局变量设计 4 &#xff08;二&#xff09; 详细设计 5 …

【Unity连载】斗兽棋-棋类游戏开发演示(2)

第四章 游戏操作与指令 如同养育一个婴儿&#xff0c;父母总会一步步引领孩子成长&#xff0c;从蹒跚学步到来去如风&#xff1b;我们对游戏功能的开发&#xff0c;也无疑应当从走出第一步棋开始。现在&#xff0c;我们已经构建出了棋盘、棋子等基本的游戏逻辑对象&#xff1b…

Java游戏开发——中国象棋联机版

游戏介绍&#xff1a; 中国象棋是起源于中国的一种棋戏&#xff0c;属于二人对抗性游戏的一种&#xff0c;在中国有着悠久的历史。由于规则简单&#xff0c;趣味性强&#xff0c;成为流行极为广泛的棋类游戏。 中国象棋使用方形格状棋盘及红黑二色圆形棋子进行对弈&#xff0c…

【论文】word中三线表的快速简单制作

【论文】word中三线表的快速简单制作 首先&#xff0c;打开word点击插入→表格&#xff0c;选择需要插入表格的行列数&#xff0c;行列数没有关系&#xff0c;因为你插入后可以随意添加行列。 则插入了一下表格&#xff1a; 把你所需要的数据放进去&#xff1a; 之后&#…

如何在word中制作线宽不同的三线表

在word中难免会插入特定的三线表&#xff0c;那就现场给给大家演示一遍 1、打开word&#xff0c;点击插入&#xff0c;点击表格&#xff0c;至于插入几行几列看自己的需求哈。 2、右键点击表格&#xff0c;然后点击表格属性 3、点击边框和底纹&#xff0c;对表格去除相关边线 …

论文中的三线表绘制(word)

步骤 1、选中表格&#xff08;点击下图中的红框部分选中&#xff09; 2、右击表格选择“表格属性” 3、点击边框和底纹&#xff0c;再选择无边框&#xff08;先不要点确定&#xff09; 4、设置三线表的上下边框&#xff08;1.5磅&#xff09;&#xff0c;完成下图之后点击确定-…

word三线表标题两条线之间如何出现空白间隔(论文必备)

为了写论文&#xff0c;我需要把以上的标题转换成下图所示的样子 所实现的步骤如下&#xff1a; 1、把标题内容回车 放在下一行 2、加一条绘制表格的线 3、选中第一行对应位置的两格&#xff0c;合并单元格 并填入内容 可以看到单纯的加上边框&#xff0c;两条线之间是没有空…

Word 2016表格三线表制作

1、打开word&#xff0c;点击插入&#xff0c;插入一个表格。 2、选中表格&#xff0c;点击设计&#xff0c;在边框中的笔画粗细选择1.5磅&#xff0c;然后在边框下拉框先选择无框线&#xff0c;再选择上框线和下框线。然后笔画粗细选择0.5磅&#xff0c;选中第一行后&#x…

三线表的制作

目录 前言参考过程 前言 最近在写些东西的时候&#xff0c;需要用到三线表&#xff0c;上网查了一下&#xff0c;将方法记录下来。 参考 三分钟快速制作论文三线表 过程 (1) 先插入一个表格&#xff0c;然后新建一个表格样式 (2) 如下图所示更改 (3) 点击第二步中的格式&a…

word表格跨页多出一根线(三线表)

在word中做三线表&#xff0c;表格跨页了自动在页底部加一横线&#xff0c;下一页页首加一横线这个怎么去掉么 首先感谢上方在知乎给出解决方案的博主&#xff0c; 接着&#xff1a;文中描述大概操作如下&#xff1a; 如果还是不行&#xff0c;那么就拿来dou一个三线表

Word插入三线表

在Word中插入一个三线表&#xff0c;方法如下所示&#xff1a; 一、先插入一个正常的表格&#xff0c;并输入好相应的数据 二、单击表格的左上角按钮&#xff0c;选中整个表格 选中表格之后&#xff0c;【右键】-【表格属性】&#xff0c;在弹出的表格属性对话框中单击【边框与…

在Word文档中插入三线表

在Word文档中插入三线表 ①插入一个适合你的文字安排的表格 例如&#xff0c;我要如下情况的示例; 则插入一个五行两列的表格并输入数据; 输完数据之后可以全选表格设置字体 全选表格——边框——边框和底纹&#xff1a; 然后按照下列设置&#xff1a; 结果如下; 然后再…