android 数独小游戏

偶然想起来写一个数独的小游戏自己没事的时候玩一玩,锻炼锻炼思路。

先上效果截图

         

数独生成的算法,参见博客:数独生成算法

数独游戏的最基础的在于生成数独,由于生成数独的算法运算问题,为了简化,本次数独的生成使用了 10 个基类,每次生成数独的时候随机从是个基类中选取一个模板,在根据模板将对应的 a--i 的字母 随机与 1--9 分别对应,然后生成一个数独。

数独模板基类

public class StandShudu {
    /**
     *  从10个基准数组中抽取一个基准数组
     *  然后将 a-i 随机分配 1-9
     *  随机赋予 a--i的值为不重复的 1--9 的值 生成一个数组
     *  有多少种可能我也不会算,反正够玩的了
     */
    public String[][] getStand(int index){
        switch (index){
            case 0:
                return stand0;
            case 1:
                return stand1;
            case 2:
                return stand2;
            case 3:
                return stand3;
            case 4:
                return stand4;
            case 5:
                return stand5;
            case 6:
                return stand6;
            case 7:
                return stand7;
            case 8:
                return stand8;
            case 9:
                return stand9;
            default:
                return stand0;
        }
    }

    private String[][] stand1=new String[][]{
            {"c","h","e","b","i","a","g","f","d",},
            {"f","b","d","g","e","c","h","a","i",},
            {"g","i","a","d","f","h","c","e","b",},
            {"h","g","i","e","d","b","a","c","f",},
            {"a","d","f","c","g","i","b","h","e",},
            {"e","c","b","h","a","f","i","d","g",},
            {"b","e","c","f","h","g","d","i","a",},
            {"i","f","g","a","c","d","e","b","h",},
            {"d","a","h","i","b","e","f","g","c",}
    };

    private String[][] stand2=new String[][]{
            {"a","c","f","b","d","e","h","i","g",},
            {"b","g","d","h","i","a","f","c","e",},
            {"h","i","e","f","c","g","b","a","d",},
            {"d","f","b","g","e","c","a","h","i",},
            {"g","a","i","d","h","f","c","e","b",},
            {"e","h","c","i","a","b","g","d","f",},
            {"i","e","g","a","f","h","d","b","c",},
            {"c","b","h","e","g","d","i","f","a",},
            {"f","d","a","c","b","i","e","g","h",}
    };


    private String[][] stand3=new String[][]{
            {"f","g","h","e","i","d","b","a","c",},
            {"e","b","c","f","a","g","i","h","d",},
            {"d","a","i","c","h","b","f","e","g",},
            {"i","f","d","a","g","e","c","b","h",},
            {"b","h","a","i","d","c","g","f","e",},
            {"c","e","g","b","f","h","a","d","i",},
            {"h","c","b","g","e","f","d","i","a",},
            {"a","d","f","h","c","i","e","g","b",},
            {"g","i","e","d","b","a","h","c","f",}
    };
    private String[][] stand4=new String[][]{
            {"i","a","h","b","c","f","d","e","g",},
            {"f","d","e","g","i","h","b","c","a",},
            {"b","c","g","e","a","d","i","f","h",},
            {"g","i","f","c","b","a","h","d","e",},
            {"d","h","a","f","g","e","c","i","b",},
            {"e","b","c","h","d","i","a","g","f",},
            {"a","g","b","i","e","c","f","h","d",},
            {"h","e","i","d","f","b","g","a","c",},
            {"c","f","d","a","h","g","e","b","i",}
    };
    private String[][] stand5=new String[][]{
            {"h","e","d","b","f","g","a","c","i",},
            {"c","i","a","d","e","h","b","g","f",},
            {"f","b","g","a","i","c","e","h","d",},
            {"a","f","i","e","g","d","h","b","c",},
            {"d","g","h","c","b","f","i","a","e",},
            {"e","c","b","h","a","i","d","f","g",},
            {"g","d","e","f","h","b","c","i","a",},
            {"b","a","f","i","c","e","g","d","h",},
            {"i","h","c","g","d","a","f","e","b",}
    };

    private String[][] stand6=new String[][]{
            {"i","g","b","f","a","h","e","c","d",},
            {"c","a","h","d","g","e","i","b","f",},
            {"f","d","e","b","c","i","h","a","g",},
            {"b","c","a","e","d","g","f","h","i",},
            {"g","e","i","h","f","a","b","d","c",},
            {"h","f","d","c","i","b","a","g","e",},
            {"a","i","c","g","b","f","d","e","h",},
            {"d","h","f","a","e","c","g","i","b",},
            {"e","b","g","i","h","d","c","f","a",}
    };
    private String[][] stand7=new String[][]{
            {"d","g","c","i","e","f","b","h","a",},
            {"f","e","h","a","b","c","g","i","d",},
            {"a","b","i","d","g","h","c","f","e",},
            {"e","a","g","f","d","b","i","c","h",},
            {"i","c","d","e","h","g","f","a","b",},
            {"b","h","f","c","i","a","e","d","g",},
            {"h","d","b","g","f","i","a","e","c",},
            {"c","f","e","b","a","d","h","g","i",},
            {"g","i","a","h","c","e","d","b","f",}
    };
    private String[][] stand8=new String[][]{
            {"e","f","g","a","d","c","b","h","i",},
            {"d","i","h","b","g","f","a","e","c",},
            {"c","a","b","e","h","i","d","f","g",},
            {"i","h","f","d","b","g","c","a","e",},
            {"g","e","a","i","c","h","f","d","b",},
            {"b","d","c","f","e","a","g","i","h",},
            {"a","c","e","h","f","b","i","g","d",},
            {"h","b","i","g","a","d","e","c","f",},
            {"f","g","d","c","i","e","h","b","a",}
    };
    private String[][] stand9=new String[][]{
            {"d","a","g","e","f","c","h","i","b",},
            {"f","b","i","g","d","h","e","a","c",},
            {"e","c","h","i","b","a","g","d","f",},
            {"h","d","f","c","a","e","b","g","i",},
            {"i","g","a","b","h","f","c","e","d",},
            {"c","e","b","d","i","g","f","h","a",},
            {"a","f","c","h","e","i","d","b","g",},
            {"g","h","d","a","c","b","i","f","e",},
            {"b","i","e","f","g","d","a","c","h",}
    };

