简单五子棋

一口气写了2篇博文。。这是第三篇。。有点小累。。不废话,上图

 


简单五子棋
 

好吧。我承认。。这是我和我女朋友的头像。。没办法。。她逼我改成这样的。。也算是秀甜蜜啦~~

又开始废话了。。。上主函数:

publicclass Main extends JFrame {

    privateintlength = 16;

    privateintheight = 27;

    privateintx0 = 130;

    privateinty0 = 130;

    privateintsize = 40;

    privateint[][] zi = newint[29][16];

    private JPanel jp10;

    private ImageIcon imageicon1,imageicon2,imageicon3;

    private Image image1,image2,image3;

 

 

    publicstaticvoid main(String[] args) {

       Main jf = new Main();

       jf.unite();

    }

 

    privatevoid unite() {

       //读取保存图片

       imageicon1 = new ImageIcon(

              "C:/Users/john/Desktop/QQ图片20130612113822.jpg");

       image1 = imageicon1.getImage();

       imageicon2 = new ImageIcon(

              "C:/Users/john/Desktop/QQ图片20130611085022.jpg");

       image2 = imageicon2.getImage();

       //设置窗体

       this.setTitle("聪明蛋的棋盘");

       this.setSize(new Dimension(600, 600));

       this.setResizable(true);

       this.setDefaultCloseOperation(EXIT_ON_CLOSE);

       this.setLocationRelativeTo(null);

       // 设置窗体边框布局

       BorderLayout bl = new BorderLayout();

       this.setLayout(bl);

       // 设置中心面板

       JPanel jp0 = new JPanel();

       jp0.setLayout(null);

       setjp0(jp0);

       jp0.setBackground(new Color(255, 255, 255));

       this.add(jp0, BorderLayout.CENTER);

 

       this.setVisible(true);

       Graphics g = this.getGraphics();

       // 设置东面板

       JPanel jp = new JPanel();

       jp.setPreferredSize(new Dimension(200, 100));

       imageicon3 = new ImageIcon(

              "C:/Users/john/Desktop/QQ图片20130612113822.jpg");

       image3 = imageicon3.getImage();

       this.add(jp, BorderLayout.EAST);

       // 加悔棋按钮

       JButton jb = new JButton("聪明蛋要悔棋");

       Font font1 = new Font("宋体", 1, 14);

       JButton ja = new JButton("聪明蛋耍赖了要先走-_-");

       JButton jc = new JButton("聪明蛋玩不下去了要重来。。");

       jc.setPreferredSize(new Dimension(400, 40));

       jc.setFont(font1);

       ja.setFont(font1);

       jb.setFont(font1);

       // 设置北面板

       JPanel jp2 = new JPanel();

       Font font2 = new Font("楷体", 1, 50);

    JLabel jl = new JLabel("~宝贝蛋先走哦~~");

       jl.setFont(font2);

       jp2.add(jl);

       this.add(jp2, BorderLayout.NORTH);

       mouselis moulis = new mouselis(g, this);

       zi = moulis.returnzi();

       actionlis ac = new actionlis(moulis);

       actionlis2 ac2 = new actionlis2(moulis);

       actionlis3 ac3 = new actionlis3(moulis);

       ja.addActionListener(ac2);

       jb.addActionListener(ac);

       jc.addActionListener(ac3);

       jp.add(ja);

       jp.add(jb);

       jp.add(jc);

       this.addMouseListener(moulis);

    }

    publicvoid paint(Graphics g) {

       super.paint(g);

       g.setColor(Color.BLACK);

       for (int i = 0; i < length - 1; i++) {

           g.drawLine(x0-size, y0 + i * size, x0 + (height - 2) * size, y0+ i * size);

       }

       for (int i = 0; i < height; i++) {

           g.drawLine(x0 + (i - 1) * size, y0, x0 + (i - 1) * size, y0

                  + (length - 2) * size);

       }

       List li = new List();

       for (int a = 1; a < 28; a++) {

           for (int b = 1; b < length; b++) {

              if (zi[a][b] == 1) {

                  g.drawImage(image1, 114 + (a - 2) * 40, 114 + (b - 1) * 40,146 + (a - 2) * 40, 146 + (b - 1) * 40, 0, 0, 345,345, null);

       } elseif (zi[a][b] == 2) {

           g.drawImage(image2, 114 + (a - 2) * 40, 114 + (b - 1) * 40,146 + (a - 2) * 40, 146 + (b - 1) * 40, 0, 0, 170,170, null);

              }

           }

       }

    }

 

    privatevoid setjp0(JPanel jp10) {

       this.jp10 = jp10;

    }

 

    private JPanel getjp0() {

       returnjp10;

    }

}

