Android开发——手把手写APP(四)——数独游戏编写(三)——计算格子不可用数据

计算格子不可用数据


单点触摸事件

当用户点击View的时候,会执行onTouchEvent事件,用户点击的类型,比如长按、按下、松开等等,以及用户点击的时间、坐标都被存在这个MotionEvent类中。
getAction方法获取用户点击的类型
getXgetY获取点击的坐标

public boolean onTouchEvent(MotionEvent event){
	//获取事件的种类
	event.getAction();
	//获取点击的坐标
	event.getX();
	event.getY();
}

碰撞检测

检测用户点击的是哪个单元格,我们只需要知道这个单元格的横纵坐标,便可知道是第几个单元格,然后在onTouchEvent方法里进行相应操作。

    //点击事件
    @Override
    public  boolean onTouchEvent(MotionEvent event){
        //如果点击不是按下则重置方法
        if(event.getAction()!=MotionEvent.ACTION_DOWN)
            return super.onTouchEvent(event);
        //获取点击格子的X和Y值
        int selectedX = (int) (event.getX() / width);
        int selectedY = (int) (event.getY() / height);
        
        return true;
    }

现在获取了点击格子的X值和Y值,需要对这个格子不可用数据进行计算

不可用数据计算

不可用数据有三,其一,这一行中已有的数据,其二,这一列中已有的数据,其三,小九宫格已有的数据。根据已经确定了的格子来计算这三个数据,并存放在used数组中。
下面有三个方法,最重要的是最后一个方法的算法,计算单独格子的不可用数据。
其他两个是补充需要。

   //用于计算所有单元格对应的不可用数据
    public void calculateAllUsedTiles(){
        for(int x = 0;x < 9;x++){
            for(int y = 0;y < 9;y++){
                used[x][y] = calculateUsedTiles(x,y);
            }
        }
    }

    //根据坐标取出单元格不可用数据
    public int[] getUsedTilesByCoor(int x,int y) {
        return used[x][y];
    }

    //计算某一单元格中已经不可用的数据
    public int[] calculateUsedTiles(int x,int y){
        int c[] = new int[9];

        //计算这一列全部用过的数字
        for(int i = 0;i < 9;i++){
            if(i == y)
                continue;
            int t = getTiile(x,i);
            if(t != 0)
                c[t-1] = t;
        }

        //计算这一行全部用过的数字
        for(int i = 0;i < 9;i++){
            if(i == x)
                continue;
            int t = getTiile(i,y);
            if(t != 0)
                c[t-1] = t;
        }

        //计算小九宫格已经用过的数字
        int startX = (x / 3) * 3;
        int startY = (y / 3) * 3;
        for(int i = startX;i < startX + 3;i++){
            for(int j = startY;j < startY + 3;j++){
                if(i == x&&j == y)
                    continue;
                int t = getTiile(i,j);
                if(t != 0)
                    c[t-1] = t;
            }

        }

        //压缩数据,把数组c中0去除掉
        int nused = 0;
        //计算c中不为0的数nused
        for (int t:c
             ) {
            if(t != 0)
                nused++;
        }
        int c1[] = new int[nused];
        int a = 0;
        //把c中不为0的数,赋值给c1
        for (int t:c
             ) {
            if(t != 0)
                c1[a++] = t;
        }
        return c1;
    }

那么,我们已经把单元格不可用数据计算出来了,下一步就是显示一个数字对话框,让玩家来选择可用数据,这个操作无疑是在点击事件中完成的,本文暂不讲对话框,先用System打印到控制台代替,看输出效果。
点击事件的完整版:

    //点击事件
    @Override
    public  boolean onTouchEvent(MotionEvent event){
        //如果点击不是按下则重置方法
        if(event.getAction()!=MotionEvent.ACTION_DOWN)
            return super.onTouchEvent(event);
        //获取点击格子的X和Y值
        int selectedX = (int) (event.getX() / width);
        int selectedY = (int) (event.getY() / height);

        //获取点击格子不可用数据
        int used[] = game.getUsedTilesByCoor(selectedX,selectedY);

        //输出不可用数据
        for(int i = 0;i < used.length;i++){
            System.out.println(used[i]);
        }
        return true;
    }

小编点击了第一行第五列的单元格
在这里插入图片描述
输出结果为 1 2 3 4 6
在这里插入图片描述
注:千万别忘了,小九宫格也不能重复哦

发布了230 篇原创文章 · 获赞 250 · 访问量 28万+

猜你喜欢

转载自blog.csdn.net/weixin_42247720/article/details/103504104