android 数独小游戏
16lz
2021-01-26
偶然想起来写一个数独的小游戏自己没事的时候玩一玩,锻炼锻炼思路。
先上效果截图
数独生成的算法,参见博客:数独生成算法
数独游戏的最基础的在于生成数独,由于生成数独的算法运算问题,为了简化,本次数独的生成使用了 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 data=new ArrayList(); 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 数独
APP下载体验
http://bmob-cdn-22713.b0.upaiyun.com/2018/12/04/f01fbccd40fef03d80fc28eb1acd99ba.apk
更多相关文章
- Android之Windows下生成动态库so并打包到APK中
- Android(安卓)笔记 :Android(安卓)热修复 Tinker接入及源码浅析
- YUV 400 格式图像转换成 ARGB 格式图像中犯的一个低级 Bug
- Android关于图片和Base64转码的工具类
- Android(安卓)柱状图的实现 简单化的
- Gradle 属性总结收录
- android 数组排序
- 生成XML
- Android(安卓)将bitmap保存为本地png图片