Java五子棋(1)

做五子棋小游戏分两个步骤
一、首先实现画棋盘,下棋子,悔棋,判断输赢。
二、AI(权值算法)

本篇先介绍第一个步骤。
那么我们可以分几个步骤走(我是按照我的思路来制作的)
1.加窗体,棋盘可以画在一个容器里,然后添加到窗体,然后按钮就分布在窗体北部。
2.棋盘的一些参数,比如X,Y值,棋盘的行和列等,这些可以放在一个类,都是定义为常量,因为后面还会有其他类,所以作为接口类便好。
3.加监听器,这时候我们引入一个新的东西,因为鼠标监听器的那些方法,有些事我们不需要的,所以我们不需要所以,我们就只需要一两个方法就好啦。

MouseAdapter

4.画棋子,我们就要找到点击的点是要画在棋盘的哪个交点,这里先讨论手动下棋,获取点击的X,Y坐标,通过计算就可以找到在哪个交点啦,因为我们不能保证点击的地方一定会在交点的地方,所以我们划分范围,靠近交点的1/2size的时候那就为此交点。
5.重绘,跟画图形很相似的点就是,需要存储响应的数据,比如棋子的位置,棋子的颜色,因为只有黑白棋,所以我们可以把下标分类为奇数或者偶数,这样,另外可以用二维数组存储交点值,从而重绘。
6.做悔棋,我们画棋子时,可以用一个计数count,用来作为存储画的交点值的矩形的下标,当悔棋的时候,只用去除最后面的交点的位置,从而让棋盘相应的交点为0,0即不画。最后重绘;
7.判断输赢,只有四种情况,横竖左斜右斜;
8.判断出输赢之后弹出一个窗体,是我表示白子还是黑子赢。

理论的知识就差不多啦,其实实现起来还是比较简单了,但是对于新手来说,记得慢慢阅读上面的步骤。下面主要展示我的代码。
1.这是我放主函数的类

public class GameUI extends JPanel{
 public void showBorder()
 {
  JFrame jf=new JFrame();
  jf.setTitle("五子棋2.0");
  jf.setSize(750, 700);
  //窗体不可变
  jf.setResizable(false);
  jf.setLocationRelativeTo(null);
  jf.setDefaultCloseOperation(3); 
  
  Listener listener=new Listener();
  
  JPanel jp=new JPanel();
  jp.setPreferredSize(new Dimension(0,50));
  jf.add(jp, BorderLayout.NORTH);
  String [] bu={"开始","认输","悔棋","人机对战","人人对战"};
  for(int i=0;i<bu.length;i++)
  {
   JButton but=new JButton(bu[i]);
   jp.add(but);
   but.addActionListener(listener);
  }
  ChessJPanel cp=new ChessJPanel();
  jf.add(cp, BorderLayout.CENTER);
  cp.addMouseListener(listener);
  jf.setVisible(true);
  Graphics g=cp.getGraphics();
  listener.setGr(g);
  listener.setCp(cp); 
 }
 public static void main(String[] args)
 {
  GameUI cb=new GameUI();
  cb.showBorder();
 }
}

2.棋盘参数

public interface Config {
 public static final int X0=80;
 public static final int Y0=40;
 public static final int SIZE=40;
 public static final int LINE=15;
 public static final int [][] chessArray=new int[LINE][LINE];
}

3.添加监听器

public class Listener extends MouseAdapter implements ActionListener,Config
 public int[][] chessArray()
 {
  return chessArray;
 }
 public void setGr(Graphics g)
 {
  gr=g;
 }
 public void setCp(ChessJPanel cp1)
 {
  this.cp=cp1;
 }

这些是必写方法
4.画棋子

gr.fillOval(a*SIZE+X0-SIZE/2, b*SIZE+Y0-SIZE/2, SIZE-5, SIZE-5);

其中a,b是我们算出来的数组棋盘的位置。
5.重绘

public class ChessJPanel extends JPanel implements Config{
 private ImageIcon image;
 
 public ChessJPanel(){
  image = new ImageIcon("E:\\五子棋4.jpg");
 }
 
