`

简单的五子棋程序

阅读更多
  
   import java.awt.Color;
   import java.awt.Container;
   import java.awt.Graphics;
   import java.awt.event.ActionEvent;
   import java.awt.event.ActionListener;
   import java.awt.event.MouseEvent;
   import java.awt.event.MouseListener;
   import java.awt.event.MouseMotionListener;
   import java.awt.event.WindowAdapter;
   import java.awt.event.WindowEvent;
   import javax.swing.ButtonGroup;
   import javax.swing.JFrame;
   import javax.swing.JMenu;
   import javax.swing.JMenuBar;
   import javax.swing.JMenuItem;
   import javax.swing.JOptionPane;
   import javax.swing.JPanel;
   import javax.swing.JRadioButtonMenuItem;
   import javax.swing.SwingUtilities;
   import javax.swing.UIManager;
      /*
    *main方法创建了ChessFrame类的一个实例对象(cf),
    *并启动屏幕显示显示该实例对象。
    **/
   public class FiveChessAppletDemo {
       public static void main(String args[]){
           ChessFrame cf = new ChessFrame();
           cf.setVisible(true);
       }
   }
      /*
    *类ChessFrame主要功能是创建五子棋游戏主窗体和菜单
    **/
   class ChessFrame extends JFrame implements ActionListener {
       /**
        * 
        */
       private static final long serialVersionUID = 2183726320279905885L;
       private String[] strsize={"20x15","30x20","40x30"};
       private String[] strmode={"人机对弈","人人对弈"};
       public static boolean iscomputer=true;
       public static boolean checkcomputer=true;
       private int width,height;
       private ChessModel cm;
       private MainPanel mp;
       
       //构造五子棋游戏的主窗体
       public ChessFrame() {
           this.setTitle("五子棋游戏");
           cm=new ChessModel(1);
           mp=new MainPanel(cm);
           Container con=this.getContentPane();
           con.add(mp,"Center");
           this.setResizable(false);
           this.addWindowListener(new ChessWindowEvent());
           MapSize(20,15);
           JMenuBar mbar = new JMenuBar();
           this.setJMenuBar(mbar);
           JMenu gameMenu = new JMenu("游戏");
           mbar.add(makeMenu(gameMenu, new Object[] {
               "开局", "棋盘","模式", null, "退出"
               }, this));
           JMenu lookMenu =new JMenu("视图");
           mbar.add(makeMenu(lookMenu,new Object[] {
               "Metal","Motif","Windows"
               },this));
           JMenu helpMenu = new JMenu("帮助");
           mbar.add(makeMenu(helpMenu, new Object[] {
               "关于"
           }, this));
       }
       //构造五子棋游戏的主菜单
       public  JMenu makeMenu(Object parent, Object items[], Object target){
           JMenu m = null;
           if(parent instanceof JMenu)
               m = (JMenu)parent;
           else if(parent instanceof String)
               m = new JMenu((String)parent);
           else
               return null;
           for(int i = 0; i < items.length; i++)
               if(items[i] == null)
                   m.addSeparator();
               else if(items[i] == "棋盘"){
                   JMenu jm = new JMenu("棋盘");
                   ButtonGroup group=new ButtonGroup();
                   JRadioButtonMenuItem rmenu;
                   for (int j=0;j<strsize.length;j++){
                       rmenu=makeRadioButtonMenuItem(strsize[j],target);
                       if (j==0)
                           rmenu.setSelected(true);
                       jm.add(rmenu);
                       group.add(rmenu);
                   }
                   m.add(jm);
               }else if(items[i] == "模式"){
                   JMenu jm = new JMenu("模式");
                   ButtonGroup group=new ButtonGroup();
                   JRadioButtonMenuItem rmenu;
                   for (int h=0;h<strmode.length;h++){
                       rmenu=makeRadioButtonMenuItem(strmode[h],target);
                       if(h==0)
                           rmenu.setSelected(true);
                       jm.add(rmenu);
                       group.add(rmenu);
                   }
                   m.add(jm);
               }else
                   m.add(makeMenuItem(items[i], target));
           return m;
       }
       
       //构造五子棋游戏的菜单项
       public  JMenuItem makeMenuItem(Object item, Object target){
           JMenuItem r = null;
           if(item instanceof String)
               r = new JMenuItem((String)item);
           else if(item instanceof JMenuItem)
               r = (JMenuItem)item;
           else
               return null;
           if(target instanceof ActionListener)
               r.addActionListener((ActionListener)target);
           return r;
       }
       
       //构造五子棋游戏的单选按钮式菜单项
       public  JRadioButtonMenuItem makeRadioButtonMenuItem(
           Object item, Object target){
           JRadioButtonMenuItem r = null;
           if(item instanceof String)
               r = new JRadioButtonMenuItem((String)item);
           else if(item instanceof JRadioButtonMenuItem)
               r = (JRadioButtonMenuItem)item;
           else
               return null;
           if(target instanceof ActionListener)
               r.addActionListener((ActionListener)target);
           return r;
       }
       
       public void MapSize(int w,int h){
           setSize(w * 20+50 , h * 20+100 );
           if(!ChessFrame.checkcomputer) {
               ChessFrame.iscomputer=false;
           } else {
               ChessFrame.iscomputer=true;
           }
           mp.setModel(cm);
           mp.repaint();
       }
       
       public boolean getiscomputer(){
           return ChessFrame.iscomputer;
       }
       
       public void restart(){
           int modeChess = cm.getModeChess();
           if(modeChess <= 3 && modeChess >= 1){
               cm = new ChessModel(modeChess);
               MapSize(cm.getWidth(),cm.getHeight());
           }else{
               System.out.println("\u81EA\u5B9A\u4E49");
           }
       }
       
       public void actionPerformed(ActionEvent e){
           String arg=e.getActionCommand();
           try{
               if (arg.equals("Windows"))
                   UIManager.setLookAndFeel(
                       "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
               else if(arg.equals("Motif"))
                   UIManager.setLookAndFeel(
                       "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
               else
                   UIManager.setLookAndFeel(
                       "javax.swing.plaf.metal.MetalLookAndFeel" );
               SwingUtilities.updateComponentTreeUI(this);
           }catch(Exception ee){}
           if(arg.equals("20x15")){
               this.width=20;
               this.height=15;
               cm=new ChessModel(1);
               MapSize(this.width,this.height);
               SwingUtilities.updateComponentTreeUI(this);
           }
           if(arg.equals("30x20")){
               this.width=30;
               this.height=20;
               cm=new ChessModel(2);
               MapSize(this.width,this.height);
               SwingUtilities.updateComponentTreeUI(this);
           }
           if(arg.equals("40x30")){
               this.width=40;
               this.height=30;
               cm=new ChessModel(3);
               MapSize(this.width,this.height);
               SwingUtilities.updateComponentTreeUI(this);
           }
           if(arg.equals("人机对弈")){
               this.checkcomputer=true;
               this.iscomputer=true;
               cm=new ChessModel(cm.getModeChess());
               MapSize(cm.getWidth(),cm.getHeight());
               SwingUtilities.updateComponentTreeUI(this);
           }
           if(arg.equals("人人对弈")){
               this.checkcomputer=false;
               this.iscomputer=false;
               cm=new ChessModel(cm.getModeChess());
               MapSize(cm.getWidth(),cm.getHeight());
               SwingUtilities.updateComponentTreeUI(this);
           }
           if(arg.equals("开局")){
               restart();
           }
           if(arg.equals("关于"))
               JOptionPane.showMessageDialog(this, "五子棋游戏测试版本", "关于", 0);
           if(arg.equals("退出"))
               System.exit(0);
       }
   }
      /*
    *类ChessModel实现了整个五子棋程序算法的核心
    */
   class ChessModel {
       //棋盘的宽度、高度、棋盘的模式(如20×15)
       private int width,height,modeChess;
       //棋盘方格的横向、纵向坐标
       private int x=0,y=0;
       //棋盘方格的横向、纵向坐标所对应的棋子颜色,
       //数组arrMapShow只有3个值:1,2,3,-5,
       //其中1代表该棋盘方格上下的棋子为黑子,
       //2代表该棋盘方格上下的棋子为白子,
       //3代表为该棋盘方格上没有棋子,
       //-5代表该棋盘方格不能够下棋子
       private int[][] arrMapShow;
       //交换棋手的标识,棋盘方格上是否有棋子的标识符
       private boolean isOdd,isExist;
          public ChessModel() {}
       
       //该构造方法根据不同的棋盘模式(modeChess)来构建对应大小的棋盘
       public ChessModel(int modeChess){
           this.isOdd=true;
           if(modeChess == 1){
               PanelInit(20, 15, modeChess);
           }
           if(modeChess == 2){
               PanelInit(30, 20, modeChess);
           }
           if(modeChess == 3){
               PanelInit(40, 30, modeChess);
           }
       }
       
       //按照棋盘模式构建棋盘大小
       private void PanelInit(int width, int height, int modeChess){
           this.width = width;
           this.height = height;
           this.modeChess = modeChess;
           arrMapShow = new int[width+1][height+1];
           for(int i = 0; i <= width; i++){
               for(int j = 0; j <= height; j++){
                   arrMapShow[i][j] = -5;
               }
           }
       }
       
       //获取是否交换棋手的标识符
       public boolean getisOdd(){
           return this.isOdd;
       }
          //设置交换棋手的标识符
       public void setisOdd(boolean isodd){
           if(isodd)
               this.isOdd=true;
           else
               this.isOdd=false;
       }
       
       //获取某棋盘方格是否有棋子的标识值
       public boolean getisExist(){
           return this.isExist;
       }
       
       //获取棋盘宽度
       public int getWidth(){
           return this.width;
       }
       
       //获取棋盘高度
       public int getHeight(){
           return this.height;
       }
       
       //获取棋盘模式
       public int getModeChess(){
           return this.modeChess;
       }
          //获取棋盘方格上棋子的信息
       public int[][] getarrMapShow(){
           return arrMapShow;
       }
          //判断下子的横向、纵向坐标是否越界
       private boolean badxy(int x, int y){
           if(x >= width+20 || x < 0)
               return true;
           return y >= height+20 || y < 0;
       }
          //计算棋盘上某一方格上八个方向棋子的最大值,
       //这八个方向分别是:左、右、上、下、左上、左下、右上、右下
       public boolean chessExist(int i,int j){
           if(this.arrMapShow[i][j]==1 || this.arrMapShow[i][j]==2)
               return true;
           return false;
       }
          //判断该坐标位置是否可下棋子
       public void readyplay(int x,int y){
           if(badxy(x,y))
               return;
           if (chessExist(x,y))
               return;
           this.arrMapShow[x][y]=3;
       }
          //在该坐标位置下棋子
       public void play(int x,int y){
           if(badxy(x,y))
               return;
           if(chessExist(x,y)){
               this.isExist=true;
               return;
           }else
               this.isExist=false;
           if(getisOdd()){
               setisOdd(false);
           this.arrMapShow[x][y]=1;
           }else{
               setisOdd(true);
               this.arrMapShow[x][y]=2;
           }
       }
          //计算机走棋
       /*
        *说明:用穷举法判断每一个坐标点的四个方向的的最大棋子数,
        *最后得出棋子数最大值的坐标,下子
        **/
       public void computerDo(int width,int height){
           int max_black,max_white,max_temp,max=0;
           setisOdd(true);
           System.out.println("计算机走棋 ...");
           for(int i = 0; i <= width; i++){
               for(int j = 0; j <= height; j++){
                   if(!chessExist(i,j)){//算法判断是否下子
                       max_white=checkMax(i,j,2);//判断白子的最大值
                       max_black=checkMax(i,j,1);//判断黑子的最大值
                       max_temp=Math.max(max_white,max_black);
                       if(max_temp>max){
                           max=max_temp;
                           this.x=i;
                           this.y=j;
                       }
                   }
               }
           }
           setX(this.x);
           setY(this.y);
           this.arrMapShow[this.x][this.y]=2;
       }
       
       //记录电脑下子后的横向坐标
       public void setX(int x){
           this.x=x;
       }
       
       //记录电脑下子后的纵向坐标
       public void setY(int y){
           this.y=y;
       }
       
       //获取电脑下子的横向坐标
       public int getX(){
           return this.x;
       }
       
       //获取电脑下子的纵向坐标
       public int getY(){
           return this.y;
       }
          //计算棋盘上某一方格上八个方向棋子的最大值,
       //这八个方向分别是:左、右、上、下、左上、左下、右上、右下
       public int checkMax(int x, int y,int black_or_white){
           int num=0,max_num,max_temp=0;
           int x_temp=x,y_temp=y;
           int x_temp1=x_temp,y_temp1=y_temp;
           //judge right
           for(int i=1;i<5;i++){
               x_temp1+=1;
               if(x_temp1>this.width)
                   break;
               if(this.arrMapShow[x_temp1][y_temp1]==black_or_white)
                   num++;
               else
                   break;
           }
           //judge left
           x_temp1=x_temp;
           for(int i=1;i<5;i++){
               x_temp1-=1;
               if(x_temp1<0)
                   break;
               if(this.arrMapShow[x_temp1][y_temp1]==black_or_white)
                   num++;
               else
                   break;
           }
           if(num<5)
               max_temp=num;
              //judge up
           x_temp1=x_temp;
           y_temp1=y_temp;
           num=0;
           for(int i=1;i<5;i++){
               y_temp1-=1;
               if(y_temp1<0)
                   break;
               if(this.arrMapShow[x_temp1][y_temp1]==black_or_white)
                   num++;
               else
                   break;
           }
           //judge down
           y_temp1=y_temp;
           for(int i=1;i<5;i++){
               y_temp1+=1;
               if(y_temp1>this.height)
                   break;
               if(this.arrMapShow[x_temp1][y_temp1]==black_or_white)
                   num++;
               else
                   break;
           }
           if(num>max_temp&&num<5)
               max_temp=num;
              //judge left_up
           x_temp1=x_temp;
           y_temp1=y_temp;
           num=0;
           for(int i=1;i<5;i++){
               x_temp1-=1;
               y_temp1-=1;
               if(y_temp1<0 || x_temp1<0)
                   break;
               if(this.arrMapShow[x_temp1][y_temp1]==black_or_white)
                   num++;
               else
                   break;
           }
           //judge right_down
           x_temp1=x_temp;
           y_temp1=y_temp;
           for(int i=1;i<5;i++){
               x_temp1+=1;
               y_temp1+=1;
               if(y_temp1>this.height || x_temp1>this.width)
                   break;
               if(this.arrMapShow[x_temp1][y_temp1]==black_or_white)
                   num++;
               else
                   break;
           }
           if(num>max_temp&&num<5)
               max_temp=num;
              //judge right_up
           x_temp1=x_temp;
           y_temp1=y_temp;
           num=0;
           for(int i=1;i<5;i++){
               x_temp1+=1;
               y_temp1-=1;
               if(y_temp1<0 || x_temp1>this.width)
                   break;
               if(this.arrMapShow[x_temp1][y_temp1]==black_or_white)
                   num++;
               else
                   break;
           }
           //judge left_down
           x_temp1=x_temp;
           y_temp1=y_temp;
           for(int i=1;i<5;i++){
               x_temp1-=1;
               y_temp1+=1;
               if(y_temp1>this.height || x_temp1<0)
                   break;
               if(this.arrMapShow[x_temp1][y_temp1]==black_or_white)
                   num++;
               else
                   break;
           }
           if(num>max_temp&&num<5)
               max_temp=num;
           max_num=max_temp;
           return max_num;
       }
          //判断胜负
       public boolean judgeSuccess(int x,int y,boolean isodd){
           int num=1;
           int arrvalue;
           int x_temp=x,y_temp=y;
           if(isodd)
               arrvalue=2;
           else
               arrvalue=1;
           int x_temp1=x_temp,y_temp1=y_temp;
           //判断右边
           for(int i=1;i<6;i++){
               x_temp1+=1;
               if(x_temp1>this.width)
                   break;
               if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)
                   num++;
               else
                   break;
           }
           //判断左边
           x_temp1=x_temp;
           for(int i=1;i<6;i++){
               x_temp1-=1;
               if(x_temp1<0)
                   break;
               if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)
                   num++;
               else
                   break;
           }
           if(num==5)
               return true;
              //判断上方
           x_temp1=x_temp;
           y_temp1=y_temp;
           num=1;
           for(int i=1;i<6;i++){
               y_temp1-=1;
               if(y_temp1<0)
                   break;
               if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)
                   num++;
               else
                   break;
           }
           //判断下方
           y_temp1=y_temp;
           for(int i=1;i<6;i++){
               y_temp1+=1;
               if(y_temp1>this.height)
                   break;
               if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)
                   num++;
               else
                   break;
           }
           if(num==5)
               return true;
              //判断左上
           x_temp1=x_temp;
           y_temp1=y_temp;
           num=1;
           for(int i=1;i<6;i++){
               x_temp1-=1;
               y_temp1-=1;
               if(y_temp1<0 || x_temp1<0)
                   break;
               if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)
                   num++;
               else
                   break;
           }
           //判断右下
           x_temp1=x_temp;
           y_temp1=y_temp;
           for(int i=1;i<6;i++){
           x_temp1+=1;
           y_temp1+=1;
           if(y_temp1>this.height || x_temp1>this.width)
               break;
               if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)
                   num++;
               else
                   break;
           }
           if(num==5)
               return true;
              //判断右上
           x_temp1=x_temp;
           y_temp1=y_temp;
           num=1;
           for(int i=1;i<6;i++){
               x_temp1+=1;
               y_temp1-=1;
               if(y_temp1<0 || x_temp1>this.width)
                   break;
               if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)
                   num++;
               else
                   break;
           }
           //判断左下
           x_temp1=x_temp;
           y_temp1=y_temp;
           for(int i=1;i<6;i++){
               x_temp1-=1;
               y_temp1+=1;
               if(y_temp1>this.height || x_temp1<0)
                   break;
               if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)
                   num++;
               else
                   break;
           }
           if(num==5)
               return true;
           return false;
       }
          //赢棋后的提示
       public void showSuccess(JPanel jp){
           JOptionPane.showMessageDialog(jp,"你赢了,好厉害!","win",
               JOptionPane.INFORMATION_MESSAGE);
       }
       
       //输棋后的提示
       public void showDefeat(JPanel jp){
           JOptionPane.showMessageDialog(jp,"你输了,请重新开始!","lost",
               JOptionPane.INFORMATION_MESSAGE);
       }
   }
      /*
    *类MainPanel主要完成如下功能:
    *1、构建一个面板,在该面板上画上棋盘;
    *2、处理在该棋盘上的鼠标事件(如鼠标左键点击、鼠标右键点击、鼠标拖动等)
    **/
   class MainPanel extends JPanel 
       implements MouseListener,MouseMotionListener{
       private int width,height;//棋盘的宽度和高度
       private ChessModel cm;
       
       //根据棋盘模式设定面板的大小
       MainPanel(ChessModel mm){
           cm=mm;
           width=cm.getWidth();
           height=cm.getHeight();
           addMouseListener(this);
       }
       
       //根据棋盘模式设定棋盘的宽度和高度
       public void setModel(ChessModel mm){
           cm = mm;
           width = cm.getWidth();
           height = cm.getHeight();
       }
          //根据坐标计算出棋盘方格棋子的信息(如白子还是黑子),
       //然后调用draw方法在棋盘上画出相应的棋子
       public void paintComponent(Graphics g){
           super.paintComponent(g);
           for(int j = 0; j <= height; j++){
               for(int i = 0; i <= width; i++){
                   int v = cm.getarrMapShow()[i][j];
                   draw(g, i, j, v);
               }
           }
       }
          //根据提供的棋子信息(颜色、坐标)画棋子
       public void draw(Graphics g, int i, int j, int v){
           int x = 20 * i+20;
           int y = 20 * j+20;
           //画棋盘
           if(i!=width && j!=height){
               g.setColor(Color.white);
               g.drawRect(x,y,20,20);
           }
           //画黑色棋子
           if(v == 1 ){
               g.setColor(Color.gray);
               g.drawOval(x-8,y-8,16,16);
               g.setColor(Color.black);
               g.fillOval(x-8,y-8,16,16);
           }
           //画白色棋子
           if(v == 2 ){
               g.setColor(Color.gray);
               g.drawOval(x-8,y-8,16,16);
               g.setColor(Color.white);
               g.fillOval(x-8,y-8,16,16);
           }
           if(v ==3){
               g.setColor(Color.cyan);
               g.drawOval(x-8,y-8,16,16);
           }
       }
          //响应鼠标的点击事件,根据鼠标的点击来下棋,
       //根据下棋判断胜负等
       public void mousePressed(MouseEvent evt){
           int x = (evt.getX()-10) / 20;
           int y = (evt.getY()-10) / 20;
           System.out.println(x+" "+y);
           if (evt.getModifiers()==MouseEvent.BUTTON1_MASK){
               cm.play(x,y);
               System.out.println(cm.getisOdd()+" "+cm.getarrMapShow()[x][y]);
               repaint();
               if(cm.judgeSuccess(x,y,cm.getisOdd())){
                   cm.showSuccess(this);
                   evt.consume();
                   ChessFrame.iscomputer=false;
               }
               //判断是否为人机对弈
               if(ChessFrame.iscomputer&&!cm.getisExist()){
                   cm.computerDo(cm.getWidth(),cm.getHeight());
                   repaint();
                   if(cm.judgeSuccess(cm.getX(),cm.getY(),cm.getisOdd())){
                       cm.showDefeat(this);
                       evt.consume();
                   }
               }
           }
       }
          public void mouseClicked(MouseEvent evt){}
       public void mouseReleased(MouseEvent evt){}
       public void mouseEntered(MouseEvent mouseevt){}
       public void mouseExited(MouseEvent mouseevent){}
       public void mouseDragged(MouseEvent evt){}
       
       //响应鼠标的拖动事件
       public void mouseMoved(MouseEvent moveevt){
           int x = (moveevt.getX()-10) / 20;
           int y = (moveevt.getY()-10) / 20;
           cm.readyplay(x,y);
           repaint();
       } 
   }
      class ChessWindowEvent extends WindowAdapter{
       public void windowClosing(WindowEvent e){
           System.exit(0);
       }
          ChessWindowEvent(){}
   }
 
0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics