2020/11/1 oop实例 扫雷代码

扫雷游戏的规则就不多说了

然后的话跟大部分人一样我也是运用二维数组来进行存储雷的信息,不过使用的是二进制数来表示雷的个数 是否插旗 和是否是雷

二维数组存储的表示这个信息 0b 0000 00 0

                                                 0001 代表有一个雷
                                                 00: 00 打开
                                                          01 插旗
                                                          10 打开
                                                     0:1 是雷
                                                       0 不是雷

首先是埋雷 埋雷的话是用随机函数来随机生成坐标X Y,然后的话主要判断方式是通过位运算来判断是否为雷,因为用的是二进制数

然后的话 输出的值是通过二进制转化成十进制的数,而我们所需要的的是 1 2  3 4 这种,所以还要让二进制的数向右位移三位,因为最后三位数并不影响雷的个数输出(这里的雷的个数是雷周围的值,也就是旁边有几个雷,以自己为中心的九宫格)。

因为是面向对象的想法 所以首先Point类,这个类是数组的下标X Y以及状态State 0b0000000

Point()

public class Point {
    private int x;//行
    private int y;//列
    private int state;// 0b1111(表示附近雷的数量)11(表示棋子状态 00 没打开 10插旗 01 打开)1(1为雷 0不为雷)
    public Point(){}
    
    public Point(int x,int y,int state)
    {
        this.x = x;
        this.y = y;
        this.state=state;
        
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

}
 

获取扫雷页面,而获取到扫雷页面的时候也已经赋值好了,也就是地雷状态这些,suoyi,然后的话运用的是对象数组。

MineMaps()

import java.util.Random;

public class MineMaps {
    private int rows; //行
    private int cols;  //列
    private int minecount; //雷的数量
    public int getRows() {
        return rows;
    }
    public void setRows(int rows) {
        this.rows = rows;
    }
    public int getCols() {
        return cols;
    }
    public void setCols(int cols) {
        this.cols = cols;
    }
    public int getMinecount() {
        return minecount;
    }
    public void setMinecount(int minecount) {
        this.minecount = minecount;
    }
    
    public MineMaps(){}
    public MineMaps(int rows,int cols,int minecount){
        this.rows = rows;
        this.cols = cols;
        this.minecount = minecount;
    }
    public Point[][] getMineMaps(){
        Point[][] mineBoard=new Point[rows][cols];
        for(int i=0;i<rows;i++)
        {
            for(int j=0;j<cols;j++)
            {
                mineBoard[i][j]=new Point(i,j,0);
            }
        }
        
        return burnMine(mineBoard);
        
    }
    
    public Point[][] burnMine(Point [][] mineBoard)
    {
        Random rd=new Random();
        for(int i=0;i<minecount;)
        {
            int x=rd.nextInt(rows);
            int y=rd.nextInt(cols);
            if((mineBoard[x][y].getState()&0b1)==0)
            {
                //没有雷
                //埋雷
                mineBoard[x][y].setState(mineBoard[x][y].getState()|0b1);
                if(x-1>=0)
                {
                    if(y-1>=0)//左上
                    {
                        mineBoard[x-1][y-1].setState(mineBoard[x-1][y-1].getState()+0b0001000);
                        
                    }
                    
                    if(y+1<cols) //右上
                    {
                        mineBoard[x-1][y+1].setState(mineBoard[x-1][y+1].getState()+0b0001000);
                    }
                    //正上方
                    mineBoard[x-1][y].setState(mineBoard[x-1][y].getState()+0b0001000);
                    
                }
                
                if(x+1<rows)
                {
                    if(y-1>=0)//左下
                    {
                        mineBoard[x+1][y-1].setState(mineBoard[x+1][y-1].getState()+0b0001000);
                        
                    }
                    
                    if(y+1<cols) //右下
                    {
                        mineBoard[x+1][y+1].setState(mineBoard[x+1][y+1].getState()+0b0001000);
                    }
                    //正下方
                    mineBoard[x+1][y].setState(mineBoard[x+1][y].getState()+0b0001000);
                    
                }
                
                if(y-1>=0)  //x最左边时
                {
                    mineBoard[x][y-1].setState(mineBoard[x][y-1].getState()+0b0001000);
                }
                if(y+1<cols) //x在最右边时
                {
                    mineBoard[x][y+1].setState(mineBoard[x][y+1].getState()+0b0001000);
                }
                
                i++;
                
            }
        }
        return mineBoard;    
    }

}
 

ClearMineGame类

这个类中包含了几个功能,整个游戏进行都在这里,分为开始选择难度,输入坐标打开格子,如果是地雷直接游戏结束,如果是空白则直接向周围的格子寻找是不是空白,如果是就打开然后一直递归,直到空白周围有数字为止,然后的话还有插旗和删旗的功能,当插旗数与地雷数一样,游戏取得胜利,不过我这里的代码其实还有点问题,就是删旗和判断游戏胜利那个地方,等明天再解决了。

import java.util.Scanner;
public class ClearMineGame {
    private MineMaps mineMap;
    private int pointCount;
    private Point[][] minePoints;
    Scanner sc = new Scanner(System.in);
    static int f=0;
    public void init() {
        System.out.println("***************欢迎进行扫雷*************");
        System.out.println("**************请选择游戏难度 2.中等 3.困难*************");
        int choice = sc.nextInt();
        switch (choice) {
        case 2:
            mineMap = new MineMaps(16, 16, 40);
            pointCount = 16 * 16;
            break;
        case 3:
            mineMap = new MineMaps(16, 30, 99);
            pointCount = 16 * 30;
            break;
        default:
            mineMap = new MineMaps(9, 9, 10);
            pointCount = 9 * 9;
            break;
        }

        minePoints = mineMap.getMineMaps();
        playGame();
    }

    
    private void playGame() {
        showMineBoard();
        boolean isOver = false;
        System.out.println("请输入坐标");
        int x = sc.nextInt();
        int y = sc.nextInt();
        Point point = minePoints[x - 1][y - 1];
        System.out.println("请选择操作1.打开 2.插旗 3.拔旗");
        int choice=0;
        do{
            choice=sc.nextInt();
            switch(choice)
            {
            case 1:
                isOver=openPoint(point);
                break;
            case 2:
                insertFlag(point);
                break;
            case 3:
                deletFlag(point);
                break;
            default:
                    System.out.println("没有此选项,请重新输入");
                    break;
            
            }
            
        }while(choice<1||choice>3);
        
        if(isOver==true)
        {
            showMineBoard();
            System.out.println("游戏结束....");
        }else{
            playGame();
        }

    }
    private boolean openPoint(Point point)
    {//1.判断是否为雷
    //2.不是雷 如果点击空白点 级联打开    
        
        if((point.getState()&0b1)==0b1)
        {
            for(int i=0;i<minePoints.length;i++)
            {
                for(int j=0;j<minePoints[0].length;j++)
                {
                    minePoints[i][j].setState(minePoints[i][j].getState()|0b010);//游戏结束 所有格子全部打开
                }
            }
            
            return true;
        }else{
            openwhitePoint(point);
            if(pointCount==0&&(f==mineMap.getMinecount()))
            {
                System.out.println("恭喜通关!");
            }
            
        }
        
        
        return false;
    }
    