 public void paint(Graphics g)
 {
  super.paint(g);
//  g.setColor(new Color(104,162,129));
//  g.fillRect(X0, Y0, (LINE-1)*SIZE, (LINE-1)*SIZE);
  
  //画图片
  g.drawImage(image.getImage(), 0, 0, this.getWidth(),this.getHeight(),null);
  g.setColor(Color.DARK_GRAY);
  for(int i=0;i<LINE;i++)
  {
   g.drawLine(X0, Y0+i*SIZE, (LINE-1)*SIZE+X0, Y0+i*SIZE);
   g.drawLine(X0+i*SIZE, Y0, X0+i*SIZE, (LINE-1)*SIZE+Y0);
  }
  Repaint(g);
 }
 private void Repaint(Graphics g)
 {
  
  for(int i=0;i<LINE;i++)
  {
   for(int j=0;j<LINE;j++)
   {
    if(chessArray[i][j]==1)
    {
     g.setColor(Color.BLACK);
     g.fillOval(i*SIZE+X0-SIZE/2, j*SIZE+Y0-SIZE/2, SIZE-5, SIZE-5);
    }
    if(chessArray[i][j]==2)
    {
     g.setColor(Color.WHITE);
     g.fillOval(i*SIZE+X0-SIZE/2, j*SIZE+Y0-SIZE/2, SIZE-5, SIZE-5);
    }
   }
  }
 }
}

6.悔棋

 //悔棋方法
 public void huiqi()
 {
  System.out.println();
  if(Ai==1)
  {
   count--;
   int a=order[count][0];
   int b=order[count][1];
   
   chessArray[a][b]=0;
   System.out.println(name+" "+count+" "+a+" "+b);
   count--;
   int a1=order[count][0];
   int b1=order[count][1];
   chessArray[a1][b1]=0;
   System.out.println(name+" "+count+" "+a1+" "+b1);
   
  }
  else if(Ai!=1)
  {
   count--;
   int a=order[count][0];
   int b=order[count][1];
   chessArray[a][b]=0;
  }
  cp.paint(gr);
 }

7.判断输赢

 public void checkwin()
 {
  for(int i=0;i<LINE;i++)
  {
   for(int j=0;j<LINE;j++)
   {
    if(chessArray[i][j]==flag)
    {
     c1++;
     if(c1==5)
     {
      vector=1;
      cout();
      break;
     }
    }
    else
     c1=0;
    if(chessArray[j][i]==flag&&vector!=1)
    {
     c2++;
     if(c2==5)
     {
      vector=1;
      cout();
      break;
     }
    }
    else
     c2=0;
   }
   if(vector==1)
    break;
  }
  if(vector==0)
  {
   c1=0;
   for(int i=0;i<LINE-5;i++)
   {
    for(int j=0;j<LINE-5;j++)
    {
     for(int z=0;z<5;z++)
     {
      if(chessArray[i+z][j+z]==flag)
      {
       c1++;
      }
      else if(chessArray[i+z][j+z]!=flag)
      {
       c1=0;
       break;
      }
     }
     if(c1==5)
     {
      vector=1;
      cout();
      break;
     }
    }
    if(c1==5)
     break;
   }
  }
  if(vector==0)
  {
   c1=0;
   for(int i=LINE-1;i>=5;i--)
   {
    for(int j=LINE-5;j>=0;j--)
    {
     for(int z=0;z<5;z++)
     {
      if(chessArray[i-z][j+z]==flag)
      {
       c1++;
      }
      else if(chessArray[i-z][j+z]!=flag)
      {
       c1=0;
       break;
      }
     }
     if(c1==5)
     {
      vector=1;
      cout();
      break;
     }
    }
    if(c1==5)
     break;
   }
  }
 }

8.输出

 public void cout()
 {
  if(flag==2)
   Win();//System.out.println("白棋胜");
  else
   Win();//System.out.println("黑棋胜");
 }
 //赢就会跳出的界面
 public void Win()
 {
  JFrame jf2 = new JFrame();
  jf2.setSize(400, 300);   
  jf2.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
  jf2.setLocationRelativeTo(null);
  java.awt.FlowLayout flow = new java.awt.FlowLayout();
  jf2.setLayout(flow);
  if(flag==1)
  {
   ImageIcon Page = new ImageIcon("E:\\black.png");
   JLabel jla = new JLabel(Page);
   Dimension du = new Dimension(400, 300);
   jla.setPreferredSize(du);
   jf2.add(jla);
  }
  else if(flag==2)
  {
   ImageIcon Page = new ImageIcon("E:\\white.png");
   JLabel jla = new JLabel(Page);
   Dimension du = new Dimension(400, 300);
   jla.setPreferredSize(du);
   jf2.add(jla);
  }
  jf2.setVisible(true);   
 }

猜你喜欢

转载自blog.csdn.net/chan_fan/article/details/83897492