图片读取的方法找得我真的好辛苦好辛苦。。。最后居然只用这么点代码。。

imageicon1 = new ImageIcon(

              "C:/Users/john/Desktop/QQ图片20130612113822.jpg");

image1 = imageicon1.getImage();

最后一行代码是一样需要的,因为g.drawImage这个方法只能画Image类的图,所以一定要从ImageIcon中提取出Image,才能画在画布上。

重绘方法是为了防止用户把界面最小化或者拖动造成棋子全部消失的情况。使用了重绘方法就可以防止这一情况的发生。而重绘时的棋子的位置则是使用了队列的思路,下面上代码:

publicclass List {

    private qi qizi[][] = new qi[29][16];

    private Graphics g;

    privateintc = 0;

    public List() {

 

       for (int i = 0; i < 28; i++) {

           for (int j = 0; j < 16; j++) {

              qizi[i][j] = new qi();

           }

       }

       for (int i = 1; i < 28; i++) {

           for (int j = 1; j < 16; j++) {

              qizi[i][j].setX(140 + (i - 1) * 40);

              qizi[i][j].setY(140 + (j - 1) * 40);

 

           }

       }

    }

    protectedvoid draw(Graphics g, int a, int b) {

       g.fillOval(qizi[a][b].getX() - 25, qizi[a][b].getY() - 25, 30, 30);

    }

}

也算是队列吧。这个类就是用来保存和画出面板上的棋子的,qizi[4][5]就表示了第4行第5列的棋子,也是二维数组的一个应用。

下面上qi类的代码:

 

publicclass qi {

    privateintx = 0;

    privateinty = 0;

 

    publicint getX() {

       returnx;

    }

 

    publicvoid setX(int x) {

       this.x = x;

    }

 

    publicint getY() {

       returny;

    }

 

    publicvoid setY(int y) {

       this.y = y;

    }

 

}

没什么说的,很简单,上鼠标监听器代码:

 