    private String[][] stand0=new String[][]{
            {"a","b","i","g","d","e","c","h","f",},
            {"c","h","f","b","a","i","e","d","g",},
            {"e","d","g","c","f","h","b","i","a",},
            {"d","e","b","a","h","c","g","f","i",},
            {"h","i","c","f","g","b","d","a","e",},
            {"g","f","a","i","e","d","h","c","b",},
            {"i","c","h","e","b","f","a","g","d",},
            {"b","g","d","h","i","a","f","e","c",},
            {"f","a","e","d","c","g","i","b","h",}
    };

获取数独的类 ,随机获取一个模板,然后用 1--9 填充

public class ShuduData {

    private int[][] number = new int[9][9];
    private StandShudu standShudu=new StandShudu();
    private Random random=new Random();

    public int[][] generateShuDu(){
        /***  获取随机的模板  **/
        String[][] stand=standShudu.getStand(random.nextInt(10));
        /** 带选择数字列表 **/
        ArrayList<Integer> data=new ArrayList<Integer>();
        data.add(1); data.add(2); data.add(3);
        data.add(4); data.add(5); data.add(6);
        data.add(7); data.add(8); data.add(9);
        /***  随机存储排序 **/
        int[] s=new int[9];
        int index=0;
        while (index<9){
            int t=random.nextInt(data.size());
            s[index]=data.get(t);
            data.remove(t);
            index++;
        }
        /**  根据模板按照获取的随机序列进行数据填充 **/
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                number[i][j]=s[getIndex(stand[i][j])-1];
            }
        }
        return number;
    }

    private Integer getIndex(String s){
        switch (s){
            case "a":
                return 1;
            case "b":
                return 2;
            case "c":
                return 3;
            case "d":
                return 4;
            case "e":
                return 5;
            case "f":
                return 6;
            case "g":
                return 7;
            case "h":
                return 8;
            case "i":
                return 9;
            default:
                return 1;
        }
    }

使用此方法虽然不能 模拟出数独的所有的可能,但是为了简化算法采用此方法。

根据获取的数独数组初始化游戏界面

/**
 * 初始化数据
 */
private fun initSize(){
    data= emptyArray()
    data= ShuduData().generateShuDu()
    val initData=Array(9) { IntArray(9) }
    for(i in 0 until 9){
        for(j in 0 until smd){
            val ranNum = random.nextInt(9)
            initData[i][ranNum]=data[i][ranNum]
        }
    }
    nv_01.number=initData
}

smd 为数独的难易程度(即每一列的提示数据的个数)

由于数独的不确定性,当所有的数字被填满时,并不能用最初获取的数独数组与填完的数组进行比对校验(在数组中部分数据的位置具有不确定性)。填玩的数组需要根据数独的校验方法进行校验(即横竖不相同,所在的小的 3 * 3 的数组里面也不能相同)。校验的算法如下:

//校验
private void checkIsRight(){
    boolean right=true;
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            int node=number[i][j];
            //此位置尚未填写
            if(node==0){
                listener.onResultIsTrue(false,-1);
                return;
            }
            //横向检查是否有相同的项 ,检查当前节点往后的节点
            for(int sx=i+1;sx<9;sx++){
                if(node==number[sx][j]){
                    right=false;
                    error[sx][j]=node;
                    error[i][j]=node;
                }
            }
            //纵向检查是否有相同的项 ,检查当前节点往下的节点
            for(int sy=j+1;sy<9;sy++){
                if(node==number[i][sy]){
                    right=false;
                    error[i][sy]=node;
                    error[i][j]=node;
                }
            }
            //根据下标判断 当前节点所在的 3 X 3 的格子中数字是否重复
            //已重复的数字放入 error 数组对应的下标
            int xi=i/3;
            int yi=j/3;
            for(int vx=0;vx<3;vx++){
                for(int vy=0;vy<3;vy++){
                    if((3*xi+vx)!=i && (3*yi+vy)!=j){
                        if(node==number[3*xi+vx][3*yi+vy]){
                            right=false;
                            error[3*xi+vx][3*yi+vy]=node;
                            error[i][j]=node;
                        }
                    }
                }
            }
        }
    }
    listener.onResultIsTrue(right,0);
}

此外本项目中还包括了 ShareSdk微信QQ的分享,以及bmob后端云的简单使用。详情见项目源码。

码云中国 git 源码链接:Android 数独

猜你喜欢

转载自blog.csdn.net/weixin_41191134/article/details/84983946