数独游戏求解程序

Posted royhoo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数独游戏求解程序相关的知识,希望对你有一定的参考价值。

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

/**
 * 模仿象棋程序的搜索算法,写一个求解数独的程序
 * @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);
		}
	}

}

以上是关于数独游戏求解程序的主要内容,如果未能解决你的问题,请参考以下文章

数独 算法 C语言 代码

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

用c语言写一个简易数独的思路。要代码

Javascript递归回溯数独求解器

优化回溯算法求解数独

数独GUI程序项目实现