zoukankan      html  css  js  c++  java
  • 五子棋

    一、实践目标:

           1.掌握JavaGUI界面设计

           2.掌握鼠标事件的监听(MouseListener,MouseMotionListener)

    二、实践内容:

          设计一个简单的五子棋程序,能够实现五子棋下棋过程。如下图所示

     

    五子棋运行界面

      1 package cn.edu.ouc.fiveChess;
      2 
      3 import java.awt.Color;
      4 import java.awt.Cursor;
      5 import java.awt.Dimension;
      6 import java.awt.Graphics;
      7 import java.awt.Graphics2D;
      8 import java.awt.Image;
      9 import java.awt.RadialGradientPaint;
     10 import java.awt.RenderingHints;
     11 import java.awt.Toolkit;
     12 import java.awt.event.MouseEvent;
     13 import java.awt.event.MouseListener;
     14 import java.awt.event.MouseMotionListener;
     15 import java.awt.geom.Ellipse2D;
     16 
     17 import javax.swing.*;
     18 /**
     19  * 五子棋--棋盘类 
     20  */
     21 
     22 public class ChessBoard extends JPanel implements MouseListener {
     23    public static final int MARGIN=30;//边距
     24    public static final int GRID_SPAN=35;//网格间距
     25    public static final int ROWS=15;//棋盘行数
     26    public static final int COLS=15;//棋盘列数
     27    
     28    Point[] chessList=new Point[(ROWS+1)*(COLS+1)];//初始每个数组元素为null
     29    boolean isBlack=true;//默认开始是黑棋先
     30    boolean gameOver=false;//游戏是否结束
     31    int chessCount;//当前棋盘棋子的个数
     32    int xIndex,yIndex;//当前刚下棋子的索引
     33    
     34    Image img;
     35    Image shadows;
     36    Color colortemp;
     37    public ChessBoard(){
     38       
     39       // setBackground(Color.blue);//设置背景色为橘黄色
     40        img=Toolkit.getDefaultToolkit().getImage("board.jpg");
     41        shadows=Toolkit.getDefaultToolkit().getImage("shadows.jpg");
     42        addMouseListener(this);
     43        addMouseMotionListener(new MouseMotionListener(){
     44            public void mouseDragged(MouseEvent e){
     45                
     46            }
     47            
     48            public void mouseMoved(MouseEvent e){
     49              int x1=(e.getX()-MARGIN+GRID_SPAN/2)/GRID_SPAN;
     50              //将鼠标点击的坐标位置转成网格索引
     51              int y1=(e.getY()-MARGIN+GRID_SPAN/2)/GRID_SPAN;
     52              //游戏已经结束不能下
     53              //落在棋盘外不能下
     54              //x,y位置已经有棋子存在,不能下
     55              if(x1<0||x1>ROWS||y1<0||y1>COLS||gameOver||findChess(x1,y1))
     56                  setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
     57              //设置成默认状态
     58              else setCursor(new Cursor(Cursor.HAND_CURSOR));
     59              
     60            }
     61        });
     62    } 
     63    
     64   
     65 
     66 //绘制
     67    public void paintComponent(Graphics g){
     68      
     69        super.paintComponent(g);//画棋盘
     70      
     71        int imgWidth= img.getWidth(this);
     72        int imgHeight=img.getHeight(this);//获得图片的宽度与高度
     73        int FWidth=getWidth();
     74        int FHeight=getHeight();//获得窗口的宽度与高度
     75        int x=(FWidth-imgWidth)/2;
     76        int y=(FHeight-imgHeight)/2;
     77        g.drawImage(img, x, y, null);
     78     
     79        
     80        for(int i=0;i<=ROWS;i++){//画横线
     81            g.drawLine(MARGIN, MARGIN+i*GRID_SPAN, MARGIN+COLS*GRID_SPAN, MARGIN+i*GRID_SPAN);
     82        }
     83        for(int i=0;i<=COLS;i++){//画竖线
     84            g.drawLine(MARGIN+i*GRID_SPAN, MARGIN, MARGIN+i*GRID_SPAN, MARGIN+ROWS*GRID_SPAN);
     85            
     86        }
     87        
     88        //画棋子
     89        for(int i=0;i<chessCount;i++){
     90            //网格交叉点x,y坐标
     91            int xPos=chessList[i].getX()*GRID_SPAN+MARGIN;
     92            int yPos=chessList[i].getY()*GRID_SPAN+MARGIN;
     93            g.setColor(chessList[i].getColor());//设置颜色
     94           // g.fillOval(xPos-Point.DIAMETER/2, yPos-Point.DIAMETER/2,
     95                            //Point.DIAMETER, Point.DIAMETER);
     96            //g.drawImage(shadows, xPos-Point.DIAMETER/2, yPos-Point.DIAMETER/2, Point.DIAMETER, Point.DIAMETER, null);
     97            colortemp=chessList[i].getColor();
     98            if(colortemp==Color.black){
     99                RadialGradientPaint paint = new RadialGradientPaint(xPos-Point.DIAMETER/2+25, yPos-Point.DIAMETER/2+10, 20, new float[]{0f, 1f}
    100                , new Color[]{Color.WHITE, Color.BLACK});
    101                ((Graphics2D) g).setPaint(paint);
    102                ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    103                ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT);
    104 
    105            }
    106            else if(colortemp==Color.white){
    107                RadialGradientPaint paint = new RadialGradientPaint(xPos-Point.DIAMETER/2+25, yPos-Point.DIAMETER/2+10, 70, new float[]{0f, 1f}
    108                , new Color[]{Color.WHITE, Color.BLACK});
    109                ((Graphics2D) g).setPaint(paint);
    110                ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    111                ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT);
    112 
    113            }
    114          
    115            Ellipse2D e = new Ellipse2D.Float(xPos-Point.DIAMETER/2, yPos-Point.DIAMETER/2, 34, 35);
    116            ((Graphics2D) g).fill(e);
    117            //标记最后一个棋子的红矩形框
    118            
    119            if(i==chessCount-1){//如果是最后一个棋子
    120                g.setColor(Color.red);
    121                g.drawRect(xPos-Point.DIAMETER/2, yPos-Point.DIAMETER/2,
    122                            34, 35);
    123            }
    124        }
    125    }
    126    
    127    public void mousePressed(MouseEvent e){//鼠标在组件上按下时调用
    128        
    129        //游戏结束时,不再能下
    130        if(gameOver) return;
    131        
    132        String colorName=isBlack?"黑棋":"白棋";
    133        
    134        //将鼠标点击的坐标位置转换成网格索引
    135        xIndex=(e.getX()-MARGIN+GRID_SPAN/2)/GRID_SPAN;
    136        yIndex=(e.getY()-MARGIN+GRID_SPAN/2)/GRID_SPAN;
    137        
    138        //落在棋盘外不能下
    139        if(xIndex<0||xIndex>ROWS||yIndex<0||yIndex>COLS)
    140            return;
    141        
    142        //如果x,y位置已经有棋子存在,不能下
    143        if(findChess(xIndex,yIndex))return;
    144        
    145        //可以进行时的处理
    146        Point ch=new Point(xIndex,yIndex,isBlack?Color.black:Color.white);
    147        chessList[chessCount++]=ch;
    148         repaint();//通知系统重新绘制
    149       
    150        
    151        //如果胜出则给出提示信息,不能继续下棋
    152        
    153        if(isWin()){
    154            String msg=String.format("恭喜,%s赢了!", colorName);
    155            JOptionPane.showMessageDialog(this, msg);
    156            gameOver=true;
    157        }
    158        isBlack=!isBlack;
    159      }
    160    //覆盖mouseListener的方法
    161    public void mouseClicked(MouseEvent e){
    162        //鼠标按键在组件上单击时调用
    163    }
    164    
    165    public void mouseEntered(MouseEvent e){
    166        //鼠标进入到组件上时调用
    167    }
    168    public void mouseExited(MouseEvent e){
    169        //鼠标离开组件时调用
    170    }
    171    public void mouseReleased(MouseEvent e){
    172        //鼠标按钮在组件上释放时调用
    173    }
    174    //在棋子数组中查找是否有索引为x,y的棋子存在
    175    private boolean findChess(int x,int y){
    176        for(Point c:chessList){
    177            if(c!=null&&c.getX()==x&&c.getY()==y)
    178                return true;
    179        }
    180        return false;
    181    }
    182    
    183    
    184    private boolean isWin(){
    185        int continueCount=1;//连续棋子的个数
    186       
    187        //横向向西寻找
    188        for(int x=xIndex-1;x>=0;x--){
    189            Color c=isBlack?Color.black:Color.white;
    190            if(getChess(x,yIndex,c)!=null){
    191                continueCount++;
    192            }else
    193                break;
    194        }
    195       //横向向东寻找
    196        for(int x=xIndex+1;x<=COLS;x++){
    197           Color c=isBlack?Color.black:Color.white;
    198           if(getChess(x,yIndex,c)!=null){
    199              continueCount++;
    200           }else
    201              break;
    202        }
    203        if(continueCount>=5){
    204              return true;
    205        }else 
    206        continueCount=1;
    207        
    208        //继续另一种搜索纵向
    209        //向上搜索
    210        for(int y=yIndex-1;y>=0;y--){
    211            Color c=isBlack?Color.black:Color.white;
    212            if(getChess(xIndex,y,c)!=null){
    213                continueCount++;
    214            }else
    215                break;
    216        }
    217        //纵向向下寻找
    218        for(int y=yIndex+1;y<=ROWS;y++){
    219            Color c=isBlack?Color.black:Color.white;
    220            if(getChess(xIndex,y,c)!=null)
    221                continueCount++;
    222            else
    223               break;
    224        
    225        }
    226        if(continueCount>=5)
    227            return true;
    228        else
    229            continueCount=1;
    230        
    231        
    232        //继续另一种情况的搜索:斜向
    233        //东北寻找
    234        for(int x=xIndex+1,y=yIndex-1;y>=0&&x<=COLS;x++,y--){
    235            Color c=isBlack?Color.black:Color.white;
    236            if(getChess(x,y,c)!=null){
    237                continueCount++;
    238            }
    239            else break;
    240        }
    241        //西南寻找
    242        for(int x=xIndex-1,y=yIndex+1;x>=0&&y<=ROWS;x--,y++){
    243            Color c=isBlack?Color.black:Color.white;
    244            if(getChess(x,y,c)!=null){
    245                continueCount++;
    246            }
    247            else break;
    248        }
    249        if(continueCount>=5)
    250            return true;
    251        else continueCount=1;
    252        
    253        
    254        //继续另一种情况的搜索:斜向
    255        //西北寻找
    256        for(int x=xIndex-1,y=yIndex-1;x>=0&&y>=0;x--,y--){
    257            Color c=isBlack?Color.black:Color.white;
    258            if(getChess(x,y,c)!=null)
    259                continueCount++;
    260            else break;
    261        }
    262        //东南寻找
    263        for(int x=xIndex+1,y=yIndex+1;x<=COLS&&y<=ROWS;x++,y++){
    264            Color c=isBlack?Color.black:Color.white;
    265            if(getChess(x,y,c)!=null)
    266                continueCount++;
    267            else break;
    268        }
    269        if(continueCount>=5)
    270            return true;
    271        else continueCount=1;
    272        
    273        return false;
    274      }
    275    
    276    
    277    private Point getChess(int xIndex,int yIndex,Color color){
    278        for(Point p:chessList){
    279            if(p!=null&&p.getX()==xIndex&&p.getY()==yIndex
    280                    &&p.getColor()==color)
    281                return p;
    282        }
    283        return null;
    284    }
    285    
    286    
    287    public void restartGame(){
    288        //清除棋子
    289        for(int i=0;i<chessList.length;i++){
    290            chessList[i]=null;
    291        }
    292        //恢复游戏相关的变量值
    293        isBlack=true;
    294        gameOver=false; //游戏是否结束
    295        chessCount =0; //当前棋盘棋子个数
    296        repaint();
    297    }
    298    
    299    //悔棋
    300    public void goback(){
    301        if(chessCount==0)
    302            return ;
    303        chessList[chessCount-1]=null;
    304        chessCount--;
    305        if(chessCount>0){
    306            xIndex=chessList[chessCount-1].getX();
    307            yIndex=chessList[chessCount-1].getY();
    308        }
    309        isBlack=!isBlack;
    310        repaint();
    311    }
    312    
    313    //矩形Dimension
    314 
    315    public Dimension getPreferredSize(){
    316        return new Dimension(MARGIN*2+GRID_SPAN*COLS,MARGIN*2
    317                             +GRID_SPAN*ROWS);
    318    }
    319    
    320    
    321    
    322 }

       2.棋子类

     1 package cn.edu.ouc.fiveChess;
     2 
     3 import java.awt.Color;
     4 /**
     5  * 棋子类
     6  */
     7 public class Point {
     8   private int x;//棋盘中的x索引
     9   private int y;//棋盘中的y索引
    10   private Color color;//颜色
    11   public static final int DIAMETER=30;//直径
    12   
    13   public Point(int x,int y,Color color){
    14       this.x=x;
    15       this.y=y;
    16       this.color=color;
    17   } 
    18   
    19   public int getX(){//拿到棋盘中x的索引
    20       return x;
    21   }
    22   public int getY(){
    23       return y;
    24   }
    25   public Color getColor(){//获得棋子的颜色
    26       return color;
    27   }
    28 }

     3.五子棋主框架类

     1 package cn.edu.ouc.fiveChess;
     2 import java.awt.event.*;
     3 import java.awt.*;
     4 
     5 import javax.swing.*;
     6 /*
     7  五子棋主框架類,程序啟動類
     8  */
     9 public class StartChessJFrame extends JFrame {
    10   private ChessBoard chessBoard;
    11   private JPanel toolbar;
    12   private JButton startButton,backButton,exitButton;
    13   
    14   private JMenuBar menuBar;
    15   private JMenu sysMenu;
    16   private JMenuItem startMenuItem,exitMenuItem,backMenuItem;
    17   //重新开始,退出,和悔棋菜单项
    18   public StartChessJFrame(){
    19       setTitle("单机版五子棋");//设置标题
    20       chessBoard=new ChessBoard();
    21     
    22       
    23       Container contentPane=getContentPane();
    24       contentPane.add(chessBoard);
    25       chessBoard.setOpaque(true);
    26       
    27       
    28       //创建和添加菜单
    29       menuBar =new JMenuBar();//初始化菜单栏
    30       sysMenu=new JMenu("系统");//初始化菜单
    31       //初始化菜单项
    32       startMenuItem=new JMenuItem("重新开始");
    33       exitMenuItem =new JMenuItem("退出");
    34       backMenuItem =new JMenuItem("悔棋");
    35       //将三个菜单项添加到菜单上
    36       sysMenu.add(startMenuItem);
    37       sysMenu.add(exitMenuItem);
    38       sysMenu.add(backMenuItem);
    39       //初始化按钮事件监听器内部类
    40       MyItemListener lis=new MyItemListener();
    41       //将三个菜单注册到事件监听器上
    42       this.startMenuItem.addActionListener(lis);
    43       backMenuItem.addActionListener(lis);
    44       exitMenuItem.addActionListener(lis);
    45       menuBar.add(sysMenu);//将系统菜单添加到菜单栏上
    46       setJMenuBar(menuBar);//将menuBar设置为菜单栏
    47       
    48       toolbar=new JPanel();//工具面板实例化
    49       //三个按钮初始化
    50       startButton=new JButton("重新开始");
    51       exitButton=new JButton("退出");
    52       backButton=new JButton("悔棋");
    53       //将工具面板按钮用FlowLayout布局
    54       toolbar.setLayout(new FlowLayout(FlowLayout.LEFT));
    55       //将三个按钮添加到工具面板
    56       toolbar.add(startButton);
    57       toolbar.add(exitButton);
    58       toolbar.add(backButton);
    59       //将三个按钮注册监听事件
    60       startButton.addActionListener(lis);
    61       exitButton.addActionListener(lis);
    62       backButton.addActionListener(lis);
    63       //将工具面板布局到界面”南方“也就是下方
    64       add(toolbar,BorderLayout.SOUTH);
    65       add(chessBoard);//将面板对象添加到窗体上
    66       //设置界面关闭事件
    67       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    68       //setSize(800,800);
    69       pack();//自适应大小
    70       
    71   }
    72   
    73   private class MyItemListener implements ActionListener{
    74       public void actionPerformed(ActionEvent e){
    75           Object obj=e.getSource();//获得事件源
    76           if(obj==StartChessJFrame.this.startMenuItem||obj==startButton){
    77               //重新开始
    78               //JFiveFrame.this内部类引用外部类
    79               System.out.println("重新开始");
    80               chessBoard.restartGame();
    81           }
    82           else if (obj==exitMenuItem||obj==exitButton)
    83               System.exit(0);
    84           else if (obj==backMenuItem||obj==backButton){
    85               System.out.println("悔棋...");
    86               chessBoard.goback();
    87           }
    88       }
    89   }
    90   
    91   
    92   
    93   public static void main(String[] args){
    94       StartChessJFrame f=new StartChessJFrame();//创建主框架
    95       f.setVisible(true);//显示主框架
    96       
    97   }
    98 }
  • 相关阅读:
    视图转换例子实践
    Xml序列化和反序列化对象使用MemoryStream实践
    iOS中控制器的实践和学习(2)认识XCode4模版(A1,A3,B2简易图)
    iOS中控制器的实践和学习(1)抛出UI问题
    拖动雪花视图实例学习
    <海量数据库解决方案>2011051901
    <海量数据库解决方案>2011051301
    提示(警告)视图的简单应用
    Delphi Prism Visual Studio Pascal For .NET
    Migrating Delphi Applications to .NET
  • 原文地址:https://www.cnblogs.com/zpfbuaa/p/5087531.html
Copyright © 2011-2022 走看看