publicclass mouselis extends MouseAdapter {

    private Graphics g;

    privateintx, y;

    private List list;

    privateinth = 1, a, b;

    privateint[][] zi = newint[28][16];

    private Main jf;

 

    private ImageIcon image;

    private Image image1;

    private ImageIcon image2;

    private Image image3;

 

    public mouselis(Graphics g, Main jf) {

       this.g = g;

       this.list = new List();

       this.jf = jf;

       image = new ImageIcon(

              "C:/Users/john/Desktop/QQ图片20130612113822.jpg");

       image1 = image.getImage();

       image2 = new ImageIcon(

              "C:/Users/john/Desktop/QQ图片20130611085022.jpg");

       image3 = image2.getImage();

    }

 

    public mouselis(Graphics g) {

       this.g = g;

       this.list = new List();

    }

 

    publicvoid mouseClicked(MouseEvent e) {

 

       image = new ImageIcon(

              "C:/Users/john/Desktop/QQ图片20130612113822.jpg");

       image1 = image.getImage();

       image2 = new ImageIcon(

              "C:/Users/john/Desktop/QQ图片20130611085022.jpg");

       image3 = image2.getImage();

       x = e.getX();

       y = e.getY();

        System.out.println(x+"    "+y);

       a = x / 20 / 2 - 1;

       b = y / 20 / 2 - 2;

       if (zi[a][b] == 0) {

           if (a > 0 && b > 0) {

              if (h % 2 == 0) {

                  g.drawImage(image1, 114 + (a - 2) * 40, 114 + (b - 1) * 40,146 + (a - 2) * 40, 146 + (b - 1) * 40, 0, 0, 345,345, jf);

              h++;

              zi[a][b] = 1;

              } else {

       g.drawImage(image3, 114 + (a - 2) * 40, 114 + (b - 1) * 40,146 + (a - 2) * 40, 146 + (b - 1) * 40, 0, 0, 170,170, jf);

                  h++;

                  zi[a][b] = 2;

              }

              panduan(a, b);

           }

       }

    }

 

    privatevoid panduan(int a, int b) {

       int count = 1;

       int c = 0;

       int d = 0;

       if (a < b) {

           c = a;

       } else {

           c = b;

       }

       if (a > b) {

           d = a;

       } else {

           d = b;

       }

       // 向右判断

       for (int i = a + 1; i < 28; i++) {

           if (zi[i][b] == zi[a][b]) {

              count++;

           } else {

              break;

           }

       }

       // 向左判断

       for (int i = a - 1; i > 0; i--) {

           if (zi[i][b] == zi[a][b]) {

              count++;

           } else {

              break;

           }

       }

       if (count >= 5) {

           if (zi[a][b] == 1) {

              JOptionPane.showMessageDialog(null, "聪明蛋获胜!");

           } elseif (zi[a][b] == 2) {

              JOptionPane.showMessageDialog(null, "宝贝蛋获胜!");

           }

           clear();

       }

 

       count = 1;

       // 向上判断

       for (int i = b - 1; i > 0; i--) {

           if (zi[a][i] == zi[a][b]) {

              count++;

           } else {

              break;

           }

       }

       // 向下判断

       for (int i = b + 1; i < 16; i++) {

           if (zi[a][i] == zi[a][b]) {

              count++;

           } else {

              break;

           }

       }

       if (count >= 5) {

           if (zi[a][b] == 1) {

              JOptionPane.showMessageDialog(null, "聪明蛋获胜!");

           } elseif (zi[a][b] == 2) {

              JOptionPane.showMessageDialog(null, "宝贝蛋获胜!");

           }

           clear();

       }

       count = 1;

       // 向左上方判断

       for (int i = 1; (c - i) > 0; i++) {

           if (zi[a][b] == zi[a - i][b - i]) {

              count++;

           } else {

              break;

           }

       }

       // 向右下方判断

       for (int i = 1; (d + i) < 28; i++) {

           if (zi[a][b] == zi[a + i][b + i]) {

              count++;

           } else {

              break;

           }

       }

       if (count >= 5) {

           if (zi[a][b] == 1) {

              JOptionPane.showMessageDialog(null, "聪明蛋获胜!");

           } elseif (zi[a][b] == 2) {

              JOptionPane.showMessageDialog(null, "宝贝蛋获胜!");

           }

           clear();

       }

       count = 1;

       // 向右上方判断

       for (int i = 1; (a + i) < 28 && (b - i) > 0; i++) {

           if (zi[a][b] == zi[a + i][b - i]) {

              count++;

           } else {

              break;

           }

       }

       // 向左下方判断

       for (int i = 1; (a - i) > 0 && (b + i) < 28; i++) {

           if (zi[a][b] == zi[a - i][b + i]) {

              count++;

           } else {

              break;

           }

       }

       if (count >= 5) {

           if (zi[a][b] == 1) {

              JOptionPane.showMessageDialog(null, "聪明蛋获胜!");

           } elseif (zi[a][b] == 2) {

              JOptionPane.showMessageDialog(null, "宝贝蛋获胜!");

           }

           clear();

       }

    }

 

    publicint[][] returnzi() {

       returnzi;

    }

 

    publicvoid print(int x, int y) {

       System.out.println(zi[x][y]);

    }

 

    privatevoid clear() {

       for (int i = 0; i < 28; i++) {

           for (int j = 0; j < 16; j++) {

              zi[i][j] = 0;

              h = 1;

           }

       }

       jf.paint(g);

    }

 

    publicvoid huiqi() {

       if (zi[a][b] == 1) {

           zi[a][b] = 0;

           h++;

           jf.paint(g);

       }

    }

 

    publicvoid changefirst() {

       h = 0;

    }

 

    publicvoid chonglai() {

       clear();

    }

}

在面板上任意点一个位置都要把棋子画在网格的中心,这个还是需要逻辑的,也是纯粹的逻辑。每生成一个棋子判断一次输赢应该是全部五子棋都要做的,可是怎么判断每个人有不同的想法,很多人的做法是遍历整个棋盘来判断,但我觉得那样做计算量很大,效率不高,所以我采用的方法是在新创建的棋子周围寻找有没有五个连续的来判断输赢,算是高效率吧。

上改变第一个走的人的代码:

publicclass actionlis2 implements ActionListener{

    public mouselis mouse;

   

    public actionlis2(mouselis mouse){

    this.mouse = mouse;

    }

    publicvoid actionPerformed(ActionEvent e) {

       mouse.changefirst();

    }

}

上重新开始的代码:

publicclass actionlis3 implements ActionListener{

   public mouselis mouse;

   

    public actionlis3(mouselis mouse){

    this.mouse = mouse;

    }

 

    publicvoid actionPerformed(ActionEvent e) {

              mouse.chonglai();

    }

 

}

上悔棋代码:

publicclass actionlis implements ActionListener{

    public mouselis mouse;

   

    public actionlis(mouselis mouse){

    this.mouse = mouse;

    }

    publicvoid actionPerformed(ActionEvent e) {

       mouse.huiqi();

      

    }

 

}

3个按钮监听器都是需要鼠标监听器的对象的,因为对应的方法都封装在了鼠标监听器里面,一来不用到处传参,二来起到了封装的效果。