数独游戏求解程序

最近玩数独游戏,每行、每列、以及9宫格都包含1-9个数组。觉得这东西很适合用程序来求解。于是我就仿照中国象棋的暴力搜索算法(可参考我之前写的文章极大极小搜索算法),写了一个程序求解数独,直接贴代码了

/**
 * 模仿象棋程序的搜索算法,写一个求解数独的程序
 * @author royhoo
 *
 */
public class ShuDu {
	private int[][] board;		// 数独矩阵
	private int zeroNum;			// 缺失的数字个数
	private int filledNum;	// 已填充的数字个数
	public int[][] result;		// 填充后的最终结果

	public ShuDu(int[][] board){
		this.board = board;

		zeroNum = getZeroNum();
		filledNum = 0;
		result = new int[9][9];
	}

	/**
	 * 计算缺失的数字个数
	 * @return
	 */
	private int getZeroNum(){
		int num = 0;
		for(int i=0; i<9; i++){
			for(int j=0; j<9; j++){
				if(board[i][j] == 0){
					num++;
				}
			}
		}

		return num;
	}

	/**
	 * 递归调用,填充缺失的数组。如果填充完毕,返回-1.否则,返回0。
	 */
	public int search(){
		for(int i=0; i<9; i++){
			for(int j=0; j<9; j++){
				if(board[i][j] > 0){
					continue;
				}

				int[] nums = getLegalNumbers(i, j);
				for(int k=1; k<=9; k++){	// 这个for循环,类似于象棋中搜索了一层。
					if(nums[k] > 0){
						board[i][j] = k;
						filledNum++;
						if(filledNum >= zeroNum){
							// 缺失数字全部填充完毕
							copyResult();
							return -1;
						}
						if(search() == -1){
							return -1;
						}
						board[i][j] = 0;
						filledNum--;
					}
				}
				return 0;
			}
		}

		return 0;
	}

	/**
	 * 返回某位置可以填的数字
	 */
	private int[] getLegalNumbers(int i, int j){
		int[] result = {0,1,1,1,1,1,1,1,1,1};

		// 保证第i行不重复
		for(int k=0; k<9; k++){
			if(board[i][k] > 0){
				result[board[i][k]] = 0;
			}
		}

		// 保证第j列不重复
		for(int k=0; k<9; k++){
			if(board[k][j] > 0){
				result[board[k][j]] = 0;
			}
		}

		// 保证9宫格不重复
		for(int m=(i/3)*3; m<(i/3 + 1)*3; m++){
			for(int n=(j/3)*3; n<(j/3 + 1)*3; n++){
				if(board[m][n] > 0){
					result[board[m][n]] = 0;
				}
			}
		}

		return result;
	}

	private void copyResult(){
		for(int i=0; i<9; i++){
			for(int j=0; j<9; j++){
				result[i][j] = board[i][j];
			}
		}
	}

	public static void main(String[] args) {
		int[][] board = {
				{3,5,0,9,0,0,6,0,0},
				{0,0,6,0,0,0,0,0,0},
				{4,2,0,5,0,0,0,9,0},
				{5,0,0,6,0,4,0,2,0},
				{0,1,0,2,8,0,3,0,0},
				{0,0,2,0,9,5,0,0,4},
				{0,0,3,0,2,0,5,0,8},
				{0,4,0,0,1,0,9,0,6},
				{0,0,0,0,0,0,0,1,0}
		};

		ShuDu myShuDu = new ShuDu(board);
		myShuDu.search();
		int[][] result = myShuDu.result;
		for(int i=0; i<9; i++){
			String str = "";
			for(int j=0; j<9; j++){
				str = str + result[i][j] + ",";
			}
			System.out.println(str);
		}
	}

}
时间: 2024-12-25 01:02:43

数独游戏求解程序的相关文章

数独游戏求解:解法适用于任意阶数的数独

0.数独简介 数独(すうどく,Sūdoku)是一种运用纸.笔进行演算的逻辑游戏.以九阶数独为例,玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行.每一列.每一个粗线宫内的数字均含1-9,不重复. 1)4阶(可填数字范围1~4,宫格2阶) 2)9阶(可填数字范围1~9,宫格3阶) 3)16阶(可填数字范围1~16,宫格4阶) *见附录 1.数独的表示 对于N阶数独可以用一个N*N的二维数组表示 1)数独阶数GridRank=N 2)宫格阶数SubGridRank=Sqrt

