简单的五子棋操作用两种方法实现

来源:互联网 发布:爱因斯坦名言知乎 编辑:程序博客网 时间:2024/05/16 19:19

最近有五子棋的大作业,周折半天才弄明白其中的原理,查阅了许多资料,然后网上的代码只有几篇原创并且注释很少,感觉不好理解。所以感觉有必要分享一下自己的心得
本人使用两种方法:
1:(传统方法)鼠标点击事件。大致流程为 定义窗口——从写JPanel中的paint函数(画图由paint实现)——画棋盘——设置数组储存坐标以及是否有棋子——添加鼠标点击事件画棋子(判断鼠标点击的位置离此点最近的那个店的坐标并画棋子)——判断是否有胜利
1)这里说一下paint函数,paint函数定义在那个界面里他会自动执行画图不需要调用,所以你只需要写好约束的事件让他画完棋盘后该什么时候在哪里画棋子。
2)repaint 函数是起到重画作用,你点击过后再最近的那个店需要画棋子,repaint就起到从画的作用
3)本人判断成行的方法是分别定义四个变量代码五子棋个数,当》=5时停止。弹出新的窗口。具体是如果此点左右都有相同颜色的棋子,就吧这个点向左找到一直颜色不同为止,然后从这点向下(右)直接计数。
4)本人的棋子是画出来的,如果追求美观可以用image方法使用下载下来的图片棋子(但是思想一致)。
附上代码和注释:

