码迷,mamicode.com
首页 > 其他好文 > 详细

数独游戏求解程序

时间:2017-04-28 00:22:04      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:log   result   不重复   矩阵   pre   class   highlight   递归调用   循环   

最近玩数独游戏,每行、每列、以及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);
		}
	}

}

数独游戏求解程序

标签:log   result   不重复   矩阵   pre   class   highlight   递归调用   循环   

原文地址:http://www.cnblogs.com/royhoo/p/6777888.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!