C语言学习 数独游戏

摘要:花了1周多时间学习了C语言,开始练手写解数独游戏的程序. 作者:乌龙哈里 时间:2015-11-22 平台:Window7 64bit,TCC 0.9.26(x86-64 Win64) 参考: 互动百科 数独 章节: 正文: 原来也用C#和Go语言写过,主要思路是暴力撞大运破解.思路什么的在程序了都注释了,不多说了.可能是没用什么先进的算法,感觉C解题速度和C#差不多(除了C#第一次运行之外),基本上出来一个数独表都不用1秒. 附完整程序: 1 /*********************

使用双向十字链表(或Dancing Links)解数独游戏

#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; struct Data { void assign(int x,int y,int z) { row=x; col=y; val=z; } int row,col,val; } data[730]; struct Node { Node(int x=0,int y=0): row(x),col(y),up(this)

数独游戏程序

mathe的专栏 http://blog.csdn.net/mathe/article/details/1175498 数独游戏程序 分类: 软件2007-08-23 11:02 22389人阅读 评论(26) 收藏 举报 游戏c图形扩展 数独简介:    数独是一个智力小游戏.一个9*9的棋盘,共有9行9列以及9个互不相交的3*3九宫格.里面某些格子开始已经填上了1-9中的一些数字.要求玩家在余下的空格中填上1-9中数字,使得每行,每列和每个3*3九宫格中都正好包含1-9数字各一个.数独游戏保

java程序计算数独游戏

兴趣来了,写了个简单的数独游戏计算程序,未做算法优化. 通过文件来输入一个二维数组,9行,每行9个数组,数独游戏中需要填空的地方用0来表示.结果也是打印二维数组. 1 import java.io.File; 2 import java.util.List; 3 //代表数独中的一个单元格位置 4 public class Cell { 5 6 // 所在行 7 public int row; 8 // 所在列 9 public int colum; 10 // 值 11 public int

数独游戏代码

//数独游戏c++ class CSudoku { int map[9][9]; int blanks; int smod; int solves; int check(int,int,int*); void dfs(); public: enum{ANY=0,ALL=1}; CSudoku(int); CSudoku::CSudoku(int *data); void SudokuGenerator(int); //随机生成数独,n越大越难 void SudokuGenerator(int *

5乘5的数独游戏

用了三个周的业余时间,日思夜想的牵挂才把5乘5的数独游戏填满了二十五个宫格. 在这前一篇<数独游戏新篇章>里面,通过对第一个宫格使用位移变换来得到后面的二十四个宫格,总觉得没有什么意思.现在可以通过回溯的办法填满整个二十五个宫格,又觉得这样的结果好像120个点的连通图里面的哈密顿回路的条数那样多得不可思议,所以就想在一个已经填入了一部分数字的情况下,再把其余的格子填满,因为已经有了可以解决3乘3标准数独的基础(前一篇那一个是芬兰数学家给出的世界最难标准数独,编写的程序运行十小时就能得到结果,就

Swift数独游戏优化&mdash;&mdash;C++与OC混编、plist自动生成

一.为什么要C++与OC混编? 在我之前的数独游戏中涉及到的数独游戏生成算法是参考的网上其他人的算法,是利用C++来实现的.   但是在我的例子中我发现这样存在一定的局限性: 1.我是利用Terminal的重定向功能来实现输出的,这样不能查看程序的实际运行状态信息. 2.C++编写的代码不能直接生成plist文件,而OC有直接的API可以生成plist文件.(当我前几天刚知道的时候我感觉之前用C++生成plist是有多勇敢)   二.如何进行C++与OC混编? 1.OC文件后缀改为"mm&quo

【DFS】数独游戏

DFS(深度优先搜索): 深度优先搜索算法(英语:Depth-First-Search,简称DFS)是一种用于遍历或搜索树或图的算法. 沿着树的深度遍历树的节点,尽可能深的搜索树的分支.当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点.整个进程反复进行直到所有节点都被访问为止.属于盲目搜索,最糟糕的情况算法时间复杂度为O(!n).(一条路走到黑,直到走不下去才往回走) 基本模板: int check(参数) { if(满足条件) return 1;