import java.awt.Color;import java.awt.Component;import java.awt.Container;import java.awt.FlowLayout;import java.awt.Font;import java.awt.Graphics;import java.awt.GridLayout;import java.awt.Point;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import javax.swing.*;public class wuziqi extends JFrame {     void judgle(int a[][],int i,int j)    {         //需要定义两个变量(作用相同)一个判断黑棋子,一个判断白棋        int k=1; int kk=1;//判断横方向 int l=1;int kl=1;//判断竖方向 int  k1=1;int kk1=1;//判断左上和右下方向     int  k2=1;  int kk2=1;//判断左下和右上方向      //横方向的判断       int m=i;int n=j;int m1=i;int n1=j;       int m2=i;int n2=j;       while(m-1>=0&&a[m-1][j]==1) {m--;}//上下判断       while(m<18&&a[m+1][j]==1) {k++;m++;} //左右判断            //    while(n-1>=0&&a[i][n-1]==1) {n--;}    while(n<18&&a[i][n+1]==1) {l++;n++;}        //左上右下    while(m1-1>=0&&n1-1>=0&&a[m1-1][n1-1]==1) {m1--;n1--;}    while(m1<18&&n1<18&&a[m1+1][n1+1]==1) {k1++;m1++;n1++;}         //左下右上方向          while(m2-1>=0&&n2+1<19&&a[m2-1][n2+1]==1) {m2--;n2++;}    while(m2<18&&n2-1>=0&&a[m2+1][n2-1]==1) {k2++;m2++;n2--;}      m=i; n=j; m1=i; n1=j;     m2=i; n2=j;    while(m-1>=0&&a[m-1][j]==2) {m--;}//上下判断    while(m<18&&a[m+1][j]==2) {kk++;m++;} //左右判断     //       while(n-1>=0&&a[i][n-1]==2) {n--;}      while(n<18&&a[i][n+1]==2) {kl++;n++;}      //左上右下       while(m1-1>=0&&n1-1>=0&&a[m1-1][n1-1]==2) {m1--;n1--;}      while(m1<18&&n1<18&&a[m1+1][n1+1]==2) {kk1++;m1++;n1++;}     //左下右上方向            while(m2-1>=0&&n2+1<19&&a[m2-1][n2+1]==2) {m2--;n2++;}      while(m2<18&&n2-1>=0&&a[m2+1][n2-1]==2) {kk2++;m2++;n2--;}      if(k>=5||l>=5||k1>=5||k2>=5||kk>=5||kl>=5||kk1>=5||kk2>=5) {          setTitle("游戏已结束");JFrame frame=new JFrame ("恭喜获胜");        Container c=frame.getContentPane();     c.setLayout(new GridLayout(4,1,0,0) );     if(a[i][j]==1) {     JLabel label=new JLabel("恭喜黑色赢了",JLabel.CENTER);     label.setFont(new Font("宋体",0,35));c.add(label);}     if(a[i][j]==2) {        JLabel label=new JLabel("恭喜白色赢了",JLabel.CENTER);        label.setFont(new Font("宋体",0,35));c.add(label);}        JButton b1=new JButton("再来一把");        JButton b2=new JButton("结     束");        b1.setFocusPainted(false);         b2.setFocusPainted(false);         c.add(new JLabel(""));          c.add(b1);        b1.setBackground(Color.YELLOW);        c.add(b2);        c.setBackground(Color.red);        frame.setSize(300, 300);        frame.setLocationRelativeTo(null);        frame.setVisible(true);//顺序问题        frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);           b1.addActionListener(new  ActionListener() {//建立监听事件         public void actionPerformed(ActionEvent e) { if(b1==e.getSource())         for(int i=0;i<19;i++)        for(int j=0;j<19;j++)        {a[i][j]=0;}        frame.dispose();repaint(); } });//关闭当前窗口        b2.addActionListener(new  ActionListener() {//建立监听事件        public void actionPerformed(ActionEvent e) {if(b2==e.getSource())System.exit(0);//关闭所有                             } });      setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); }}public wuziqi() {        setTitle("这是一个五子棋游戏");        setVisible(true);        Container c = getContentPane();        DrawPanel1 jp1 = new DrawPanel1();        c.add(jp1);        setSize(1000, 1010);        jp1.setBackground(new Color(60,150,200));//随便赋值一个背景颜色        this.setResizable(false);        this.setLocationRelativeTo(null);//剧中放置,要在setsize后面放置        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);        c.addMouseListener(new MouseAdapter() {        public void mouseClicked(MouseEvent e) {        {        int x=0,y=0;        for (int i = 0; i < 19; i++) {        if (jp1.b4[i][2] >e.getX())        {if(i>0) {  if(e.getX()-jp1.b4[i-1][2]<jp1.b4[i][2] - e.getX()) //正常情况下判断这个点离左右那个点进         {x=i-1;}   else {x = i;}}        if(i==0) {x = i;}//在第一个点的左侧,选择第一个点           break;}        else {x=18;}}        for (int i = 0; i < 19; i++) {        if (jp1.b3[2][i] > e.getY())//找到点击的点右侧的最近那个坐标值        {        if(i>0) {  if(e.getY()-jp1.b3[2][i-1]<jp1.b3[2][i] - e.getY()) //正常情况下判断这个点离左右那个点进         {y=i-1;}   else {y = i;}}        if(i==0) {y = i;}//在第一个点的左侧,选择第一个点        break;}//如果全部不满足就取18        else {y=18;}        }        if(jp1.b2[x][y]==0) {//如果没旗子才可以画棋子,不然不可以画棋子        if(jp1.m%2==0) {        jp1.b2[x][y] = 1;}        else {jp1.b2[x][y] = 2;}        jp1.m++;        judgle(jp1.b2,x,y);        repaint();                }}            }        });    }    public static void main(String[] args) {        new wuziqi();    }    class DrawPanel1 extends JPanel {//重写Jpanel的paint方法        boolean b1[][] = new boolean[19][19];// 判断是否有棋子        int b2[][] = new int[19][19];// 存0.1.2代表没棋子,有黑棋子,白棋子        int b3[][] = new int[19][19];// 存纵坐标用        { int q1 = 50;        for(int j1 = 0;j1<19;j1++)//纵坐标赋值给核心j1        {            for(int i=0;i<19;i++)            {b3[i][j1]=q1;}q1=q1+50;}}        int b4[][] = new int[19][19];// 存横坐标        { int q2=50;          for(int i=0;i<19;i++) { for(int j=0;j<19;j++) {b4[i][j]=q2;}q2=q2+50;}         }         int m = 0;//判断奇数偶数给黑白也可以在主函数中定义static常量计算        public void paint(Graphics g) {            super.paint(g);//画棋盘            for (int i = 50; i <= 950; i = i + 50) {                g.drawLine(50, i, 950, i);                g.setColor(Color.black);            }            for (int i = 50; i <= 950; i = i + 50) {                g.drawLine(i, 50, i, 950);            }            for(int i=0;i<19;i++)//画棋子。这里的b[i][j]由前面的监听操作所决定                for(int j=0;j<19;j++) {            if(b2[i][j]==1)                    {                 g.setColor(Color.BLACK);                  g.fillOval(b4[i][j]-20, b3[i][j]-20,40, 40);}//前面是外接长方形的左上角点坐标所以要减去圆的半径            if(b2[i][j]==2)             {  g.setColor(Color.WHITE);              g.fillOval(b4[i][j]-20, b3[i][j]-20,40, 40);}     }}}}                               

运行结果
这里写图片描述
2:使用按钮的鼠标监听方法:具体思路为。先定义窗体使用网格布局方式布局按钮(按钮刚开始没有图标)然后画棋盘(注意)这个棋盘要根据实际情况调整,因为计算的不准确,网格布局两侧有缝隙影响位置的测试,所以需要你自己做出微调,然后给按钮建立鼠标监听事件,点击的按钮会被添加图标,这个图标就是你画的圆(或者下载的图片棋子)。按钮其实自己是有颜色和边框的,为了达到效果,要使用b[i][j].setContentAreaFilled(false);//透明b[i][j].setBorderPainted(false);//取消边框b[i][j].setFocusPainted(false); //取消焦点这三个函数。才能达到视觉效果。但是最后就是有问题白色的棋子无法遮住棋盘线,
有兴趣的大佬可以试试图片图标可以实现不。具体代码如下:

import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.*;import javax.xml.soap.Text;public class wuziqi2 extends JFrame{    static Color d=Color.white;    static int n=0;    static boolean[][]judgle=new boolean[19][19];//判断是否有棋子    static boolean[][]white=new boolean[19][19];//判断是否为白棋子    static boolean[][]black=new boolean[19][19];//判断是否为黑棋子    static JButton b[][]=new JButton[19][19];    public  void judgle1(boolean a[][],int i,int j)//用于判断是否成行    {   int k=1;//判断横方向        int l=1;//判断竖方向        int  k1=1;//判断左上和右下方向        int  k2=1;//判断左下和右上方向        // if(i>=0&&i<=18) {//横方向的判断        int m=i;int n=j;int m1=i;int n1=j;        int m2=i;int n2=j;        while(m-1>=0&&a[m-1][j]==true) {m--;}//上下判断        while(m<18&&a[m+1][j]==true) {k++;m++;} //左右判断            //       while(n-1>=0&&a[i][n-1]==true) {n--;}       while(n<18&&a[i][n+1]==true) {l++;n++;}        //左上右下        while(m1-1>=0&&n1-1>=0&&a[m1-1][n1-1]==true) {m1--;n1--;}        while(m1<18&&n1<18&&a[m1+1][n1+1]==true) {k1++;m1++;n1++;}         //左下右上方向           while(m2-1>=0&&n2+1<19&&a[m2-1][n2+1]==true) {m2--;n2++;}     while(m2<18&&n2-1>=0&&a[m2+1][n2-1]==true) {k2++;m2++;n2--;}              if(k>=5||l>=5||k1>=5||k2>5) {                           setTitle("游戏已结束");JFrame frame=new JFrame ("恭喜获胜");            Container c=frame.getContentPane();            c.setLayout(new GridLayout(4,1,0,0) );            JLabel label=new JLabel("恭喜你赢了",JLabel.CENTER);            label.setFont(new Font("宋体",0,35));            JButton b1=new JButton("再来一把");            JButton b2=new JButton("结     束");            b1.setFocusPainted(false);             b2.setFocusPainted(false);             c.add(new JLabel(""));            c.add(label);            c.add(b1);            b1.setBackground(Color.YELLOW);            c.add(b2);            c.setBackground(Color.red);            //c.add(b1);            //c.add(b2);            frame.setSize(300, 300);            frame.setLocationRelativeTo(null);            frame.setVisible(true);//顺序问题            frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);       b1.addActionListener(new  ActionListener() {//建立监听事件     public void actionPerformed(ActionEvent e) {        if(b1==e.getSource())               for(int i=0;i<19;i++)            for(int j=0;j<19;j++)            {judgle[i][j]=false; black[i][j]=false;              white[i][j]=false;b[i][j].setIcon(null);     frame.dispose();repaint(); }                     } });    b2.addActionListener(new  ActionListener() {//建立监听事件     public void actionPerformed(ActionEvent e) {if(b2==e.getSource())System.exit(0);                         } });               //System.exit(0);//结束             }        }    public wuziqi2()    {        setTitle("这是一个五子棋游戏");        //Container c=getContentPane();        //setLayout(new FlowLayout(2,10,10));//流布局管理器        DrawPanel1 d1=new DrawPanel1();        d1.setSize(950,950);        d1.setLayout(new GridLayout(19,19,0,0));//网格布局19行19列        d1.setBackground(new Color(0,200,200));        setResizable(false);        add(d1);        for(int i=0;i<19;i++) {        for(int j=0;j<19;j++) {b[i][j]=new JButton("");d1.add(b[i][j]); b[i][j].setContentAreaFilled(false);//透明        b[i][j].setBorderPainted(false);//取消边框        b[i][j].setFocusPainted(false); //取消焦点        }}        for(   int i=0;i<19;i++)        {   for(int j=0;j<19;j++)            b[i][j].addActionListener(new ActionListener() {//建立监听事件                 public void actionPerformed(ActionEvent e)                 {   for(  int i=0;i<19;i++){                     for(int j=0;j<19;j++)                     if(!judgle[i][j])                    if(e.getSource()==b[i][j])                    {                     if(n%2==0) {    drawlconw icon = new drawlconw(40, 40);white[i][j]=true;//有bai棋子                    b[i][j].setIcon(icon);judgle1(white,i,j);}                    if(n%2!=0) {    drawlconb icon = new drawlconb(40, 40);black[i][j]=true;//有hei棋子                    b[i][j].setIcon(icon);judgle1(black,i,j);}                    n++;//奇数偶数的计量方式,没有特别意义                    judgle[i][j]=true;//有了棋子                 }}                 }             });        }        setSize(950,950);        setLocationRelativeTo(null);//要放在sitsize后面,不然整个图形就在        setVisible(true);        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);    }    public static void main(String[] args)    {        wuziqi2 f=  new wuziqi2();    }static  class drawlconw implements Icon{ // 实现Icon接口白色棋子        private int width; // 声明图标的宽        private int height; // 声明图标的长        public int getIconHeight() { // 实现getIconHeight()方法            return this.height;        }        public int getIconWidth() { // 实现getIconWidth()方法            return this.width;        }        public drawlconw(int width, int height) { // 定义构造方法            this.width = width;            this.height = height;        }        // 实现paintIcon()方法        public void paintIcon(Component arg0, Graphics arg1, int x, int y) {            arg1.setColor(Color.white);            arg1.fillOval(x, y, width, height); // 绘制一个圆形        }}static  class drawlconb implements Icon{ // 实现Icon接口白色棋子    private int width; // 声明图标的宽    private int height; // 声明图标的长    public int getIconHeight() { // 实现getIconHeight()方法        return this.height;    }    public int getIconWidth() { // 实现getIconWidth()方法        return this.width;    }    public drawlconb(int width, int height) { // 定义构造方法        this.width = width;        this.height = height;    }    // 实现paintIcon()方法    public void paintIcon(Component arg0, Graphics arg1, int x, int y) {        arg1.setColor(Color.black);        arg1.fillOval(x, y, width, height); // 绘制一个圆形       }}class DrawPanel1 extends JPanel {    // Graphics g=getGraphics();    public void paint(Graphics g) {        super.paint(g);        for ( int i = 25; i < 910; i = i + 48) {//画竖线            g.drawLine(30, i, 912, i);            g.setColor(Color.black);        }        for (int i = 30; i <= 925; i = i + 49) {//画横线            g.drawLine(i, 25, i, 890);        }    }}}

这里写图片描述
本人菜鸡刚学java,有很多理解不好的地方,忘大佬指出!

阅读全文
2 0