数独游戏的解法到App的实现
在LeetCode上偶然刷到一个解数独的题目:
编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
- 数字 1-9 在每一行只能出现一次。
- 数字 1-9 在每一列只能出现一次。
- 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 ‘.’ 表示。
一个数独。
答案被标成红色。
Note:
- 给定的数独序列只包含数字 1-9 和字符 ‘.’ 。
- 你可以假设给定的数独只有唯一解。
- 给定数独永远是 9x9 形式的。
这个题目很是有趣,解决了数独算不出来的难题。
首先想到的是暴力枚举了,也就是对每个空格进行枚举,回溯法。
public void solveSudoku(char[][] board) {//boolean数组 表明是否被使用过,按照给定的规则boolean[][] rows = new boolean[9][10];//行boolean[][] cols = new boolean[9][10];//列boolean[][] boxes = new boolean[9][10];//每个3*3小块//先都初始化,有值的表示已被使用for (int i = 0; i < 9; i++) {for (int j = 0; j < 9; j++) {if (board[i][j] != '.') {int num = board[i][j] - '0';rows[i][num] = true;cols[j][num] = true;boxes[(i / 3) * 3 + j / 3][num] = true;}}}//开始回溯bactTrack(board, rows, cols, boxes, 0, 0);}private boolean bactTrack(char[][] board, boolean[][] rows, boolean[][] cols, boolean[][] boxes, int i, int j) {//当回溯到达每行的边界时,进入下一行if (j == board[0].length) {j = 0;i++;//如果都遍历完成,也就是到达(9,9)处,找到其中一个解if (i == board.length) {return true;}}//如果是 空 格if (board[i][j] == '.') {for (int num = 1; num <= 9; num++) {int boxIndex = (i / 3) * 3 + j / 3;//这个时将i,j下标映射到对应的3*3小块中boolean isUesd = rows[i][num] || cols[j][num] || boxes[boxIndex][num];//判断是否被使用//如果没有被使用if (!isUesd) {rows[i][num] = true;cols[j][num] = true;boxes[boxIndex][num] = true;board[i][j] = (char) ('0' + num);//进入下一步if (bactTrack(board, rows, cols, boxes, i, j + 1)) {return true;}//如果下一步无解,回溯board[i][j] = '.';rows[i][num] = false;cols[j][num] = false;boxes[boxIndex][num] = false;}}} else {//不是空格直接跳过return bactTrack(board, rows, cols, boxes, i, j + 1);}//前面都没找到解return false;}
以上的算法便是根据给出的数独得到数独的解。
然后突然想试试这个算法,但是没有生成数独的算法,找到了数独-- 一个高效率生成数独的算法博客里的方法,也验证了下,能达到随机生成的效果(虽然都是伪随机)
//seedArray是用来生成数独的种子数组
private void creatSudokuArray(int[][] seedArray) {//产生一个1-9的不重复长度为9的一维数组ArrayList<Integer> randomList = new ArrayList<>();Random random = new Random();for (int i = 0; i < 9; i++) {int randomNum = random.nextInt(9) + 1;while (true) {if (!randomList.contains(randomNum)) {randomList.add(randomNum);break;}randomNum = random.nextInt(9) + 1;}}/*通过一维数组和原数组生成随机的数独矩阵遍历二维数组里的数据,在一维数组找到当前值的位置,并把一维数组当前位置加一处位置的值赋到当前二维数组中。目的就是将一维数组为依据,按照随机产生的顺序,将这个9个数据进行循环交换,生成一个随机的数独矩阵。*/for (int i = 0; i < 9; i++) {for (int j = 0; j < 9; j++) {for (int k = 0; k < 9; k++) {if (seedArray[i][j] == randomList.get(k)) {seedArray[i][j] = randomList.get((k + 1) % 9);break;}}//将生成的重新赋值给需要的,seedArray不做改变board[i][j] = seedArray[i][j];}}}
好了,有了生成数独的算法后,但是这只是个数独终盘,还需要挖空,最后利用随机数完成了不同等级的挖空
/*** 给指定数独终盘挖空,利用随机数,随机次数为level,也就是对每行挖level次空* 难度对应easy--5, middle--7, hard--9* 每次挖空后判断是否有解,若无解重新挖空* @param level 挖空等级*/public void resetSudoku(int level) {int[][] copies = new int[board.length][board[0].length];if (level < 5) {level = 5;}creatSudokuArray(seedArray);Random random = new Random();for (int i = 0; i < 9; i++) {for (int j = 0; j < level; j++) {int ran = random.nextInt(9);board[i][ran] = 0;}}if (!solveSudoku(copies)) {resetSudoku(level);}}
好了,有了这一系列的算法后,便可以自己写一个数独游戏了。
图片示意如下:
Github:DiyViewPracticeDemo
数独游戏的解法到App的实现相关推荐
- 怎样设计解开数独游戏
很早之前大概是2014年的时候,我用WPF就是C#啦,写了一个数独游戏,那时之所以有这个想法,主要还是因为更早之前玩数独游戏时基本没有把题目解出,有点小受伤,但本葛葛毕竟是程序员啊,我解不出,可以用程 ...
- 使用Android studio开发一个数独游戏APP 系列第一讲
数独是一种需要进行演算的逻辑游戏.玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并且满足每一行.每一列.每一个粗线宫内的数字均含1-9,不能重复.随着各种报刊杂志刊登了数独游戏,也让越 ...
- java数独流程图_九宫格数独游戏C语言解法
最近几天深圳一直下雨,一个人闷在屋里很是无聊,偶然打开一个小游戏网站看到了我的最爱--九宫格数独游戏.共有1-5五个难度级别,像我这种资深玩家其他难度就不用考虑了,冲着难度5的题目就去了,结果做地汗流 ...
- mfc做数独游戏_我终于在iPhone上找到了体验最好的数独游戏
我已经被一个 9×9 的格子困住将近 30 分钟,它既让人深陷其中还欲罢不能. 玩<数独 2>这款 app 之前我是抗拒的,因为我对数字超级无感,但抱着朋友告诉我入门很简单后试一试的心态, ...
- 数独游戏-安卓版源代码和分析。
1.在创建的项目中,主要有以下类,其中, Game.java 是数独游戏的算法: keydialog:主要控制数据九宫格的显示和操作 MainActivity:主要加载主页面,代码只需改动一个setc ...
- 算法实践:数独的基本解法
数独(Sudoku)是一种运用纸.笔进行演算的逻辑游戏.玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行.每一列.每一个粗线宫内的数字均含1-9,不重复. 每一道合格的数独谜 ...
- 算法实践——数独的基本解法
数独(Sudoku)是一种运用纸.笔进行演算的逻辑游戏.玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行.每一列.每一个粗线宫内的数字均含1-9,不重复. 每一道合格的数独谜 ...
- 安卓期末大作业——Android数独游戏
功能描述: app实现了数独游戏基础功能,难度分为入门,初级和大师级,可设置背景音乐.背景颜色和字体大小等,适合新手学习.搭建方法请看教程菜单中的androidstudio项目搭建教程. 开发语言: ...
- 求解数独的所有解法,java编程实现
数独是一种考验眼力和逻辑的小游戏,关键在这个"独"字上,横竖不能重复,方块不能重复.今天我给大家介绍一种利用"循环+递归+回溯"的办法来用Java程序替我们完成 ...
最新文章
- 二分图最大匹配(匈牙利算法) POJ 3020 Antenna Placement
- leetcode算法题--有序数组中的单一元素
- 在 Linux 下运行 ASP.NET 2.0
- 修改sga后oracle打不开的解决方法
- ultraEdit-32 PHP/HTML智能提示
- PHP算法按数组某一字段进行排序
- [渝粤教育] 平顶山学院 传播理论与技巧 参考 资料
- 转账为demo,spring事务
- 微信iOS 7.0.9版本更新:今天的朋友圈是一片欢乐的海洋!
- gzip: File too large错误
- mysql 创建函数_MySQL函数,存储过程,用户管理
- Java定义一维数组从键盘赋值
- ThreadPoolExecutor运转机制详解
- linux运维必学python吗_Python学习资源整理
- pythonATM,购物车项目实战5-数据处理层
- ES6之导入模块时的内存共享
- VSCode 使用 StandardJS 自动格式化代码
- SDN网络编排与服务
- IntelliJ IDEA中文注释字体更换最佳方法
- 定义Mat类型显示未定义
热门文章
- 第6代无线技术802.11ax详解
- 跟女友旅游三天,还好Python治好了我的内耗
- SPD到底能为大家带来什么?(一) 缘起-曲折-三方-四方
- EOS基础全家桶(五)钱包管理
- 基于粒子群优化的BP神经网络(分类应用) - 附代码
- Python全栈开发记录_第七篇(模块_time_datetime_random_os_sys_hashlib_logging_configparser_re)...
- 想报学大学生计算机学习班哪有,兴城学习计算机,兴城学计算机报班,兴城学计算机自学好还是报班好 - IT教育频道...
- Selenium—八种元素定位方法
- K-Means++ 聚类之数据可视化:使用gnuplot
- 银联app控件 php后台开发