在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的实现相关推荐

  1. 怎样设计解开数独游戏

    很早之前大概是2014年的时候,我用WPF就是C#啦,写了一个数独游戏,那时之所以有这个想法,主要还是因为更早之前玩数独游戏时基本没有把题目解出,有点小受伤,但本葛葛毕竟是程序员啊,我解不出,可以用程 ...

  2. 使用Android studio开发一个数独游戏APP 系列第一讲

    数独是一种需要进行演算的逻辑游戏.玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并且满足每一行.每一列.每一个粗线宫内的数字均含1-9,不能重复.随着各种报刊杂志刊登了数独游戏,也让越 ...

  3. java数独流程图_九宫格数独游戏C语言解法

    最近几天深圳一直下雨,一个人闷在屋里很是无聊,偶然打开一个小游戏网站看到了我的最爱--九宫格数独游戏.共有1-5五个难度级别,像我这种资深玩家其他难度就不用考虑了,冲着难度5的题目就去了,结果做地汗流 ...

  4. mfc做数独游戏_我终于在iPhone上找到了体验最好的数独游戏

    我已经被一个 9×9 的格子困住将近 30 分钟,它既让人深陷其中还欲罢不能. 玩<数独 2>这款 app 之前我是抗拒的,因为我对数字超级无感,但抱着朋友告诉我入门很简单后试一试的心态, ...

  5. 数独游戏-安卓版源代码和分析。

    1.在创建的项目中,主要有以下类,其中, Game.java 是数独游戏的算法: keydialog:主要控制数据九宫格的显示和操作 MainActivity:主要加载主页面,代码只需改动一个setc ...

  6. 算法实践:数独的基本解法

    数独(Sudoku)是一种运用纸.笔进行演算的逻辑游戏.玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行.每一列.每一个粗线宫内的数字均含1-9,不重复. 每一道合格的数独谜 ...

  7. 算法实践——数独的基本解法

    数独(Sudoku)是一种运用纸.笔进行演算的逻辑游戏.玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行.每一列.每一个粗线宫内的数字均含1-9,不重复. 每一道合格的数独谜 ...

  8. 安卓期末大作业——Android数独游戏

    功能描述: app实现了数独游戏基础功能,难度分为入门,初级和大师级,可设置背景音乐.背景颜色和字体大小等,适合新手学习.搭建方法请看教程菜单中的androidstudio项目搭建教程. 开发语言: ...

  9. 求解数独的所有解法,java编程实现

    数独是一种考验眼力和逻辑的小游戏,关键在这个"独"字上,横竖不能重复,方块不能重复.今天我给大家介绍一种利用"循环+递归+回溯"的办法来用Java程序替我们完成 ...

最新文章

  1. 二分图最大匹配(匈牙利算法) POJ 3020 Antenna Placement
  2. leetcode算法题--有序数组中的单一元素
  3. 在 Linux 下运行 ASP.NET 2.0
  4. 修改sga后oracle打不开的解决方法
  5. ultraEdit-32 PHP/HTML智能提示
  6. PHP算法按数组某一字段进行排序
  7. [渝粤教育] 平顶山学院 传播理论与技巧 参考 资料
  8. 转账为demo,spring事务
  9. 微信iOS 7.0.9版本更新:今天的朋友圈是一片欢乐的海洋!
  10. gzip: File too large错误
  11. mysql 创建函数_MySQL函数,存储过程,用户管理
  12. Java定义一维数组从键盘赋值
  13. ThreadPoolExecutor运转机制详解
  14. linux运维必学python吗_Python学习资源整理
  15. pythonATM,购物车项目实战5-数据处理层
  16. ES6之导入模块时的内存共享
  17. VSCode 使用 StandardJS 自动格式化代码
  18. SDN网络编排与服务
  19. IntelliJ IDEA中文注释字体更换最佳方法
  20. 定义Mat类型显示未定义

热门文章

  1. 第6代无线技术802.11ax详解
  2. 跟女友旅游三天,还好Python治好了我的内耗
  3. SPD到底能为大家带来什么?(一) 缘起-曲折-三方-四方
  4. EOS基础全家桶(五)钱包管理
  5. 基于粒子群优化的BP神经网络(分类应用) - 附代码
  6. Python全栈开发记录_第七篇(模块_time_datetime_random_os_sys_hashlib_logging_configparser_re)...
  7. 想报学大学生计算机学习班哪有,兴城学习计算机,兴城学计算机报班,兴城学计算机自学好还是报班好 - IT教育频道...
  8. Selenium—八种元素定位方法
  9. K-Means++ 聚类之数据可视化:使用gnuplot
  10. 银联app控件 php后台开发