五子棋小游戏(计科(智能)22-1赵冰凝小组)

一、项目简介

利用Java写编写了五子棋小游戏,具体包括四个类:ChessBoard.java

            ChessBoardListener.java

            ChessPosition.java

            ChessUl.java

分为人人对战和人机对战两个部分

具体功能有重新开始,游戏设置,

二、功能架构图

a6e3b871a3c0401bbf676c7fa3ae38b9.png

四、功能代码

1、实现游戏界面:注意getGraphics要在seVisible后,要不然会报出空指针异常

  1. import javax.imageio.ImageIO;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.awt.event.MouseEvent;
  5. import java.awt.event.MouseListener;
  6. import java.awt.image.BufferedImage;
  7. import java.io.File;
  8. import java.io.IOException;
  9. public class MyJFrame extends JFrame implements MouseListener {
  10.     int qx = 20, qy = 40, qw = 490, qh = 490; //棋盘位置、宽高
  11.     int bw = 150, bh = 50, bx = 570, by = 150; //按钮宽高、位置
  12.     int x = 0, y = 0; //保存棋子坐标
  13.     int[][] SaveGame = new int[15][15]; //保存每个棋子
  14.     int qc = 1;//记录白棋=2,黑棋=1
  15.     int qn = 0;//判断棋子是否重复
  16.     boolean canplay = true; //判断游戏是否开始和结束
  17.     String go = "黑子先行"; //游戏信息
  18.     int bq = 0, hq = 0;

//---------------------------------------------------------------------------------------------------------------------
    //窗体

  1.     public void myJFrame() {
  2.         this.setTitle("五子棋"); //标题
  3.         this.setSize(800, 550); //窗口大小
  4.         this.setResizable(false); //窗口是否可以改变大小=否
  5.         this.setDefaultCloseOperation(MyJFrame.EXIT_ON_CLOSE); //窗口关闭方式为关闭窗口同时结束程序
  6.         int width = Toolkit.getDefaultToolkit().getScreenSize().width; //获取屏幕宽度
  7.         int height = Toolkit.getDefaultToolkit().getScreenSize().height; //获取屏幕高度
  8. //        System.out.println("宽度:"+width);//测试
  9. //        System.out.println("高度:"+height);//测试
  10.         this.setLocation((width - 800) / 2, (height - 600) / 2); //设置窗口默认位置以屏幕居中
  11.         this.addMouseListener(this);
  12.         this.setVisible(true); //窗口是否显示=是
  13.     }
  14.     public class Position {
  15.         int listx;
  16.         int listy;
  17.     }
  18.     public class chessUI extends JPanel {
  19.         public Position[] ps = new Position[300];
  20.         int i;
  21.     }
  22.     chessUI ui = new chessUI();
  23.     Position p = new Position();
  24.  //---------------------------------------------------------------------------------------------------------------------
  25.     //覆写paint方法,绘制界面
  26.     public void paint(Graphics g) {
  27.         //双缓冲技术防止屏幕闪烁
  28.         BufferedImage bi = new BufferedImage(800, 550, BufferedImage.TYPE_INT_ARGB);
  29.         Graphics g2 = bi.createGraphics();
  30.         //获取图片路径
  31.         BufferedImage image = null;
  32.         try {
  33.             //获取项目文件夹路径
  34.             File directory = new File("");
  35.             //路径拼接
  36.             image = ImageIO.read(new File(directory.getAbsolutePath() + "/tp/wzqbj.jpg"));
  37.         } catch (IOException e) {
  38.             e.printStackTrace();
  39.         }
  40.         g2.drawImage(image, 10, 10, this); //显示图片
  41.         g2.setColor(Color.BLACK);//设置画笔颜色
  42.         g2.setFont(new Font("华文行楷", 10, 50)); //设置字体
  43.         g2.drawString("凝静五子棋", 525, 100); //绘制字符
  44.         //棋盘
  45.         g2.setColor(Color.getHSBColor(30, (float) 0.10, (float) 0.90)); //设置画笔颜色
  46.         g2.fillRect(qx, qy, qw, qh); //绘制棋盘背景矩形
  47.         //开始按钮
  48.         g2.setColor(Color.WHITE); //设置画笔颜色
  49.         g2.fillRect(bx, by, bw, bh); //绘制开始按钮
  50.         g2.setFont(new Font("华文行楷", 10, 30)); //设置字体
  51.         g2.setColor(Color.black); //设置画笔颜色
  52.         g2.drawString("开始", 615, 185); //绘制字符
  53.         //悔棋按钮
  54.         g2.setColor(Color.LIGHT_GRAY); //设置画笔颜色
  55.         g2.fillRect(bx, by + 60, bw, bh); //绘制悔棋按钮
  56.         g2.setFont(new Font("华文行楷", 10, 30)); //设置字体
  57.         g2.setColor(Color.WHITE); //设置画笔颜色  
  58.         g2.drawString("悔棋", 615, 245); //绘制字符
  59.         //认输按钮
  60.         g2.setColor(Color.GRAY); //设置画笔颜色
  61.         g2.fillRect(bx, by + 120, bw, bh); //绘制认输按钮
  62.         g2.setFont(new Font("华文行楷", 10, 30)); //设置字体
  63.         g2.setColor(Color.WHITE); //设置画笔颜色
  64.         g2.drawString("认输", 615, 305); //绘制字符
  65.         //游戏信息栏
  66.         g2.setColor(Color.getHSBColor(30, (float) 0.10, (float) 0.90)); //设置画笔颜色
  67.         g2.fillRect(550, 350, 200, 150); //绘制游戏状态区域
  68.         g2.setColor(Color.black); //设置画笔颜色
  69.         g2.setFont(new Font("黑体", 10, 20)); //设置字体
  70.    g2.drawString("游戏信息", 610, 380); //绘制字符
  71.         g2.drawString(go, 610, 410); //绘制字符
  72.         g2.drawString("作者:赵冰凝,孙静", 560, 440); //绘制字符
  73.        
  74.  
  75.         g2.setColor(Color.BLACK); //设置画笔颜色
  76.  
  77.         //绘制棋盘格线
  78.         for (int x = 0; x <= qw; x += 35) {
  79.             g2.drawLine(qx, x + qy, qw + qx, x + qy); //绘制一条横线
  80.             g2.drawLine(x + qx, qy, x + qx, qh + qy); //绘制一条竖线
  81.         }
  82.  
  83.         //绘制标注点
  84.         for (int i = 3; i <= 11; i += 4) {
  85.             for (int y = 3; y <= 11; y += 4) {
  86.                 g2.fillOval(35 * i + qx - 3, 35 * y + qy - 3, 6, 6); //绘制实心圆
  87.             }
  88.         }
  89.  
  90.  
  91.         //绘制棋子
  92.         for (int i = 0; i < 15; i++) {
  93.             for (int j = 0; j < 15; j++) {
  94.                 if (SaveGame[i][j] == 1) //黑子
  95.                 {
  96.                     int sx = i * 35 + qx;
  97.                     int sy = j * 35 + qy;
  98.                     g2.setColor(Color.BLACK);
  99.                     g2.fillOval(sx - 13, sy - 13, 26, 26); //绘制实心圆
  100.                     hq++;
  101.                 }
  102.                 if (SaveGame[i][j] == 2) //白子
  103.                 {
  104.                     int sx = i * 35 + qx;
  105.                     int sy = j * 35 + qy;
  106.                     g2.setColor(Color.WHITE);
  107.                     g2.fillOval(sx - 13, sy - 13, 26, 26); //绘制实心圆
  108.                     g2.setColor(Color.BLACK);
  109.                     g2.drawOval(sx - 13, sy - 13, 26, 26); //绘制空心圆
  110.                     bq++;
  111.                 }
  112.             }
  113.         }
  114.         g.drawImage(bi, 0, 0, this);
  115.  
  116.  
  117. // g.drawRect(20, 20, 20, 20);//绘制空心矩形
  118.     }
 

效果图

7844788a870e4a4d9d6896ce602316db.jpeg 接下来分人人对战和人机对战部分来讲述

2、下棋:需要对鼠标监听器获取x, y坐标处理,为了使黑白子轮流下棋,我们用了flag来标志,当flag为1时下的棋为黑色,flag为2时棋为白色。下完一颗棋子后就反转标志位,就可实现黑白子轮流下棋。创建一个大小为15*15的二维数组,用来保存棋盘上的棋子值,初始化为0后,下了一颗黑棋就把数组对应的位置的值置为1,下白棋则置为2,同时每下一颗棋子将其放入ArrayList中,方便悔棋。

 

  1.                     //画实心白子
  2.                     if(allChess[i][j] == 2){
  3.                         int tempX = i*25+47;
  4.                         int tempY = j*25+64;
  5.                         g1.setColor(Color.WHITE);
  6.                         g1.fillOval(tempX, tempY, 16, 16);
  7.                         g1.setColor(Color.WHITE);
  8.                         g1.drawOval(tempX, tempY, 16, 16);
  9.                     }
  10.                 }
  11.             }
  12.         
  13.             
  14.              g.drawImage(buf, 0, 0,this);    
  15.     }
  16.     
  17.     
  18.     
  19.     public void mousePressed(MouseEvent e){
  20.         if(canPlay){
  21.             x=e.getX();
  22.             y=e.getY();  // 用来获取鼠标坐标
  23.             if(x>55 && x<= 405  && y>=72 && y<=420){
  24.                 //让鼠标在棋盘范围内
  25.                 if((x-55)%25>12){
  26.                     x=(x-55)/25 + 1;
  27.                 }else {
  28.                     x = (x-55)/25;
  29.                 }
  30.                 if((y-72)%25>12){
  31.                     y=(y-72)/25 + 1;
  32.                 }else {
  33.                     y=(y-72)/25;
  34.                 }

2、判断输赢:每下完一步棋,就要判断一下是否分出胜负,判断胜负的规则是看棋盘上有没有五个及以上相同颜色的棋子。

  1. //---------------------------------------------------------------------------------------------------------------------
  2.     //判断输赢
  3.     private boolean WinLose() {
  4.         boolean flag = false; //输赢
  5.         int count = 1; //相连数
  6.         int color = SaveGame[x][y]; //记录棋子颜色
  7.         //判断横向棋子是否相连
  8.         int i = 1; //迭代数
  9.         while (color == SaveGame[x + i][y]) {
  10.             count++;
  11.             i++;
  12.         }
  13.         i = 1; //迭代数
  14.         while (color == SaveGame[x - i][y]) {
  15.             count++;
  16.             i++;
  17.         }
  18.         if (count >= 5) {
  19.             flag = true;
  20.         }
  21.  
  22.         //判断纵向棋子是否相连
  23.         count = 1;
  24.         i = 1; //迭代数
  25.         while (color == SaveGame[x][y + i]) {
  26.             count++;
  27.             i++;
  28.         }
  29.         i = 1; //迭代数
  30.         while (color == SaveGame[x][y - i]) {
  31.             count++;
  32.             i++;
  33.         }
  34.         if (count >= 5) {
  35.             flag = true;
  36.         }
  37.  
  38.         //判断斜向棋子是否相连(左上右下)
  39.         count = 1;
  40.         i = 1; //迭代数
  41.         while (color == SaveGame[x - i][y - i]) {
  42.             count++;
  43.             i++;
  44.         }
  45.         i = 1; //迭代数
  46.         while (color == SaveGame[x + i][y + i]) {
  47.             count++;
  48.             i++;
  49.         }
  50.         if (count >= 5) {
  51.             flag = true;
  52.         }
  53.  
  54.         //判断斜向棋子是否相连(左下右上)
  55.         count = 1;
  56.         i = 1; //迭代数
  57.         while (color == SaveGame[x + i][y - i]) {
  58.             count++;
  59.             i++;
  60.         }
  61.         i = 1; //迭代数
  62.         while (color == SaveGame[x - i][y + i]) {
  63.             count++;
  64.             i++;
  65.         }
  66.         if (count >= 5) {
  67.             flag = true;
  68.         }
  69.         return flag;
  70.     }

3、初始化游戏

  1. //---------------------------------------------------------------------------------------------------------------------
  2.     //初始化游戏
  3.     public void Initialize() {
  4.         //遍历并初始化数组
  5.         for (int i = 0; i < 15; i++) {
  6.             for (int j = 0; j < 15; j++) {
  7.                 SaveGame[i][j] = 0;
  8.             }
  9.         }
  10.         //黑子先行
  11.         qc = 1;
  12.         go = "轮到黑子";
  13.     }

4、鼠标点击

  1.  //---------------------------------------------------------------------------------------------------------------------
  2.     @Override //鼠标点击
  3.     public void mouseClicked(MouseEvent e) {
  4.     }
  5.     @Override //鼠标按下
  6.     public void mousePressed(MouseEvent e) {
  7.         //判断是否已开始游戏
  8.         if (canplay) {
  9.             //获取鼠标点击位置
  10.             x = e.getX();
  11.             y = e.getY();
  12.             ui.ps[ui.i] = p;
  13.             //判断点击是否为棋盘内
  14.             if (x > qx && x < qx + qw && y > qy && y < qy + qh) {
  15.                 //计算点击位置最近的点
  16.                 if ((x - qx) % 35 > 17) {
  17.                     x = (x - qx) / 35 + 1;
  18.                 } else {
  19.                     x = (x - qx) / 35;
  20.                 }
  21.                 if ((y - qy) % 35 > 17) {
  22.                     y = (y - qy) / 35 + 1;
  23.                 } else {
  24.                     y = (y - qy) / 35;
  25.                 }
  26.                 ui.ps[ui.i].listx = x;
  27.                 ui.ps[ui.i].listy = y;
  28.                 ui.i++;
  29.                 //判断当前位置有没有棋子
  30.                 if (SaveGame[x][y] == 0) {
  31.                     SaveGame[x][y] = qc;
  32.                     qn = 0;
  33.                 } else {
  34.                     qn = 1;
  35.                 }
  36.                 //切换棋子
  37.                 if (qn == 0) {
  38.                     if (qc == 1) {
  39.                         qc = 2;
  40.                         go = "轮到白子";
  41.                     } else {
  42.                         qc = 1;
  43.                         go = "轮到黑子";
  44.                     }
  45.                 }
  46.                 this.repaint(); //重新执行一次paint方法
  47. //                弹出胜利对话框
  48.                 boolean wl = this.WinLose();
  49.                 if (wl) {
  50.                     JOptionPane.showMessageDialog(this, "游戏结束," + (SaveGame[x][y] == 1 ? "黑方赢了" : "白方赢了")); //弹出提示对话框
  51.                     canplay = false;
  52.                 }
  53.                 //弹出平局对话框
  54.                 if (bq + hq == 255) {
  55.                     JOptionPane.showMessageDialog(this, "游戏结束,平局!"); //弹出提示对话框
  56.                     canplay = false;

     

5、实现开始按钮

  1. //实现开始按钮
  2.         //判断是否点击开始按钮
  3.         if (e.getX() > bx && e.getX() < bx + bw && e.getY() > by && e.getY() < by + bh) {
  4.             //判断游戏是否开始
  5.             if (!canplay) {
  6.                 //如果游戏结束,则开始游戏
  7.                 canplay = true;
  8.                 JOptionPane.showMessageDialog(this, "游戏开始");
  9.                 //初始化游戏
  10.                 Initialize();
  11.                 this.repaint(); //重新执行一次paint方法
  12.             } else {
  13.                 //如果游戏进行中,则重新开始
  14.                 JOptionPane.showMessageDialog(this, "重新开始");
  15.                 //初始化游戏
  16.                 Initialize();
  17.                 this.repaint(); //重新执行一次paint方法
  18.             }
  19.         }
  20.  
  21.         //实现悔棋按钮
  22.         //判断是否点击悔棋按钮
  23.         if (e.getX() > bx && e.getX() < bx + bw && e.getY() > by + 60 && e.getY() < by + 60 + bh) {
  24.             //判断游戏是否开始
  25.             if (canplay) {
  26.                 //遍历棋盘上是否有棋子
  27.                 int z = 0;
  28.                 for (int i = 0; i < 15; i++) {
  29.                     for (int j = 0; j < 15; j++) {
  30.                         if (SaveGame[i][j] != 0) {
  31.                             z++;
  32.                         }
  33.                     }
  34.                 }
  35.                 //判断是否有棋子
  36.                 if (z != 0) {
  37.                     int result = JOptionPane.showConfirmDialog(this, "确认要悔棋吗?");
  38.                     if (result == 0) {
  39.                         int x = ui.ps[ui.i - 1].listx;
  40.                         int y = ui.ps[ui.i - 1].listy;
  41.                         if (SaveGame[x][y] == 0){
  42.                             JOptionPane.showMessageDialog(this, "已悔过一次棋了!");
  43.                         }else{
  44.                             if (SaveGame[x][y] == 1) {
  45.                                 qc = 1;
  46.                                 go = "轮到黑子";
  47.                             } else if (SaveGame[x][y] == 2){
  48.                                 qc = 2;
  49.                                 go = "轮到白子";
  50.                             }
  51.                             SaveGame[x][y] = 0;
  52.                             ui.i--;
  53.           
  54. this.repaint();
  55.                         }
  56.                     }
  57.                 } else {
  58.                     JOptionPane.showMessageDialog(this, "棋盘上已无棋子");
  59.                 }
  60.             } else {
  61.                 JOptionPane.showMessageDialog(this, "请先开始游戏");
  62.             }
  63.         }
  64.  
  65.         //实现认输按钮
  66.         //判断是否点击认输按钮
  67.         if (e.getX() > bx && e.getX() < bx + bw && e.getY() > by + 120 && e.getY() < by + 120 + bh) {
  68.             //判断游戏是否开始
  69.             if (canplay) {
  70.                 //判断是谁认输
  71.                 if (qc == 1) {
  72.                     JOptionPane.showMessageDialog(this, "黑方认输,白方获胜");
  73.                     canplay = false;
  74.                 } else if (qc == 2) {
  75.                     JOptionPane.showMessageDialog(this, "白方认输,黑方获胜");
  76.                     canplay = false;
  77.                 }
  78.             } else {
  79.                 JOptionPane.showMessageDialog(this, "请先开始游戏");
  80.             }
  81.         }
  82.  
  83.     }
  84.  
  85.     @Override//鼠标抬起
  86.     public void mouseReleased(MouseEvent e) {
  87.     }
  88.     @Override//鼠标进入
  89.     public void mouseEntered(MouseEvent e) {
  90.     }
  91.     @Override//鼠标离开
  92.     public void mouseExited(MouseEvent e) {
  93.     }
  94. }

6、Test

 

  1. import javax.swing.*;
  2. public class Test {
  3.     public static void main(String[] args) {
  4.         Object[] objects={"人人对战","人机对战"};
  5.         int a = JOptionPane.showOptionDialog(null,"请选择游戏模式","请选择",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE,null, objects, objects[0]);
  6.         System.out.println(a);
  7.         if (a == 0){
  8.             MyJFrame mj = new MyJFrame();
  9.             mj.myJFrame();
  10.         }else if (a == 1){
  11.             MyJFrame_AI mjAI = new MyJFrame_AI();
  12.             mjAI.myJFrame();
  13.         }else{
  14.             System.exit(0);
  15.         }
  16.     }
  17. }
     

所以判断的写法:从当前棋子位置开始,分别从横向、竖向、左斜、右斜方向,用count来计数。另外,设置一个标志位gameover初始化为1,意思是允许下棋,当分出胜负后,设置gameover为0,就不能再下棋或者悔棋了。二、人机对战:设置了人先下棋(黑子)然后机器下棋。

难点在于机器下棋,当人下完一步后,用权值法去解决机器应该下到哪里,每一种行棋的情况用枚举法尽可能的列出来

  1. import javax.imageio.ImageIO;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.awt.event.MouseEvent;
  5. import java.awt.event.MouseListener;
  6. import java.awt.image.BufferedImage;
  7. import java.io.File;
  8. import java.io.IOException;
  9. public class MyJFrame_AI extends JFrame implements MouseListener {
  10.     int qx = 20, qy = 40, qw = 490, qh = 490; //棋盘位置、宽高
  11.     int bw = 150, bh = 50, bx = 570, by = 150; //按钮宽高、位置
  12.     int x = 0, y = 0; //保存棋子坐标
  13.     int[][] SaveGame = new int[15][15]; //保存每个棋子
  14.     int qc = 1;//记录白棋=2,黑棋=1
  15.     int qn = 0;//判断棋子是否重复
  16.     boolean canplay = true; //判断游戏是否开始和结束
  17.     String go = "黑子先行"; //游戏信息
  18.     int bq = 0, hq = 0;
  19.     //人机对战增加参数
  20.     int machine = 0;// 该数值为1代表电脑先行
  21.     int[][] score = new int[15][15];// 权值表,保存每个位置的分数
  22.           //---------------------------------------------------------------------------------------------------------------------
  23.     //窗体
  24.     public void myJFrame() {
  25.  
  26.         this.setTitle("五子棋(人机对战)"); //标题
  27.         this.setSize(800, 550); //窗口大小
  28.         this.setResizable(false); //窗口是否可以改变大小=否
  29.         this.setDefaultCloseOperation(MyJFrame_AI.EXIT_ON_CLOSE); //窗口关闭方式为关闭窗口同时结束程序
  30.  
  31.         int width = Toolkit.getDefaultToolkit().getScreenSize().width; //获取屏幕宽度
  32.         int height = Toolkit.getDefaultToolkit().getScreenSize().height; //获取屏幕高度
  33. // System.out.println("宽度:"+width);//测试
  34. // System.out.println("高度:"+height);//测试
  35.  
  36.         this.setLocation((width - 800) / 2, (height - 600) / 2); //设置窗口默认位置以屏幕居中
  37.  
  38.         this.addMouseListener(this);
  39.  
  40.         this.setVisible(true); //窗口是否显示=是
  41.  
  42.         first();
  43.     }
  44.  
  45.     public static class Position {
  46.         static int listx;
  47.         static int listy;
  48.     }
  49.  
  50.     public static class chessUI extends JPanel {
  51.         public static Position[] ps = new Position[300];
  52.         int i;
  53.     }
  54.  
  55.     static chessUI ui = new chessUI();
  56.     static Position p = new Position();     
  57.   
  58.   //---------------------------------------------------------------------------------------------------------------------
  59.     //窗体
  60.     public void myJFrame() {
  61.         this.setTitle("五子棋(人机对战)"); //标题
  62.         this.setSize(800, 550); //窗口大小
  63.         this.setResizable(false); //窗口是否可以改变大小=否
  64.         this.setDefaultCloseOperation(MyJFrame_AI.EXIT_ON_CLOSE); //窗口关闭方式为关闭窗口同时结束程序
  65.         int width = Toolkit.getDefaultToolkit().getScreenSize().width; //获取屏幕宽度
  66.         int height = Toolkit.getDefaultToolkit().getScreenSize().height; //获取屏幕高度
  67. //        System.out.println("宽度:"+width);//测试
  68. //        System.out.println("高度:"+height);//测试
  69.         this.setLocation((width - 800) / 2, (height - 600) / 2); //设置窗口默认位置以屏幕居中
  70.         this.addMouseListener(this);
  71.         this.setVisible(true); //窗口是否显示=是
  72.         first();
  73.     }
  74.     public static class Position {
  75.         static int listx;
  76.         static int listy;
  77.     }
  78.     public static class chessUI extends JPanel {
  79.         public static Position[] ps = new Position[300];
  80.         int i;
  81.     }
  82.     static chessUI ui = new chessUI();
  83.     static Position p = new Position();
  84.  //---------------------------------------------------------------------------------------------------------------------
  85.     //覆写paint方法,绘制界面
  86.     public void paint(Graphics g) {
  87.         //双缓冲技术防止屏幕闪烁
  88.         BufferedImage bi = new BufferedImage(800, 550, BufferedImage.TYPE_INT_ARGB);
  89.         Graphics g2 = bi.createGraphics();
  90.         //获取图片路径
  91.         BufferedImage image = null;
  92.         try {
  93.             //获取项目文件夹路径
  94.             File directory = new File("");
  95.             //路径拼接
  96.             image = ImageIO.read(new File(directory.getAbsolutePath() + "/tp/wzqbj.jpg"));
  97.         } catch (IOException e) {
  98.             e.printStackTrace();
  99.         }
  100.         g2.drawImage(image, 10, 10, this); //显示图片
  101.         g2.setColor(Color.BLACK);//设置画笔颜色
  102.         g2.setFont(new Font("华文行楷", 10, 50)); //设置字体
  103.         g2.drawString("凝静五子棋", 525, 100); //绘制字符
  104.         //棋盘
  105.         g2.setColor(Color.getHSBColor(30, (float) 0.10, (float) 0.90)); //设置画笔颜色
  106.         g2.fillRect(qx, qy, qw, qh); //绘制棋盘背景矩形
  107.         //开始按钮
  108.         g2.setColor(Color.WHITE); //设置画笔颜色
  109.         g2.fillRect(bx, by, bw, bh); //绘制开始按钮
  110.         g2.setFont(new Font("华文行楷", 10, 30)); //设置字体
  111.         g2.setColor(Color.black); //设置画笔颜色
  112.         g2.drawString("开始", 615, 185); //绘制字符
  113.         //悔棋按钮
  114.         g2.setColor(Color.LIGHT_GRAY); //设置画笔颜色
  115.         g2.fillRect(bx, by + 60, bw, bh); //绘制悔棋按钮
  116.         g2.setFont(new Font("华文行楷", 10, 30)); //设置字体
  117.         g2.setColor(Color.WHITE); //设置画笔颜色  
  118.         g2.drawString("悔棋", 615, 245); //绘制字符
  119.         //认输按钮
  120.         g2.setColor(Color.GRAY); //设置画笔颜色
  121.         g2.fillRect(bx, by + 120, bw, bh); //绘制认输按钮
  122.         g2.setFont(new Font("华文行楷", 10, 30)); //设置字体
  123.         g2.setColor(Color.WHITE); //设置画笔颜色
  124.         g2.drawString("认输", 615, 305); //绘制字符
  125.         //游戏信息栏
  126.         g2.setColor(Color.getHSBColor(30, (float) 0.10, (float) 0.90)); //设置画笔颜色
  127.         g2.fillRect(550, 350, 200, 150); //绘制游戏状态区域
  128.         g2.setColor(Color.black); //设置画笔颜色
  129.         g2.setFont(new Font("黑体", 10, 20)); //设置字体
  130.    
  131.  //绘制棋盘格线
  132.         for (int x = 0; x <= qw; x += 35) {
  133.             g2.drawLine(qx, x + qy, qw + qx, x + qy); //绘制一条横线
  134.             g2.drawLine(x + qx, qy, x + qx, qh + qy); //绘制一条竖线
  135.         }
  136.         //绘制标注点
  137.         for (int i = 3; i <= 11; i += 4) {
  138.             for (int y = 3; y <= 11; y += 4) {
  139.                 g2.fillOval(35 * i + qx - 3, 35 * y + qy - 3, 6, 6); //绘制实心圆
  140.             }
  141.         }
  142.  
  143.         //绘制棋子
  144.         for (int i = 0; i < 15; i++) {
  145.             for (int j = 0; j < 15; j++) {
  146.                 if (SaveGame[i][j] == 1) //黑子
  147.                 {
  148.                     int sx = i * 35 + qx;
  149.                     int sy = j * 35 + qy;
  150.                     g2.setColor(Color.BLACK);
  151.                     g2.fillOval(sx - 13, sy - 13, 26, 26); //绘制实心圆
  152.                     hq++;
  153.                 }
  154.                 if (SaveGame[i][j] == 2) //白子
  155.                 {
  156.                     int sx = i * 35 + qx;
  157.                     int sy = j * 35 + qy;
  158.                     g2.setColor(Color.WHITE);
  159.                     g2.fillOval(sx - 13, sy - 13, 26, 26); //绘制实心圆
  160.                     g2.setColor(Color.BLACK);
  161.                     g2.drawOval(sx - 13, sy - 13, 26, 26); //绘制空心圆
  162.                     bq++;
  163.                 }
  164.             }
  165.         }
  166.         g.drawImage(bi, 0, 0, this);
  167.  
  168. //        g.drawRect(20, 20, 20, 20);//绘制空心矩形
  169.     }

2、判断输赢

  1.  
  2.     //---------------------------------------------------------------------------------------------------------------------
  3.     //判断输赢
  4.     private boolean WinLose() {
  5.         boolean flag = false; //输赢
  6.         int count = 1; //相连数
  7.         int color = SaveGame[x][y]; //记录棋子颜色
  8.         //判断横向棋子是否相连
  9.         int i = 1; //迭代数
  10.         while (color == SaveGame[x + i][y]) {
  11.             count++;
  12.             i++;
  13.         }
  14.         i = 1; //迭代数
  15.         while (color == SaveGame[x - i][y]) {
  16.             count++;
  17.             i++;
  18.         }
  19.         if (count >= 5) {
  20.             flag = true;
  21.         }
  22.  
  23.         //判断纵向棋子是否相连
  24.         count = 1;
  25.         i = 1; //迭代数
  26.         while (color == SaveGame[x][y + i]) {
  27.             count++;
  28.             i++;
  29.         }
  30.         i = 1; //迭代数
  31.         if (y > 0) {
  32.             while (color == SaveGame[x][y - i]) {
  33.                 count++;
  34.                 i++;
  35.             }
  36.         }
  37.         if (count >= 5) {
  38.             flag = true;
  39.         }
  40.  
  41.         //判断斜向棋子是否相连(左上右下)
  42.         count = 1;
  43.         i = 1; //迭代数
  44.         while (color == SaveGame[x - i][y - i]) {
  45.             count++;
  46.             i++;
  47.         }
  48.         i = 1; //迭代数
  49.         while (color == SaveGame[x + i][y + i]) {
  50.             count++;
  51.             i++;
  52.         }
  53.         if (count >= 5) {
  54.             flag = true;
  55.         }
  56.  
  57.         //判断斜向棋子是否相连(左下右上)
  58.         count = 1;
  59.         i = 1; //迭代数
  60.         while (color == SaveGame[x + i][y - i]) {
  61.             count++;
  62.             i++;
  63.         }
  64.         i = 1; //迭代数
  65.         while (color == SaveGame[x - i][y + i]) {
  66.             count++;
  67.             i++;
  68.         }
  69.         if (count >= 5) {
  70.             flag = true;
  71.         }
  72.         return flag;
  73.     }

3、初始化游戏

  1.  //---------------------------------------------------------------------------------------------------------------------
  2.     //初始化游戏
  3.     public void Initialize() {
  4.         //遍历并初始化棋子位置数组
  5.         for (int i = 0; i < 15; i++) {
  6.             for (int j = 0; j < 15; j++) {
  7.                 SaveGame[i][j] = 0;
  8.             }
  9.         }
  10.         //遍历并初始化权值数组
  11.         for (int i = 0; i < 15; i++) {
  12.             for (int j = 0; j < 15; j++) {
  13.                 score[i][j] = 0;
  14.             }
  15.         }
  16.         //黑子先行
  17.         qc = 1;
  18.         go = "轮到黑子";
  19.         first();
  20.     }
  21.     /**
  22.      * 判断谁先走
  23.      */
  24.     public void first() {
  25.         Object[] objects = {"玩家先走", "电脑先走"};
  26.         int a = JOptionPane.showOptionDialog(null, "请选择先行者", "请选择", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, objects, objects[0]);
  27.         if (a == -1) {
  28.             System.exit(0);
  29.         }
  30.         if (a == 1) {
  31.             machine = 1;
  32.         }
  33.         if (a == 0) {
  34.             machine = 0;
  35.         }
  36.         // 如果电脑先走,在中间位置下棋
  37.         if (machine == 1) {
  38.             SaveGame[7][7] = 1;
  39.             qc = 2;
  40.             go = "轮到白子";
  41.             this.repaint();
  42.         }
  43.     }
  44.     /**
  45.      * 计算五元组分数
  46.      */
  47.     public int score(int blackNum, int whiteNum) {
  48.         // 通过电脑是否先行判断电脑棋子颜色
  49.         //  如果电脑执黑
  50.         if (machine == 1) {
  51.             // 如果五元组中两种棋子都有,分值为0
  52.             if (blackNum > 0 && whiteNum > 0) {
  53.                 return 0;
  54.             }
  55.             // 都没有,分值为7
  56.             if (blackNum == 0 && whiteNum == 0) {
  57.                 return 7;
  58.             }
  59.             // 判断其中白棋数量计算分数
  60.             if (blackNum == 1) {
  61.                 return 35;
  62.             }
  63.             if (blackNum == 2) {
  64.                 return 800;
  65.             }
  66.             if (blackNum == 3) {
  67.                 return 15000;
  68.             }
  69.             if (blackNum == 4) {
  70.                 return 800000;
  71.             }
  72.             // 判断其中白棋数量计算分数
  73.             if (whiteNum == 1) {
  74.                 r

3、电脑执白

  1. // 如果电脑执白
  2.         if (machine == 0) {
  3.             // 如果五元组中两种棋子都有,分值为0
  4.             if (blackNum > 0 && whiteNum > 0) {
  5.                 return 0;
  6.             }
  7.             // 都没有,分值为7
  8.             if (blackNum == 0 && whiteNum == 0) {
  9.                 return 7;
  10.             }
  11.             // 判断其中白棋数量计算分数
  12.             if (blackNum == 1) {
  13.                 return 15;
  14.             }
  15.             if (blackNum == 2) {
  16.                 return 400;
  17.             }
  18.             if (blackNum == 3) {
  19.                 return 1800;
  20.             }
  21.             if (blackNum == 4) {
  22.                 return 100000;
  23.             }
  24.             // 判断其中白棋数量计算分数
  25.             if (whiteNum == 1) {
  26.                 return 35;
  27.             }
  28.             if (whiteNum == 2) {
  29.                 return 800;
  30.             }
  31.             if (whiteNum == 3) {
  32.                 return 15000;
  33.             }
  34.             if (whiteNum == 4) {
  35.                 return 800000;
  36.             }
  37.    }
  38.         return -1;
  39.     }
  40.     /**
  41.      * 判断人机最佳下棋位置
  42.      */
  43.     public void machineGo(int pieces) {
  44.         int blackNum = 0;
  45.         int whiteNum = 0;
  46.         // 横向
  47.         for (int i = 0; i < 15; i++) {
  48.             for (int j = 0; j < 11; j++) {
  49.                 int k = j;
  50.                 while (k < j + 5) {
  51.                     if (SaveGame[i][k] == 1) {
  52.                         blackNum++;
  53.                     } else if (SaveGame[i][k] == 2) {
  54.                         whiteNum++;
  55.                     }
  56.                     k++;
  57.                 }
  58.                 // 给五元组每个没有落子的位置添加分数
  59.                 for (k = j; k < j + 5; k++) {
  60.                     if (score[i][k] == 0) {
  61.                         score[i][k] += score(blackNum, whiteNum);
  62.                     }
  63.                 }
  64.                 // 将上次值归零,以便下次计算
  65.                 blackNum = 0;
  66.                 whiteNum = 0;
  67.             }
  68.         }
  69.         // 纵向
  70.         for (int i = 0; i < 15; i++) {
  71.             for (int j = 0; j < 11; j++) {
  72.                 int k = j;
  73.                 while (k < j + 5) {
  74.                     if (SaveGame[k][i] == 1) {
  75.                         blackNum++;
  76.                     } else if (SaveGame[k][i] == 2) {
  77.                         whiteNum++;
  78.                     }
  79.                     k++;
  80.                 }
  81.                 // 给五元组每个没有落子的位置添加分数
  82.                 for (k = j; k < j + 5; k++) {
  83.                     score[k][i] += score(blackNum, whiteNum);
  84.                 }
  85.                 // 将上次值归零,以便下次计算
  86.                 blackNum = 0;
  87.                 whiteNum = 0;
  88.             }
  89.         }

3、电脑棋子位置

  1. //右上左下,上部分
  2.         for (int i = 14; i >= 4; i--) {
  3.             for (int k = i, j = 0; j < 15 && k >= 0; j++, k--) {
  4.                 int m = k;
  5.                 int n = j;
  6.                 while (m > k - 5 && k - 5 >= -1) {
  7.                     if (SaveGame[m][n] == 1) {
  8.                         blackNum++;
  9.                     } else if (SaveGame[m][n] == 2) {
  10.                         whiteNum++;
  11.                     }
  12.                     m--;
  13.                     n++;
  14.                 }
  15.                 // 斜向判断时,可能无法构成五元组,进行判断对其忽略
  16.                 if (m == k - 5) {
  17.                     for (m = k, n = j; m > k - 5; m--, n++) {
  18.                         score[m][n] += score(blackNum, whiteNum);
  19.                     }
  20.                 }
  21.                 // 将上次值归零,以便下次计算
  22.                 blackNum = 0;
  23.                 whiteNum = 0;
  24.             }
  25.         }
  26.         //右上左下,下部分
  27.         for (int i = 1; i < 15; i++) {
  28.             for (int k = i, j = 14; j >= 0 && k < 15; j--, k++) {
  29.                 int m = k;
  30.                 int n = j;
  31.                 while (m < k + 5 && k + 5 <= 15) {
  32.                     if (SaveGame[n][m] == 1) {
  33.                         blackNum++;
  34.                     } else if (SaveGame[n][m] == 2) {
  35.                         whiteNum++;
  36.                     }
  37.                     m++;
  38.                     n--;
  39.                 }
  40.                 // 斜向判断时,可能无法构成五元组,进行判断对其忽略
  41.                 if (m == k + 5) {
  42.                     for (m = k, n = j; m < k + 5; m++, n--) {
  43.                         score[n][m] += score(blackNum, whiteNum);
  44.                     }
  45.                 }
  46.                 // 将上次值归零,以便下次计算
  47.                 blackNum = 0;
  48.                 whiteNum = 0;
  49.             }
  50.         }
  51. //右上左下,上部分
  52.         for (int i = 14; i >= 4; i--) {
  53.             for (int k = i, j = 0; j < 15 && k >= 0; j++, k--) {
  54.                 int m = k;
  55.                 int n = j;
  56.                 while (m > k - 5 && k - 5 >= -1) {
  57.                     if (SaveGame[m][n] == 1) {
  58.                         blackNum++;
  59.                     } else if (SaveGame[m][n] == 2) {
  60.                         whiteNum++;
  61.                     }
  62.                     m--;
  63.                     n++;
  64.                 }
  65.                 // 斜向判断时,可能无法构成五元组,进行判断对其忽略
  66.                 if (m == k - 5) {
  67.                     for (m = k, n = j; m > k - 5; m--, n++) {
  68.                         score[m][n] += score(blackNum, whiteNum);
  69.                     }
  70.                 }
  71.                 // 将上次值归零,以便下次计算
  72.                 blackNum = 0;
  73.                 whiteNum = 0;
  74.             }
  75.         }
  76.         //右上左下,下部分
  77.         for (int i = 1; i < 15; i++) {
  78.             for (int k = i, j = 14; j >= 0 && k < 15; j--, k++) {
  79.                 int m = k;
  80.                 int n = j;
  81.                 while (m < k + 5 && k + 5 <= 15) {
  82.                     if (SaveGame[n][m] == 1) {
  83.                         blackNum++;
  84.                     } else if (SaveGame[n][m] == 2) {
  85.                         whiteNum++;
  86.                     }
  87.                     m++;
  88.                     n--;
  89.                 }
  90.                 // 斜向判断时,可能无法构成五元组,进行判断对其忽略
  91.                 if (m == k + 5) {
  92.                     for (m = k, n = j; m < k + 5; m++, n--) {
  93.                         score[n][m] += score(blackNum, whiteNum);
  94.                     }
  95.                 }
  96.                 // 将上次值归零,以便下次计算
  97.                 blackNum = 0;
  98.                 whiteNum = 0;
  99.             }
  100.         }

4、。

  1. //右上左下,上部分
  2.         for (int i = 14; i >= 4; i--) {
  3.             for (int k = i, j = 0; j < 15 && k >= 0; j++, k--) {
  4.                 int m = k;
  5.                 int n = j;
  6.                 while (m > k - 5 && k - 5 >= -1) {
  7.                     if (SaveGame[m][n] == 1) {
  8.                         blackNum++;
  9.                     } else if (SaveGame[m][n] == 2) {
  10.                         whiteNum++;
  11.                     }
  12.                     m--;
  13.                     n++;
  14.                 }
  15.                 // 斜向判断时,可能无法构成五元组,进行判断对其忽略
  16.                 if (m == k - 5) {
  17.                     for (m = k, n = j; m > k - 5; m--, n++) {
  18.                         score[m][n] += score(blackNum, whiteNum);
  19.                     }
  20.                 }
  21.                 // 将上次值归零,以便下次计算
  22.                 blackNum = 0;
  23.                 whiteNum = 0;
  24.             }
  25.         }
  26.         //右上左下,下部分
  27.         for (int i = 1; i < 15; i++) {
  28.             for (int k = i, j = 14; j >= 0 && k < 15; j--, k++) {
  29.                 int m = k;
  30.                 int n = j;
  31.                 while (m < k + 5 && k + 5 <= 15) {
  32.                     if (SaveGame[n][m] == 1) {
  33.                         blackNum++;
  34.                     } else if (SaveGame[n][m] == 2) {
  35.                         whiteNum++;
  36.                     }
  37.                     m++;
  38.                     n--;
  39.                 }
  40.                 // 斜向判断时,可能无法构成五元组,进行判断对其忽略
  41.                 if (m == k + 5) {
  42.                     for (m = k, n = j; m < k + 5; m++, n--) {
  43.                         score[n][m] += score(blackNum, whiteNum);
  44.                     }
  45.                 }
  46.                 // 将上次值归零,以便下次计算
  47.                 blackNum = 0;
  48.                 whiteNum = 0;
  49.             }
  50.         }
  51. // 左上右下,上部分
  52.         for (int i = 0; i < 11; i++) {
  53.             for (int k = i, j = 0; j < 15 && k < 15; j++, k++) {
  54.                 int m = k;
  55.                 int n = j;
  56.                 while (m < k + 5 && k + 5 <= 15) {
  57.                     if (SaveGame[m][n] == 1) {
  58.                         blackNum++;
  59.                     } else if (SaveGame[m][n] == 2) {
  60.                         whiteNum++;
  61.                     }
  62.                     m++;
  63.                     n++;
  64.                 }
  65.                 // 斜向判断时,可能无法构成五元组,进行判断对其忽略
  66.                 if (m == k + 5) {
  67.                     //为该五元组的每个位置添加分数
  68.                     for (m = k, n = j; m < k + 5; m++, n++) {
  69.                         score[m][n] += score(blackNum, whiteNum);
  70.                     }
  71.                 }
  72.                 // 将上次值归零,以便下次计算
  73.                 blackNum = 0;
  74.                 whiteNum = 0;
  75.             }
  76.         }
  77.         // 左上右下,下部分
  78.         for (int i = 1; i < 11; i++) {
  79.             for (int k = i, j = 0; j < 15 && k < 15; j++, k++) {
  80.                 int m = k;
  81.                 int n = j;
  82.                 while (m < k + 5 && k + 5 <= 15) {
  83.                     if (SaveGame[n][m] == 1) {
  84.                         blackNum++;
  85.                     } else if (SaveGame[n][m] == 2) {
  86.                         whiteNum++;
  87.                     }
  88.                     m++;
  89.                     n++;
  90.                 }
  91.                 // 斜向判断时,可能无法构成五元组,进行判断对其忽略
  92.                 if (m == k + 5) {
  93.                     //为该五元组的每个位置添加分数
  94.                     for (m = k, n = j; m < k + 5; m++, n++) {
  95.                         score[n][m] += score(blackNum, whiteNum);
  96.                     }
  97.                 }
  98.                 // 将上次值归零,以便下次计算
  99.                 blackNum = 0;
  100.                 whiteNum = 0;
  101.             }
  102.         }
  103.         int maxScore = 0;
  104.         // 从没有落子的位置,找到分数最大的
  105.         for (int i = 0; i < 15; i++) {
  106.             for (int j = 0; j < 15; j++) {
  107.                 if (SaveGame[i][j] == 0 && score[i][j] > maxScore) {
  108.           
  1.  x = i;
  2.                     y = j;
  3.                     maxScore = score[i][j];
  4.                 }
  5.             }
  6.         }
  7.         SaveGame[x][y] = pieces;
  8.         ui.ps[ui.i].listx = x;
  9.         ui.ps[ui.i].listy = y;
  10.         ui.i++;
  11.         this.repaint(); //重新执行一次paint方法
  12.         // 弹出胜利对话框
  13.         boolean wl = this.WinLose();
  14.         if (wl) {
  15.             JOptionPane.showMessageDialog(this, "游戏结束," + (SaveGame[x][y] == 1 ? "黑方赢了" : "白方赢了")); //弹出提示对话框
  16.             canplay = false;
  17.         }
  18.         //弹出平局对话框
  19.         if (bq + hq == 255) {
  20.             JOptionPane.showMessageDialog(this, "游戏结束,平局!"); //弹出提示对话框
  21.             canplay = false;
  22.         }
  23.     }
  24. //---------------------------------------------------------------------------------------------------------------------
  25.     @Override //鼠标点击
  26.     public void mouseClicked(MouseEvent e) {
  27.     }
  28.     @Override //鼠标按下
  29.     public void mousePressed(MouseEvent e) {
  30.         //判断是否已开始游戏
  31.         if (canplay) {
  32.             //获取鼠标点击位置
  33.             x = e.getX();
  34.             y = e.getY();
  35.             ui.ps[ui.i] = p;
  36.             //判断点击是否为棋盘内
  37.             if (x > qx && x < qx + qw && y > qy && y < qy + qh) {
  38.                 //计算点击位置最近的点
  39.                 if ((x - qx) % 35 > 17) {
  40.                     x = (x - qx) / 35 + 1;
  41.                 } else {
  42.                     x = (x - qx) / 35;
  43.                 }
  44.                 if ((y - qy) % 35 > 17) {
  45.                     y = (y - qy) / 35 + 1;
  46.                 } else {
  47.                     y = (y - qy) / 35;
  48.                 }
  49.                 ui.ps[ui.i].listx = x;
  50.                 ui.ps[ui.i].listy = y;
  51.                 ui.i++;
  52.                 //判断当前位置有没有棋子
  53.                 if (SaveGame[x][y] == 0) {
  54.                     SaveGame[x][y] = qc;
  55.                     qn = 0;
  56.                 } else {
  57.                     qn = 1;
  58.                 }
  59.                 //切换棋子
  60.                 if (qn == 0) {
  61.                     if (qc == 1) {
  62.                         qc = 2;
  63.                         go = "轮到白子";
  64.                     } else {
  65.                         qc = 1;
  66.                         go = "轮到黑子";
  67.                     }
  68.                 }
  69.                 this.repaint(); //重新执行一次paint方法
  70. //实现悔棋按钮
  71.         //判断是否点击悔棋按钮
  72.         if (e.getX() > bx && e.getX() < bx + bw && e.getY() > by + 60 && e.getY() < by + 60 + bh) {
  73.             //判断游戏是否开始
  74.             if (canplay) {
  75.                 //遍历棋盘上是否有棋子
  76.                 int z = 0;
  77.                 for (int i = 0; i < 15; i++) {
  78.                     for (int j = 0; j < 15; j++) {
  79.                         if (SaveGame[i][j] != 0) {
  80.                             z++;
  81.                         }
  82.                     }
  83.                 }
  84.                 //判断是否有棋子
  85.                 if (z != 0) {
  86.                     int result = JOptionPane.showConfirmDialog(this, "确认要悔棋吗?");
  87.                     if (result == 0) {
  88.                         int x = ui.ps[ui.i - 1].listx;
  89.                         int y = ui.ps[ui.i - 1].listy;
  90.                         if (SaveGame[x][y] == 0) {
  91.                             JOptionPane.showMessageDialog(this, "已悔过一次棋了!");
  92.                         } else {
  93.                             if (SaveGame[x][y] == 1) {
  94.                                 qc = 1;
  95.                                 go = "轮到黑子";
  96.                             } else if (SaveGame[x][y] == 2) {
  97.                                 qc = 2;
  98.                                 go = "轮到白子";
  99.                             }
  100.                             SaveGame[x][y] = 0;
  101.                             ui.i--;
  102.                             this.repaint();
  103.                         }
  104.                     }
  105.                 } else {
  106.                     JOptionPane.showMessageDialog(this, "棋盘上已无棋子");
  107.                 }
  108.             } else {
  109.                 JOptionPane.showMessageDialog(this, "请先开始游戏");
  110.             }
  111.         }
  112. @Override//鼠标抬起
  113.     public void mouseReleased(MouseEvent e) {
  114.         //如果电脑先行,就也代表电脑执黑子,否则反之。在相应回合时让电脑做出反应
  115.         if (machine == 1) {
  116.             if (qc == 1) {
  117.                 machineGo(qc);
  118.                 qc = 2;
  119.                 go = "轮到白子";
  120.             }
  121.         } else {
  122.             if (qc == 2) {
  123.                 machineGo(qc);
  124.                 qc = 1;
  125.                 go = "轮到黑子";
  126.             }
  127.         }
  128.     }
  129.  
  130.     @Override//鼠标进入
  131.     public void mouseEntered(MouseEvent e) {
  132.  
  133.     }
  134.  
  135.     @Override//鼠标离开
  136.     public void mouseExited(MouseEvent e) {
  137.  
  138.     }
  139. }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值