    private void openwhitePoint(Point point)
    {
        if(((point.getState()&0b1)==0b1)||((point.getState()&0b110)==0b100)||(point.getState()&0b110)==0b010)
        {
            return ;
        }
        minePoints[point.getX()][point.getY()].setState(point.getState()|0b010);
        pointCount--;
        if(point.getState()>>3==0)
        {
            if(point.getX()-1>0)
            {
                if(point.getY()-1>0) //左上
                {
                    openwhitePoint(minePoints[point.getX()-1][point.getY()-1]);
                }
                if(point.getY()+1<minePoints[0].length) //右上
                {
                    openwhitePoint(minePoints[point.getX()-1][point.getY()+1]);
                }
                openwhitePoint(minePoints[point.getX()-1][point.getY()]);
            }
            
            if(point.getX()+1<minePoints.length)
            {
                if(point.getY()-1>0)//左下
                {
                    openwhitePoint(minePoints[point.getX()+1][point.getY()-1]);
                }
                if(point.getY()+1<minePoints[0].length)//右下
                {
                    openwhitePoint(minePoints[point.getX()+1][point.getY()+1]);
                }
                openwhitePoint(minePoints[point.getX()+1][point.getY()]);
            }
            
            if(point.getY()-1>=0)
            {
                openwhitePoint(minePoints[point.getX()][point.getY()-1]);
            }
            if(point.getY()+1<minePoints[0].length)
            {
                openwhitePoint(minePoints[point.getX()][point.getY()+1]);
            }
            
        }
        
        
    }
    
    
    private void insertFlag(Point point)
    {
        if((point.getState()&0b110)==0b010)
        {
            System.out.println("已经打开!");
             return;
         }
        if((point.getState()&0b110)==0b100)
        {
            System.out.println("已经是插过的旗子了!");
            return ;
        }
        minePoints[point.getX()][point.getY()].setState(point.getState()|0b100);
        f++;
        pointCount--;
        
    }
    private void deletFlag(Point point)
    {
        if((point.getState()&0b110)==0b100)
        {
            minePoints[point.getX()][point.getY()].setState(minePoints[point.getX()][point.getY()].getState()&0b000);
        }
        
    }
    
    public void showMineBoard() {
        // 输出列下标
        System.out.print("\t");
        for (int i = 1; i <= minePoints[0].length; i++) {
            System.out.print(i + "\t");
        }
        System.out.println();
        // 输出*
        System.out.print("\t");
        for (int i = 0; i < minePoints[0].length; i++) {
            System.out.print("*\t");
        }
        System.out.println();

        for (int i = 0; i < minePoints.length; i++) {
            System.out.print((i + 1) + "*\t");

            for (int j = 0; j < minePoints[0].length; j++) {
                // 判断是否打开
                if ((minePoints[i][j].getState() & 0b110) == 0) // 未打开
                {
                    System.out.print("M\t");
                } else if ((minePoints[i][j].getState() & 0b100) == 0b100) {
                    // 10 表示插旗 xxxx10x & 0b110
                    System.out.print("F\t");

                } else {
                    if ((minePoints[i][j].getState() & 0b1) == 0b1) // 判断是否为雷
                    {
                        System.out.print("N\t");
                    } else {
                        if (minePoints[i][j].getState() >> 3 == 0) // 使用位运算来判断
                        {
                            System.out.print("\t"); // 值为0的话 就设置为空
                        } else {
                            System.out.print((minePoints[i][j].getState() >> 3) + "\t"); // 二进制数向右移动三位
                                                                                            // 0b0001000
                            // 0b0010000
                            /*
                             * 0b0011000
                             */
                        }
                    }

                }
            }
            System.out.println();
        }

    }

}
 

 

public class Start {
    public static void main(String[] args) {
        
    ClearMineGame s=new ClearMineGame();
     s.init();
        
    }

}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值