zoukankan      html  css  js  c++  java
  • 实践周java基础软件开发app之五子棋

    五子棋人机对战实践项目

    总的任务和目标

    完成一个人机对战的五子棋项目,基本效果如下:

       

    第一部分 Java绘图原理

    1.   基本概念

    像素,坐标

    第二部分 绘制棋盘

    1.   基本思路

    在一个JPanel上绘制一个背景,然后绘制水平和垂直的若干条线,使其构成等距离的格子,通常是15*15(条线)。

    2.   代码实现

    第三部分 绘制棋子

    1.   基本思路

    使用drawOval()可以绘制空心的圆,使用fillOval()可以填充实心的圆。

    2.   坐标计算

    由于格子是水平和垂直的有下标的,而绘制时需要使用实际的像素坐标,所以,需要进行行列下标到像素坐标的转换:

    int x = col * GRID_WIDTH;

    int y = row * GRID_WIDTH;

    3.   代码实现

    (1)     ChessPanel代码:

     

    第四部分 鼠标下棋

    1.   基本思路

    需要处理鼠标单点事件,获取鼠标所在的位置,然后计算出应该绘制棋子的行列下标,并使用一个二维数组来全局存储棋子的位置。

    2.   鼠标位置与行列下标计算

            int x = e.getX();

            int y = e.getY();

            int row = y / GRID_WIDTH;

         int col = x / GRID_WIDTH;

    3.   代码实现

    (1)      ChessPanel属性和构造方法代码:

     

    (2)监听器类(内部类)代码:

     

    (3)绘图代码:

     

    第五部分 判断胜负

    1.   基本思路

    判断胜负是因为在当前位置(row, col)落子导致了胜负,所以,判断胜负其实是在当前落子位置为中心,横向搜索左边第4个位置开始到右边第4个位置(其余位置不需要考虑),或者从上到下,或者正向45度,或者反向45度位置。

    2.   处理方法

    处理方法有很多,可以采用计数的方式,也可以采用字符串连接的方式,此处采用了将从左边第4颗开始,到右边第4颗结束,将每颗的颜色表示成字符1(黑色)或者2(白色),只需要判断其中是否有连续的5个1或5个2,即“11111”或“22222”即可知道胜负。

    3.   代码实现

    (1)     监听器类(内部类)代码:

     

    (2)checkWin判断胜负的代码:

    /** 判断胜负

            * @param row      落子的行下标

            * @param col       落子的列下标

            * @return 是否获胜,true-是,false-否

            */

    public boolean checkWin(int row, int col) {}

     

    (3)重置游戏状态

     

    【目前代码】

      1 package wuziqi;
      2 
      3 import java.awt.Color;
      4 import java.awt.Container;
      5 import java.awt.Graphics;
      6 import java.awt.event.MouseAdapter;
      7 import java.awt.event.MouseEvent;
      8 
      9 import javax.swing.JFrame;
     10 import javax.swing.JOptionPane;
     11 import javax.swing.JPanel;
     12 
     13 public class wuziqijiemianDemo {
     14     //创建窗口为主类的类部类并且继承自JFrame
     15     public class Myjframe extends JFrame {
     16         /**
     17          * 用一个构造方法创建窗口
     18          */
     19         public Myjframe() {
     20             this.setTitle("五子棋");
     21             this.setSize(620, 640);
     22             //获取内容面板
     23             Container cp = getContentPane();
     24             //创建一个面板JPanel
     25             JPanel jPanel = new MyJanel();
     26             cp.add(jPanel);
     27             //面板的背景颜色为黄色,便于下白棋与黑棋
     28             jPanel.setBackground(Color.yellow);
     29             this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
     30             //窗口默认设置为显示屏的正中间
     31             this.setLocationRelativeTo(null);
     32             //不可改变窗口的大小
     33             this.setResizable(false);
     34         }
     35     }
     36 /**
     37  * 创建一个面板继承自JPanel
     38  * @author Administrator
     39  *
     40  */
     41     public class MyJanel extends JPanel {
     42         //表示每个方格的大小
     43         private static final int GRID_WIDTh = 40;
     44         //棋盘的大小,代表棋盘的线的条数
     45         private static final int LINE_COUNT = 15;
     46         //设置黑棋子为1、白棋子为2、没有棋子为0(默认值)
     47         public static final int BLACK=1;
     48         public static final int WHITE=2;
     49         //定义一个棋盘大小的数组用来存放黑棋和白棋的位置
     50         int[][] chessItems=new int[LINE_COUNT][LINE_COUNT];
     51         //定义一个标志位,代表黑棋先下(黑棋和白棋轮流下棋)
     52         int flag=BLACK;
     53         /**
     54          * 构造方法用来画棋盘的棋子
     55          */
     56         public MyJanel(){
     57             /**
     58              * 为这个面板添加一个鼠标点击事件,鼠标每点击一次,就在棋盘上下一个棋子
     59              *使用适配器的方式添加鼠标点击事件    
     60              */
     61             this.addMouseListener(new MouseAdapter() {
     62                 public void mouseClicked(MouseEvent e){
     63                     /**
     64                      * 获取当前的鼠标点击的位置
     65                      */
     66                     int x=e.getX();
     67                     int y=e.getY();
     68                     /**
     69                      * 因为棋盘是用二维数组的方式表示的,所以最后表示为二维数组的行与列
     70                      */
     71                     int row=y/GRID_WIDTh;
     72                     int col=x/GRID_WIDTh;
     73                     //当前这个位置没有棋子(为零),可以下一个黑棋子
     74                     if(chessItems[row][col]==0){
     75                         if(flag==BLACK){
     76                             chessItems[row][col]=flag;
     77                             //下完黑棋下白棋
     78                             flag=WHITE;
     79                             //必须有,不然后面的白棋会覆盖黑棋
     80                         }
     81                         //当前这个位置没有棋子(为零),可以下一个白棋子
     82                         else{
     83                             chessItems[row][col]=flag;
     84                             //下完白棋下黑棋
     85                             flag=BLACK;
     86                         }
     87                     }
     88                     /**
     89                      * 每当下完一步棋之后便判断是否已经取胜
     90                      */
     91                     if(checkImage(row,col)){
     92                         //显示对话窗口
     93                         JOptionPane.showMessageDialog(null, "your win");
     94                         //清空棋盘
     95                         clear();
     96                     }
     97                     //System.out.println(chessItems[row][col]);
     98                 }
     99             });
    100         }
    101         /**
    102          * 调用public void paintComponent(Graphics arg0){};方法画图
    103          */
    104         public void paintComponent(Graphics g) {
    105             //系统调用
    106             super.paintComponent(g);
    107 //            g.setColor(Color.yellow);
    108 //            g.fillRect(0, 0, jPanel.width(),jPanel.height());
    109             /**
    110              * 画横线,起始位置在窗口左上定点(GRID_WIDTh/2,GRID_WIDTh/2)
    111              */
    112             for (int i = 0; i < LINE_COUNT; i++) {
    113                 int x1 = GRID_WIDTh / 2;
    114                 int y1 = GRID_WIDTh / 2 + i * GRID_WIDTh;
    115                 int x2 = x1 + (LINE_COUNT-1)* GRID_WIDTh;
    116                 int y2 = y1;
    117                 //画线
    118                 g.drawLine(x1, y1, x2, y2);
    119             }
    120             /**
    121              * 画竖线
    122              */
    123             for (int i = 0; i < LINE_COUNT; i++) {
    124                 int x1 = GRID_WIDTh / 2 + i * GRID_WIDTh;
    125                 int y1 = GRID_WIDTh / 2;
    126                 int x2 = x1;
    127                 int y2 = y1 + (LINE_COUNT-1) * GRID_WIDTh;
    128                 //画线
    129                 g.drawLine(x1, y1, x2, y2);
    130             }
    131             /**
    132              * 遍历这个数组
    133              */
    134             for(int row=0;row<LINE_COUNT;row++){
    135                 for(int col=0;col<LINE_COUNT;col++){
    136                     //判断数组当前值,来画棋子
    137                     switch (chessItems[row][col]) {
    138                     case WHITE:chessItem(row, col, Color.WHITE, g);break;
    139                     case BLACK:chessItem(row, col, Color.BLACK, g);break;
    140                     }
    141                     repaint();
    142                 }
    143             }
    144         };
    145         /**
    146          * 清空数组,便于下次下棋
    147          */
    148         private void clear() {
    149             for(int row=0;row<LINE_COUNT;row++){                    
    150                 for(int col=0;col<LINE_COUNT;col++){
    151                     //全部置为0
    152                     chessItems[row][col]=0;
    153                 }
    154             }
    155             //重画一遍棋盘
    156             repaint();
    157         }
    158         /**
    159          * 用于判断是否已经取胜
    160          * @param row
    161          * @param col
    162          * @return
    163          */
    164         private boolean checkImage(int row, int col) {
    165             /**
    166              * 判断横行是否win
    167              */
    168             StringBuilder stringBuilder=new StringBuilder();
    169             //记录当前存在字符串中的数据个数
    170             int count=0;
    171             for(int i=-4;i<=4;i++){
    172                 int Newcol=col+i;
    173                 if(Newcol>=0&&Newcol<LINE_COUNT){
    174                     count++;
    175                     stringBuilder.append(chessItems[row][Newcol]);
    176                 }
    177             }
    178             if(stringBuilder.indexOf("11111")>=0||stringBuilder.indexOf("22222")>=0){
    179                 return true;
    180             }else {
    181                 //如果当前不能赢,则清空字符串
    182                 stringBuilder.delete(0, count);
    183                 count=0;
    184             }
    185             /**
    186              * 判断竖行是否win
    187              */
    188             for(int i=-4;i<=4;i++){
    189                 int Newrow=row+i;
    190                 if(Newrow>=0&&Newrow<LINE_COUNT){
    191                     count++;
    192                     stringBuilder.append(chessItems[Newrow][col]);
    193                 }
    194             }
    195             if(stringBuilder.indexOf("11111")>=0||stringBuilder.indexOf("22222")>=0){
    196                 return true;
    197             }else {
    198                 stringBuilder.delete(0, count);
    199                 count=0;
    200             }
    201             /**
    202              * 判断负45°是否win
    203              */
    204             for(int i=-4;i<=4;i++){
    205                 int Newcol=col+i;
    206                 int Newrow=row+i;
    207                 if(Newcol>=0&&Newcol<LINE_COUNT&&Newrow>=0&&Newrow<LINE_COUNT){
    208                     count++;
    209                     stringBuilder.append(chessItems[Newrow][Newcol]);
    210                 }
    211             }
    212             if(stringBuilder.indexOf("11111")>=0||stringBuilder.indexOf("22222")>=0){
    213                 return true;
    214             }else {
    215                 stringBuilder.delete(0, count);
    216                 count=0;
    217             }
    218             /**
    219              * 判断正45°是否win
    220              */
    221             for(int i=-4;i<=4;i++){
    222                 int Newcol=col+i;
    223                 int Newrow=row-i;
    224                 if(Newcol>=0&&Newcol<LINE_COUNT&&Newrow>=0&&Newrow<LINE_COUNT){
    225                     count++;
    226                     stringBuilder.append(chessItems[Newrow][Newcol]);
    227                 }
    228             }
    229             if(stringBuilder.indexOf("11111")>=0||stringBuilder.indexOf("22222")>=0){
    230                 return true;
    231             }else {
    232                 stringBuilder.delete(0, count);
    233                 count=0;
    234             }
    235             return false;
    236         }
    237         //画棋子
    238         public void chessItem(int row,int col,Color color,Graphics graphics){
    239             //x与y分别代表在面板上的位置
    240             int x=col*GRID_WIDTh;
    241             int y=row*GRID_WIDTh;
    242             graphics.setColor(color);
    243             //画圆
    244             graphics.fillOval(x, y, GRID_WIDTh,GRID_WIDTh);
    245         }
    246     }
    247 
    248     public static void main(String[] args) {
    249         /**
    250          * 使用一个java类来创建一个主类为wuziqijiemianDemo,其中的窗口与棋盘为该主类的内部类
    251          */
    252         //使用类部类的方式创建一个窗口引用对象(方式为 外部类名.内部类名 变量名=new 外部类名().new 内部类名();)
    253         wuziqijiemianDemo.Myjframe myjframe = new wuziqijiemianDemo().new Myjframe();
    254         //设置窗口可见
    255         myjframe.setVisible(true);
    256     }
    257 
    258 }

    第六部分 人机对战

    1.   基本思路

    当人点了鼠标落子以后,轮到电脑下棋,电脑的基本思想就是,在棋盘的空白处的每个位置,进行判断,当前位置的进攻指数和防守指数分别为多少,在进攻指数和防守指数中取一个较大值作为当前位置的评估值,在整个棋盘的所有空白处找到一个最大值,最大值的那个位置即为应该落子的位置。

    2.  代码实现

    (1)监听器类(内部类)代码:

    (2)电脑下棋的代码

    (3)     评估关键参数代码:

     

    (4) 评估方法代码:

    【自己代码】

      1 package wuziqi;
      2 
      3 import java.awt.Color;
      4 import java.awt.Container;
      5 import java.awt.Graphics;
      6 import java.awt.Image;
      7 import java.awt.Point;
      8 import java.awt.event.MouseAdapter;
      9 import java.awt.event.MouseEvent;
     10 import java.io.File;
     11 import java.io.IOException;
     12 
     13 import javax.imageio.ImageIO;
     14 import javax.swing.JFrame;
     15 import javax.swing.JOptionPane;
     16 import javax.swing.JPanel;
     17 
     18 public class wuziqijiemianDemo {
     19     // 创建窗口为主类的类部类并且继承自JFrame
     20     public class Myjframe extends JFrame {
     21         /**
     22          * 用一个构造方法创建窗口
     23          */
     24         public Myjframe() {
     25             this.setTitle("五子棋");
     26             this.setSize(620, 640);
     27             // 获取内容面板
     28             Container cp = getContentPane();
     29             // 创建一个面板JPanel
     30             JPanel jPanel = new MyJanel();
     31             cp.add(jPanel);
     32             // 面板的背景颜色为黄色,便于下白棋与黑棋
     33             jPanel.setBackground(Color.yellow);
     34             this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
     35             // 窗口默认设置为显示屏的正中间
     36             this.setLocationRelativeTo(null);
     37             // 不可改变窗口的大小
     38             this.setResizable(false);
     39         }
     40     }
     41 
     42     /**
     43      * 创建一个面板继承自JPanel
     44      * 
     45      * @author Administrator
     46      * 
     47      */
     48     public class MyJanel extends JPanel {
     49         // 表示每个方格的大小
     50         private static final int GRID_WIDTh = 40;
     51         // 棋盘的大小,代表棋盘的线的条数
     52         private static final int LINE_COUNT = 15;
     53         // 设置黑棋子为1、白棋子为2、没有棋子为0(默认值)
     54         public static final int BLACK = 1;
     55         public static final int WHITE = 2;
     56         // 定义一个棋盘大小的数组用来存放黑棋和白棋的位置
     57         int[][] chessItems = new int[LINE_COUNT][LINE_COUNT];
     58         // 定义一个标志位,代表黑棋先下(黑棋和白棋轮流下棋)
     59         int flag = BLACK;
     60         //定义一个方框标记计算机下棋的棋子
     61         private Point lastpoint=new Point();
     62         //利用图片代表棋子
     63         Image blackImage=null;
     64         Image whiImage=null;
     65         //定义一个进攻的数组
     66         String[] defendstring={
     67             "11111","011110","11110","01111","11011",
     68             "10111","11101","01110","11100","00111",
     69             "0111","1110","1011","1101","111",
     70             "01100","00110","011","110","11"
     71         };
     72         //定义一个防守的数组
     73         String[] attackstring={
     74             "22222","022220","22220","02222","22022",
     75             "20222","22202","02220","22200","00222",
     76             "0222","2220","2022","2202","222",
     77             "02200","00220","022","220","22"
     78         };
     79         //定义一个防守与进攻对应的得分
     80         int[] score={
     81             100,90,80,80,80,
     82             80,80,70,60,60,
     83             50,50,50,50,40,
     84             30,30,20,20,10,
     85         };
     86         /**
     87          * 构造方法用来画棋盘的棋子
     88          */
     89         public MyJanel() {
     90             /**
     91              * 将棋子改变为图片,将黑子白子图片导入进来
     92              */
     93             try {
     94                 blackImage=ImageIO.read(new File("imgs/black.png"));
     95                 whiImage=ImageIO.read(new File("imgs/WHITE.png"));
     96             } catch (IOException e1) {
     97                 // TODO Auto-generated catch block
     98                 e1.printStackTrace();
     99             }
    100             /**
    101              * 为这个面板添加一个鼠标点击事件,鼠标每点击一次,就在棋盘上下一个棋子 使用适配器的方式添加鼠标点击事件
    102              */
    103             this.addMouseListener(new MouseAdapter() {
    104                 public void mouseClicked(MouseEvent e) {
    105                     /**
    106                      * 获取当前的鼠标点击的位置
    107                      */
    108                     int x = e.getX();
    109                     int y = e.getY();
    110                     /**
    111                      * 因为棋盘是用二维数组的方式表示的,所以最后表示为二维数组的行与列
    112                      */
    113                     int row = y / GRID_WIDTh;
    114                     int col = x / GRID_WIDTh;
    115                     // 当前这个位置没有棋子(为零),可以下一个黑棋子
    116                     if (chessItems[row][col] == 0) {
    117                         //人先下黑棋
    118                         chessItems[row][col] = flag;
    119                         /**
    120                          * 每当下完一步棋之后便判断是否已经取胜
    121                          */
    122                         if (checkImage(row, col)) {
    123                             JOptionPane.showMessageDialog(null, "你赢了");
    124                             clear();
    125                             return;
    126                         }
    127                         // 人下完黑棋下白棋,之后再给计算机下黑棋的机会
    128                         flag = WHITE;
    129                         //计算机下棋
    130                         computerPlay();
    131                         // 计算机下完摆起之后,给人下黑棋的机会
    132                         flag = BLACK;
    133                         // 必须有,不然后面的白棋会覆盖黑棋
    134                     }        
    135                     // System.out.println(chessItems[row][col]);
    136                 }
    137                 //计算机下棋调用方法
    138                 private void computerPlay() {
    139                     // 当前初始化找到的位置和期望值
    140                     int tempRow = -1, tempCol = -1, maxValue = 0;
    141                     // 遍历数组一个位置一个位置的找
    142                     for (int i = 0; i < LINE_COUNT; i++) {
    143                         for (int j = 0; j < LINE_COUNT; j++) {
    144                             // 如果这个位置已经下棋,则跳过
    145                             if (chessItems[i][j] > 0) {
    146                                 continue;
    147                             }
    148                             // 表示进攻得分和防守得分
    149                             int attack = CheckMax(i, j, WHITE);
    150                             int defend= CheckMax(i, j, BLACK);
    151                             int max = Math.max(attack, defend);
    152                             // 获取最大值,并记录下标
    153                             if (max > maxValue) {
    154                                 tempRow = i;
    155                                 tempCol = j;
    156                                 maxValue = max;
    157                             }
    158                         }
    159                     }
    160                     //如果当前计算机没有找到下棋的位置,表明为平局
    161                     if(tempCol<0||tempRow<0){
    162                         JOptionPane.showMessageDialog(null, "平局");
    163                         clear();
    164                         return;
    165                     }else{
    166                     // 计算机下白棋,下完之后人下黑棋,画一遍
    167                         chessItems[tempRow][tempCol] = WHITE;
    168                         lastpoint.x=tempRow;
    169                         lastpoint.y=tempCol;
    170                         repaint();
    171                     }
    172                     // 计算机下完棋之后便判断自己是否已经获胜
    173                     if (checkImage(tempRow, tempCol)) {
    174                         JOptionPane.showMessageDialog(null, "你输了");
    175                         clear();
    176                         return;
    177                     }
    178                 }
    179                 //计算机查看当前位置(黑棋与白棋)
    180                 private int CheckMax(int row, int col, int current_colorpointer) {
    181                     //max记录最大的期望,而tempmax记录当前的期望
    182                     int max=0,tempmax=0;
    183                     //判断当前是进攻还是防守
    184                     String[] array=current_colorpointer==WHITE?attackstring:defendstring;
    185                     //用一个字符串存放当前的状态
    186                     StringBuilder stringBuilder=new StringBuilder();
    187                     //水平方向
    188                     for (int i = -4; i <= 4; i++) {
    189                         int Newcol = col + i;
    190                         if (Newcol<0 ||Newcol >= LINE_COUNT) {
    191                             continue;
    192                         }
    193                         //假装先把这个位置下棋,实质上并没有下棋
    194                         if(i==0){
    195                             stringBuilder.append(current_colorpointer);
    196                         }else{
    197                             stringBuilder.append(chessItems[row][Newcol]);
    198                         }
    199                     }
    200                     for(int i=0;i<array.length;i++){
    201                         String string=array[i];
    202                         //查找匹配字符串数组,并计算出期望值,找到即跳出循环
    203                         if(stringBuilder.indexOf(string)>=0){
    204                             max=score[i];
    205                             break;
    206                         }
    207                     }
    208                     //如果当前为最大的期望,即可以获胜,就直接return
    209                     if(max==100){
    210                         return max;
    211                     }
    212                     //每次在每个方向判断之后,应该清空当前的stringBuilder字符串
    213                     stringBuilder.delete(0, stringBuilder.length());
    214                     //垂直方向
    215                     for (int i = -4; i <= 4; i++) {
    216                         int Newrow = row + i;
    217                         if (Newrow<0 ||Newrow >= LINE_COUNT) {
    218                             continue;
    219                         }
    220                         if(i==0){
    221                             stringBuilder.append(current_colorpointer);
    222                         }else{
    223                             stringBuilder.append(chessItems[Newrow][col]);
    224                         }
    225                     }
    226                     tempmax=0;
    227                     for(int i=0;i<array.length;i++){
    228                         String string=array[i];
    229                         if(stringBuilder.indexOf(string)>=0){
    230                             tempmax=score[i];
    231                             break;
    232                         }
    233                     }
    234                     if(max<tempmax){
    235                         max=tempmax;
    236                     }
    237                     if(max==100){
    238                         return max;
    239                     }
    240                     //每次在每个方向判断之后,应该清空当前的stringBuilder字符串
    241                     stringBuilder.delete(0, stringBuilder.length());
    242                     //负45°
    243                     for (int i = -4; i <= 4; i++) {
    244                         int Newrow = row + i;
    245                         int Newcol = col + i; 
    246                         if ((Newrow<0 ||Newrow >= LINE_COUNT||Newcol<0 ||Newcol >= LINE_COUNT)) {
    247                             continue;
    248                         }
    249                         if(i==0){
    250                             stringBuilder.append(current_colorpointer);
    251                         }else{
    252                             stringBuilder.append(chessItems[Newrow][Newcol]);
    253                         }
    254                     }
    255                     tempmax=0;
    256                     for(int i=0;i<array.length;i++){
    257                         String string=array[i];
    258                         if(stringBuilder.indexOf(string)>=0){
    259                             tempmax=score[i];
    260                             break;
    261                         }
    262                     }
    263                     if(max<tempmax){
    264                         max=tempmax;
    265                     }
    266                     if(max==100){
    267                         return max;
    268                     }
    269                     //每次在每个方向判断之后,应该清空当前的stringBuilder字符串
    270                     stringBuilder.delete(0, stringBuilder.length());
    271                     //正45°
    272                     for (int i = -4; i <= 4; i++) {
    273                         int Newrow = row + i;
    274                         int Newcol = col - i; 
    275                         if ((Newrow<0 ||Newrow >= LINE_COUNT||Newcol<0 ||Newcol >= LINE_COUNT)) {
    276                             continue;
    277                         }
    278                         if(i==0){
    279                             stringBuilder.append(current_colorpointer);
    280                         }else{
    281                             stringBuilder.append(chessItems[Newrow][Newcol]);
    282                         }
    283                     }
    284                     tempmax=0;
    285                     for(int i=0;i<array.length;i++){
    286                         String string=array[i];
    287                         if(stringBuilder.indexOf(string)>=0){
    288                             tempmax=score[i];
    289                             break;
    290                         }
    291                     }
    292                     if(max<tempmax){
    293                         max=tempmax;
    294                     }
    295                     if(max==100){
    296                         return max;
    297                     }
    298                     return max;
    299                 }
    300             });
    301         }
    302 
    303         /**
    304          * 调用public void paintComponent(Graphics arg0){};方法画图
    305          */
    306         public void paintComponent(Graphics g) {
    307             // 系统调用
    308             super.paintComponent(g);
    309             // g.setColor(Color.yellow);
    310             // g.fillRect(0, 0, jPanel.width(),jPanel.height());
    311             /**
    312              * 画横线,起始位置在窗口左上定点(GRID_WIDTh/2,GRID_WIDTh/2)
    313              */
    314             for (int i = 0; i < LINE_COUNT; i++) {
    315                 int x1 = GRID_WIDTh / 2;
    316                 int y1 = GRID_WIDTh / 2 + i * GRID_WIDTh;
    317                 int x2 = x1 + (LINE_COUNT - 1) * GRID_WIDTh;
    318                 int y2 = y1;
    319                 // 画线
    320                 g.drawLine(x1, y1, x2, y2);
    321             }
    322             /**
    323              * 画竖线
    324              */
    325             for (int i = 0; i < LINE_COUNT; i++) {
    326                 int x1 = GRID_WIDTh / 2 + i * GRID_WIDTh;
    327                 int y1 = GRID_WIDTh / 2;
    328                 int x2 = x1;
    329                 int y2 = y1 + (LINE_COUNT - 1) * GRID_WIDTh;
    330                 // 画线
    331                 g.drawLine(x1, y1, x2, y2);
    332             }
    333             /**
    334              * 遍历这个数组
    335              */
    336             for (int row = 0; row < LINE_COUNT; row++) {
    337                 for (int col = 0; col < LINE_COUNT; col++) {
    338                     // 判断数组当前值,来画棋子
    339                     switch (chessItems[row][col]) {
    340                     case WHITE:
    341                         chessItem(row, col, Color.WHITE, g);
    342                         //每次画完计算机下完白棋之后,在白棋上面画一个方框
    343                         chessface(lastpoint,Color.RED, g);
    344                         break;
    345                     case BLACK:
    346                         chessItem(row, col, Color.BLACK, g);
    347                         break;
    348                     }
    349                     repaint();
    350                 }
    351             }
    352         };
    353 
    354         /**
    355          * 清空数组,便于下次下棋
    356          */
    357         private void clear() {
    358             for (int row = 0; row < LINE_COUNT; row++) {
    359                 for (int col = 0; col < LINE_COUNT; col++) {
    360                     // 全部置为0
    361                     chessItems[row][col] = 0;
    362                 }
    363             }
    364             // 重画一遍棋盘
    365             repaint();
    366         }
    367 
    368         /**
    369          * 用于判断是否已经取胜
    370          * 
    371          * @param row
    372          * @param col
    373          * @return
    374          */
    375         private boolean checkImage(int row, int col) {
    376             /**
    377              * 判断横行是否win
    378              */
    379             StringBuilder stringBuilder = new StringBuilder();
    380             // 记录当前存在字符串中的数据个数
    381             int count = 0;
    382             for (int i = -4; i <= 4; i++) {
    383                 int Newcol = col + i;
    384                 if (Newcol >= 0 && Newcol < LINE_COUNT) {
    385                     count++;
    386                     stringBuilder.append(chessItems[row][Newcol]);
    387                 }
    388             }
    389             if (stringBuilder.indexOf("11111") >= 0
    390                     || stringBuilder.indexOf("22222") >= 0) {
    391                 return true;
    392             } else {
    393                 // 如果当前不能赢,则清空字符串
    394                 stringBuilder.delete(0, count);
    395                 count = 0;
    396             }
    397             /**
    398              * 判断竖行是否win
    399              */
    400             for (int i = -4; i <= 4; i++) {
    401                 int Newrow = row + i;
    402                 if (Newrow >= 0 && Newrow < LINE_COUNT) {
    403                     count++;
    404                     stringBuilder.append(chessItems[Newrow][col]);
    405                 }
    406             }
    407             if (stringBuilder.indexOf("11111") >= 0
    408                     || stringBuilder.indexOf("22222") >= 0) {
    409                 return true;
    410             } else {
    411                 stringBuilder.delete(0, count);
    412                 count = 0;
    413             }
    414             /**
    415              * 判断负45°是否win
    416              */
    417             for (int i = -4; i <= 4; i++) {
    418                 int Newcol = col + i;
    419                 int Newrow = row + i;
    420                 if (Newcol >= 0 && Newcol < LINE_COUNT && Newrow >= 0
    421                         && Newrow < LINE_COUNT) {
    422                     count++;
    423                     stringBuilder.append(chessItems[Newrow][Newcol]);
    424                 }
    425             }
    426             if (stringBuilder.indexOf("11111") >= 0
    427                     || stringBuilder.indexOf("22222") >= 0) {
    428                 return true;
    429             } else {
    430                 stringBuilder.delete(0, count);
    431                 count = 0;
    432             }
    433             /**
    434              * 判断正45°是否win
    435              */
    436             for (int i = -4; i <= 4; i++) {
    437                 int Newcol = col + i;
    438                 int Newrow = row - i;
    439                 if (Newcol >= 0 && Newcol < LINE_COUNT && Newrow >= 0
    440                         && Newrow < LINE_COUNT) {
    441                     count++;
    442                     stringBuilder.append(chessItems[Newrow][Newcol]);
    443                 }
    444             }
    445             if (stringBuilder.indexOf("11111") >= 0
    446                     || stringBuilder.indexOf("22222") >= 0) {
    447                 return true;
    448             } else {
    449                 stringBuilder.delete(0, count);
    450                 count = 0;
    451             }
    452             return false;
    453         }
    454 
    455         // 画棋子
    456         public void chessItem(int row, int col, Color color, Graphics graphics) {
    457             // x与y分别代表在面板上的位置
    458             int x = col * GRID_WIDTh;
    459             int y = row * GRID_WIDTh;
    460             //判断是白棋还是黑棋
    461             Image image=Color.BLACK.equals(color)?blackImage:whiImage;
    462             graphics.drawImage(image, x, y, GRID_WIDTh, GRID_WIDTh, this);
    463 //            graphics.setColor(color);
    464 //            // 画圆
    465 //            graphics.fillOval(x, y, GRID_WIDTh, GRID_WIDTh);
    466         }
    467         /**
    468          * 为计算机画白棋定义一个方法,用于在计算机下白棋的棋子上画一个方框,表示是当前的棋子
    469          * @param point
    470          * @param color
    471          * @param graphics
    472          */
    473         public void chessface(Point point, Color color, Graphics graphics ){
    474             int x = point.y * GRID_WIDTh;
    475             int y = point.x * GRID_WIDTh;
    476             graphics.setColor(color);
    477             graphics.drawRect(x+GRID_WIDTh/4, y+GRID_WIDTh/4, GRID_WIDTh/2, GRID_WIDTh/2);
    478         }
    479     }
    480 
    481     public static void main(String[] args) {
    482         /**
    483          * 使用一个java类来创建一个主类为wuziqijiemianDemo,其中的窗口与棋盘为该主类的内部类
    484          */
    485         // 使用类部类的方式创建一个窗口引用对象(方式为 外部类名.内部类名 变量名=new 外部类名().new 内部类名();)
    486         wuziqijiemianDemo.Myjframe myjframe = new wuziqijiemianDemo().new Myjframe();
    487         // 设置窗口可见
    488         myjframe.setVisible(true);
    489     }
    490 
    491 }
  • 相关阅读:
    2019-2020-1学期 20192413 《网络空间安全专业导论》第九周学习总结
    2019-2020-1学期 20192413 《网络空间安全专业导论》第八周学习总结
    175210《网络对抗技术》Exp9 Web安全基础
    175210闵天 《网络对抗技术》Exp8 Web基础
    175210《网络对抗技术》Exp7 网络欺诈防范
    175210课设个人报告
    175210 Exp6 MSF基础应用
    175210课设第三次报告
    175210 《网络对抗技术》 Exp5 信息搜集与漏洞扫描
    175210课设第二次报告
  • 原文地址:https://www.cnblogs.com/0405mxh/p/10173137.html
Copyright © 2011-2022 走看看