[Java] 五子棋 →→→→→进入此内容的聊天室

来自 , 2020-01-15, 写在 Java, 查看 105 次.
URL http://www.code666.cn/view/3bbfdde8
  1. 第一个文件:
  2. import javax.swing.*;
  3. import java.awt.event.*;
  4. import java.awt.*;
  5. /*
  6. 五子棋-主框架类, 程序启动类
  7.  */
  8. public class StartChessJFrame extends JFrame {
  9.     private ChessBoard chessBoard;//对战面板
  10.     private JPanel toolbar;//工具条面板
  11.          
  12.     private JButton startButton, backButton, exitButton;
  13.     //重新开始按钮,悔棋按钮,和退出按钮
  14.      
  15.     private JMenuBar menuBar;//菜单栏
  16.     private JMenu sysMenu;//系统菜单
  17.     private JMenuItem startMenuItem, exitMenuItem, backMenuItem;
  18.     //重新开始,退出,和悔棋菜单项  
  19.      
  20.     public StartChessJFrame() {
  21.         setTitle("单机版五子棋");//设置标题
  22.         chessBoard = new ChessBoard();//初始化面板对象
  23.         // 创建和添加菜单
  24.         menuBar = new JMenuBar();//初始化菜单栏
  25.         sysMenu = new JMenu("系统");//初始化菜单
  26.         startMenuItem = new JMenuItem("重新开始");
  27.         exitMenuItem = new JMenuItem("退出");
  28.         backMenuItem = new JMenuItem("悔棋");//初始化菜单项
  29.         sysMenu.add(startMenuItem);//将三个菜单项添加到菜单上
  30.         sysMenu.add(backMenuItem);
  31.         sysMenu.add(exitMenuItem);
  32.         MyItemListener lis = new MyItemListener();//初始化按钮事件监听器内部类
  33.         this.startMenuItem.addActionListener(lis);//将三个菜单项注册到事件监听器上
  34.         backMenuItem.addActionListener(lis);
  35.         exitMenuItem.addActionListener(lis);
  36.  
  37.         menuBar.add(sysMenu);//将系统菜单添加到菜单栏上
  38.         setJMenuBar(menuBar);// 将menuBar设置为菜单栏
  39.  
  40.         toolbar = new JPanel();//工具面板栏实例化
  41.         startButton = new JButton("重新开始");//三个按钮初始化
  42.         backButton = new JButton("悔棋");
  43.         exitButton = new JButton("退出");
  44.         toolbar.setLayout(new FlowLayout(FlowLayout.LEFT));//将工具面板按钮用FlowLayout布局
  45.         toolbar.add(startButton);//将三个按钮添加到工具面板上
  46.         toolbar.add(backButton);
  47.         toolbar.add(exitButton);
  48.         startButton.addActionListener(lis);//将三个按钮注册监听事件
  49.         backButton.addActionListener(lis);
  50.         exitButton.addActionListener(lis);
  51.         add(toolbar, BorderLayout.SOUTH);//将工具面板布局到界面"南"方也就是下面
  52.         add(chessBoard);//将面板对象添加到窗体上
  53.         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置界面关闭事件
  54.         //setSize(800,800);
  55.         pack(); // 自适应大小
  56.     }
  57.  
  58.     private class MyItemListener implements ActionListener {//事件监听器内部类
  59.  
  60.         public void actionPerformed(ActionEvent e) {
  61.             Object obj = e.getSource(); // 取得事件源
  62.             if (obj == StartChessJFrame.this.startMenuItem || obj == startButton) {
  63.                 // 重新开始
  64.               // JFiveFrame.this内部类引用外部类
  65.                 System.out.println("重新开始...");
  66.                 chessBoard.restartGame();
  67.  
  68.             } else if (obj == exitMenuItem || obj == exitButton) {
  69.                 System.exit(0); // 结束应用程序
  70.             } else if (obj == backMenuItem || obj == backButton) { // 悔棋
  71.                 System.out.println("悔棋...");
  72.                 chessBoard.goback();
  73.             }
  74.         }
  75.     }
  76.     public static void main(String[] args) {
  77.         StartChessJFrame f = new StartChessJFrame(); // 创建主框架
  78.         f.setVisible(true); // 显示主框架
  79.     }
  80. }
  81.  
  82. 第二个文件:
  83. import java.awt.Color;
  84.  
  85. /*五子棋的棋子设计。
  86.  */
  87. public class Point {
  88.     private int x; // 棋盘中的x索引
  89.     private int y; // 棋盘中的y索引
  90.     private Color color;//颜色
  91.     public static final int DIAMETER = 30;//直径
  92.     public Point(int x, int y, Color color) {
  93.         this.x = x;
  94.         this.y = y;
  95.         this.color = color;
  96.     }
  97.     public int getX() {// 拿到棋盘中的x索引
  98.         return x;
  99.     }
  100.     public int getY() {// 拿到棋盘中的Y索引
  101.         return y;
  102.     }
  103.     public Color getColor() {//得到颜色
  104.         return color;
  105.     }
  106. }
  107.  
  108. 第三个文件:
  109. import javax.swing.*;
  110. import java.awt.*;
  111. import java.awt.event.MouseListener;
  112. import java.awt.event.MouseMotionListener;
  113. import java.awt.event.MouseEvent;
  114. /*
  115.  
  116.  五子棋-棋盘类
  117.  */
  118. public class ChessBoard extends JPanel implements MouseListener {
  119.     public static final int MARGIN = 30; // 边距
  120.     public static final int GRID_SPAN = 35; // 网格间距
  121.     public static final int ROWS = 15;//棋盘行数
  122.     public static final int COLS = 15;//棋盘列数
  123.  
  124.     Point[] chessList = new Point[(ROWS + 1) * (COLS + 1)]; // 初始每个数组元素为null
  125.     boolean isBlack = true;//默然开始是黑棋先下
  126.     boolean gameOver = false;// 游戏是否结束
  127.     int chessCount; // 当前棋盘的棋子个数
  128.     int xIndex, yIndex; // 当前刚下的棋子的索引
  129.  
  130.     public ChessBoard() {
  131.         setBackground(Color.ORANGE);//设置背景颜色为橘黄色
  132.         addMouseListener(this);// 添加监听器
  133.         addMouseMotionListener(new MouseMotionListener() { // 匿名内部类
  134.             public void mouseDragged(MouseEvent e) {
  135.             }
  136.  
  137.             public void mouseMoved(MouseEvent e) {
  138.                 int x1 = (e.getX() - MARGIN + GRID_SPAN / 2) / GRID_SPAN;
  139.                 // 将鼠标点击的坐标位置转换成网格索引。
  140.                 int y1 = (e.getY() - MARGIN + GRID_SPAN / 2) / GRID_SPAN;
  141.                 // 游戏已经结束,不能下
  142.                 // 落在棋盘外,不能下
  143.                 // x,y位置已经有棋子存在,不能下
  144.                 if (x1 < 0 || x1 > ROWS || y1 < 0 || y1 > COLS || gameOver
  145.                         || findChess(x1, y1))
  146.                     setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); // 设置成默认形状
  147.                 else
  148.                     setCursor(new Cursor(Cursor.HAND_CURSOR)); // 设置成手型
  149.             }
  150.         });
  151.     }
  152.  
  153.     // 绘制
  154.     public void paintComponent(Graphics g) {
  155.         super.paintComponent(g);
  156.         // 画棋盘
  157.         for (int i = 0; i <= ROWS; i++) { // 画横线
  158.             g.drawLine(MARGIN, MARGIN + i * GRID_SPAN, MARGIN + COLS
  159.                     * GRID_SPAN, MARGIN + i * GRID_SPAN);
  160.         }
  161.         for (int i = 0; i <= COLS; i++) {// 画直线
  162.             g.drawLine(MARGIN + i * GRID_SPAN, MARGIN, MARGIN + i * GRID_SPAN,
  163.                     MARGIN + ROWS * GRID_SPAN);
  164.         }
  165.         // 画棋子
  166.         for (int i = 0; i < chessCount; i++) {
  167.             int xPos = chessList[i].getX() * GRID_SPAN + MARGIN; // 网格交叉点的x坐标
  168.             int yPos = chessList[i].getY() * GRID_SPAN + MARGIN;// 网格交叉点的y坐标
  169.             g.setColor(chessList[i].getColor()); // 设置颜色
  170.             g.fillOval(xPos - Point.DIAMETER / 2, yPos - Point.DIAMETER / 2,
  171.                     Point.DIAMETER, Point.DIAMETER);
  172.             // 标记最后一个棋子的红矩形框
  173.             if (i == chessCount - 1) { // 最后一个棋子
  174.                 g.setColor(Color.red);
  175.                 g.drawRect(xPos - Point.DIAMETER / 2,
  176.                         yPos - Point.DIAMETER / 2, Point.DIAMETER,
  177.                         Point.DIAMETER);
  178.             }
  179.         }
  180.  
  181.     }
  182.  
  183.     public void mousePressed(MouseEvent e) {// 鼠标按键在组件上按下时调用。
  184.         // 游戏已经结束,不能下
  185.         if (gameOver)
  186.             return;
  187.         String colorName = isBlack ? "黑棋" : "白棋";
  188.  
  189.         xIndex = (e.getX() - MARGIN + GRID_SPAN / 2) / GRID_SPAN; // 将鼠标点击的坐标位置转换成网格索引。
  190.         yIndex = (e.getY() - MARGIN + GRID_SPAN / 2) / GRID_SPAN;
  191.  
  192.         // 落在棋盘外,不能下
  193.         if (xIndex < 0 || xIndex > ROWS || yIndex < 0 || yIndex > COLS)
  194.             return;
  195.         // x,y位置已经有棋子存在,不能下
  196.         if (findChess(xIndex, yIndex))
  197.             return;
  198.  
  199.         Point ch = new Point(xIndex, yIndex, isBlack ? Color.black: Color.white);
  200.         chessList[chessCount++] = ch;
  201.         repaint(); // 通知系统重新绘制
  202.         if (isWin()) {
  203.             // 给出胜利信息,不能再继续下棋
  204.             String msg = String.format("恭喜,%s赢了!", colorName);
  205.             JOptionPane.showMessageDialog(this, msg);
  206.             gameOver = true;
  207.         }
  208.         isBlack = !isBlack;
  209.     }
  210.  
  211.     // 覆盖MouseListener的方法
  212.     public void mouseClicked(MouseEvent e) {
  213.     } // 鼠标按键在组件上单击(按下并释放)时调用。
  214.  
  215.     public void mouseEntered(MouseEvent e) {
  216.     }// 鼠标进入到组件上时调用。
  217.  
  218.     public void mouseExited(MouseEvent e) {
  219.     }// 鼠标离开组件时调用。
  220.  
  221.     public void mouseReleased(MouseEvent e) {
  222.     } // 鼠标按钮在组件上释放时调用。
  223.  
  224.     // 在棋子数组中查找是否有索引为x,y的棋子存在
  225.     private boolean findChess(int x, int y) {
  226.         for (Point c : chessList) {
  227.             if (c != null && c.getX() == x && c.getY() == y)
  228.                 return true;
  229.         }
  230.         return false;
  231.     }
  232.  
  233.     private boolean isWin() {//判断那方赢
  234.         int continueCount = 1; // 连续棋子的个数
  235.         // 横向向西寻找
  236.         for (int x = xIndex - 1; x >= 0; x--) {
  237.             Color c = isBlack ? Color.black : Color.white;
  238.             if (getChess(x, yIndex, c) != null) {
  239.                 continueCount++;
  240.             } else
  241.                 break;
  242.         }
  243.         // 横向向东寻找
  244.         for (int x = xIndex + 1; x <= ROWS; x++) {
  245.             Color c = isBlack ? Color.black : Color.white;
  246.             if (getChess(x, yIndex, c) != null) {
  247.                 continueCount++;
  248.             } else
  249.                 break;
  250.         }
  251.         if (continueCount >= 5) {
  252.             return true;
  253.         } else
  254.             continueCount = 1;
  255.  
  256.         // 继续另一种情况的搜索: 纵向
  257.         // 纵向向上寻找
  258.         for (int y = yIndex - 1; y >= 0; y--) {
  259.             Color c = isBlack ? Color.black : Color.white;
  260.             if (getChess(xIndex, y, c) != null) {
  261.                 continueCount++;
  262.             } else
  263.                 break;
  264.         }
  265.         // 纵向向下寻找
  266.         for (int y = yIndex + 1; y <= ROWS; y++) {
  267.             Color c = isBlack ? Color.black : Color.white;
  268.             if (getChess(xIndex, y, c) != null) {
  269.                 continueCount++;
  270.             } else
  271.                 break;
  272.         }
  273.         if (continueCount >= 5) {
  274.             return true;
  275.         } else
  276.             continueCount = 1;
  277.  
  278.         // 继续另一种情况的搜索: 斜向
  279.         // 东北寻找
  280.         for (int x = xIndex + 1, y = yIndex - 1; y >= 0 && x <= COLS; x++, y--) {
  281.             Color c = isBlack ? Color.black : Color.white;
  282.             if (getChess(x, y, c) != null) {
  283.                 continueCount++;
  284.             } else
  285.                 break;
  286.         }
  287.         // 西南寻找
  288.         for (int x = xIndex - 1, y = yIndex + 1; y <= ROWS && x >= 0; x--, y++) {
  289.             Color c = isBlack ? Color.black : Color.white;
  290.             if (getChess(x, y, c) != null) {
  291.                 continueCount++;
  292.             } else
  293.                 break;
  294.         }
  295.         if (continueCount >= 5) {
  296.             return true;
  297.         } else
  298.             continueCount = 1;
  299.  
  300.         // 继续另一种情况的搜索: 斜向
  301.         // 西北寻找
  302.         for (int x = xIndex - 1, y = yIndex - 1; y >= 0 && x >= 0; x--, y--) {
  303.             Color c = isBlack ? Color.black : Color.white;
  304.             if (getChess(x, y, c) != null) {
  305.                 continueCount++;
  306.             } else
  307.                 break;
  308.         }
  309.         // 西南寻找
  310.         for (int x = xIndex + 1, y = yIndex + 1; y <= ROWS && x <= COLS; x++, y++) {
  311.             Color c = isBlack ? Color.black : Color.white;
  312.             if (getChess(x, y, c) != null) {
  313.                 continueCount++;
  314.             } else
  315.                 break;
  316.         }
  317.         if (continueCount >= 5) {
  318.             return true;
  319.         } else
  320.             continueCount = 1;
  321.  
  322.         return false;
  323.     }
  324.  
  325.     private Point getChess(int xIndex, int yIndex, Color color) {
  326.         for (Point c : chessList) {
  327.             if (c != null && c.getX() == xIndex && c.getY() == yIndex
  328.                     && c.getColor() == color)
  329.                 return c;
  330.         }
  331.         return null;
  332.     }
  333.  
  334.     public void restartGame() {
  335.         // 清除棋子
  336.         for (int i = 0; i < chessList.length; i++)
  337.             chessList[i] = null;
  338.         // 恢复游戏相关的变量值
  339.         isBlack = true;
  340.         gameOver = false;// 游戏是否结束
  341.         chessCount = 0; // 当前棋盘的棋子个数
  342.         repaint();
  343.  
  344.     }
  345.  
  346.     // 悔棋
  347.     public void goback() {
  348.         if (chessCount == 0)
  349.             return;
  350.  
  351.         chessList[chessCount - 1] = null;
  352.         chessCount--;
  353.         if (chessCount > 0) {
  354.             xIndex = chessList[chessCount - 1].getX();
  355.             yIndex = chessList[chessCount - 1].getY();
  356.         }
  357.         isBlack = !isBlack;
  358.         repaint();
  359.     }
  360.  
  361.     // Dimension: 矩形
  362.     public Dimension getPreferredSize() {
  363.         return new Dimension(MARGIN * 2 + GRID_SPAN * COLS, MARGIN * 2
  364.                 + GRID_SPAN * ROWS);
  365.     }
  366.  
  367. }

回复 "五子棋"

这儿你可以回复上面这条便签

captcha