生活随笔
收集整理的這篇文章主要介紹了
数独游戏求解:解法适用于任意阶数的数独
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
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(N)
3)數獨包含宮的階數SubGridIncludeRank=Sqrt(N)
4)可填最大數字MaxValue=N
5)可填最小數字MinValue=1??
?
Public Class SudokuClass? ? Public Property Rank As Integer '數獨的階數? ?? ???Get? ?? ?? ?? ?Return GridRank? ?? ???End Get? ?? ???Set(ByVal value As Integer)? ?? ?? ?? ?GridRank = value? ?? ?? ?? ?SubGridRank = CType(Math.Sqrt(value), Integer)? ?? ?? ?? ?SubGridIncludeRank = SubGridRank? ?? ?? ?? ?DataMaxValue = value? ?? ?? ?? ?DataMinValue = 1? ?? ???End Set? ? End Property? ? Public Property GridData As Integer?(,) '數獨的數據? ? Private GridRank As Integer '數獨的階數? ? Private SubGridRank As Integer '子數獨(宮)的階數? ? Private SubGridIncludeRank As Integer '數獨包含子數獨(宮)的階數? ? Private DataMaxValue As Integer '數獨可填最大數值? ? Private DataMinValue As Integer '數獨可填最小數值? ? ''' <summary>? ? ''' 實例化一個指定階數的數獨類? ? ''' </summary>? ? ''' <param name="nRank">指定的階數</param>? ? Public Sub New(nRank As Integer)? ?? ???Me.Rank = nRank? ? End SubEnd Class 復制代碼
6)任意階數獨的表示(N≠K2,K>1,K∈Z)
任意階數獨僅有一個宮,所以數獨階數和宮階數相等。以7階為例,設置GridRank=7,SubGridRank=7,SubGridIncludeRank=1即可。
2、數獨的求解
采用回溯法,直接尋找到一個空白格,嘗試填入所有可能的數字,繼續填下一個空白格,直至填滿或者不能繼續填入為止(不符合規則)。
1)尋找空白格
空白格的選擇至關重要,當一個格子的限制越多,也就是可填入數字越少時,優先選擇該空白格。這樣做可以大大降低遞歸填格子的次數。
'查找當前空白格(最佳格)? ? Private Function getStartPoint(ByRef data As Integer?(,)) As Point? ?? ???Dim gPoint As Point? ?? ???Dim tempValue As Integer? ?? ???Dim maxValue As Integer? ?? ???'查找限制最多的空白格? ?? ???For i = 0 To GridRank - 1? ?? ?? ?? ?For j = 0 To GridRank - 1? ?? ?? ?? ?? ? If data(i, j) = 0 Then? ?? ?? ?? ?? ?? ???tempValue = 0? ?? ?? ?? ?? ?? ???For k = 0 To GridRank - 1? ?? ?? ?? ?? ?? ?? ?? ?If data(i, k) > 0 Then tempValue += 1? ?? ?? ?? ?? ?? ?? ?? ?If data(k, j) > 0 Then tempValue += 1? ?? ?? ?? ?? ?? ?? ?? ?If data((i \ SubGridIncludeRank) * SubGridIncludeRank + k \ SubGridIncludeRank, (j \ SubGridIncludeRank) * SubGridIncludeRank + (k Mod SubGridIncludeRank)) > 0 Then tempValue += 1? ?? ?? ?? ?? ?? ???Next? ?? ?? ?? ?? ?? ???If tempValue > maxValue Then? ?? ?? ?? ?? ?? ?? ?? ?maxValue = tempValue? ?? ?? ?? ?? ?? ?? ?? ?gPoint.X = i? ?? ?? ?? ?? ?? ?? ?? ?gPoint.Y = j? ?? ?? ?? ?? ?? ???End If? ?? ?? ?? ?? ? End If? ?? ?? ?? ?Next? ?? ???Next? ?? ???If maxValue > 0 Then? ?? ?? ?? ?Return gPoint? ?? ???Else? ?? ?? ?? ?gPoint.X = -1? ?? ?? ?? ?gPoint.Y = -1? ?? ?? ?? ?Return gPoint? ?? ???End If? ? End Function 復制代碼
當確定空白格后就需要向其中填入數字了,一一篩選出符合規則的數字。規則就是格子當前行,當前列,當前宮不能有相同數值出現。
'判斷同行同列同宮是否已經存在? ? Private Function GetExisting(ByRef data As Integer?(,), ByVal gX As Integer, ByVal gY As Integer, ByVal gValue As Integer) As Boolean? ?? ???For k = 0 To GridRank - 1? ?? ?? ?? ?If data(gX, k) = gValue OrElse data(k, gY) = gValue OrElse data((gX \ SubGridIncludeRank) * SubGridIncludeRank + k \ SubGridIncludeRank, (gY \ SubGridIncludeRank) * SubGridIncludeRank + (k Mod SubGridIncludeRank)) = gValue Then? ?? ?? ?? ?? ? Return True? ?? ?? ?? ?End If? ?? ???Next? ?? ???Return False? ? End Function 復制代碼
2)回溯法求解
簡單的遞歸調用即可。
'遞歸求解數獨? ? Private Function GetValue(ByVal gData As Integer?(,)) As List(Of Integer?(,))? ?? ???Dim ResultList As New List(Of Integer?(,))? ?? ???Dim i, j As Integer? ?? ???Dim tempPoint As Point = getStartPoint(gData)? ?? ???i = tempPoint.X : j = tempPoint.Y? ?? ???If i >= 0 AndAlso j >= 0 Then? ?? ?? ?? ?For value = DataMinValue To DataMaxValue? ?? ?? ?? ?? ? If GetExisting(gData, i, j, value) = False Then? ?? ?? ?? ?? ?? ???gData(i, j) = value? ?? ?? ?? ?? ?? ???GetValue(gData)? ?? ?? ?? ?? ?? ???gData(i, j) = 0? ?? ?? ?? ?? ? End If? ?? ?? ?? ?Next? ?? ???Else? ?? ?? ?? ?'新增一個結果? ?? ?? ?? ?ResultList.Add(gData)? ?? ???End If? ?? ???Return ResultList? ? End Function 復制代碼
3)其他
判斷一個序列(數組)中是否有重復數字
?
''' <summary>? ? ''' 判斷一個序列是否有重復數字? ? ''' </summary>? ? ''' <param name="Numbers"></param>? ? ''' <returns></returns>? ? Private Function IsDuplicate(ByVal Numbers() As Integer) As Boolean? ?? ???Array.Sort(Numbers)? ?? ???If Numbers.Length > 1 Then? ?? ?? ?? ?For i = 0 To Numbers.Length - 2? ?? ?? ?? ?? ? If Numbers(i) = Numbers(i + 1) Then Return True? ?? ?? ?? ?Next? ?? ???End If? ?? ???Return False? ? End Function 復制代碼
判斷數獨是否填寫完畢,無空白格且所有格子填入的數字符合規則
Public Function IsWin(ByVal Numbers As Integer?(,)) As Boolean? ?? ???For i = 0 To GridRank - 1? ?? ?? ?? ?For j = 0 To GridRank - 1? ?? ?? ?? ?? ? If Not Numbers(i, j).HasValue Then Return False '出現空格? ?? ?? ?? ?Next? ?? ???Next? ?? ???Dim TempInt As New List(Of Integer)? ?? ???'判斷行重復? ?? ???For i = 0 To GridRank - 1? ?? ?? ?? ?TempInt.Clear()? ?? ?? ?? ?For j = 0 To GridRank - 1? ?? ?? ?? ?? ? TempInt.Add(CInt(Numbers(i, j)))? ?? ?? ?? ?Next? ?? ?? ?? ?If IsDuplicate(TempInt.ToArray) Then Return False? ?? ???Next? ?? ???'判斷列重復? ?? ???For j = 0 To GridRank - 1? ?? ?? ?? ?TempInt.Clear()? ?? ?? ?? ?For i = 0 To GridRank - 1? ?? ?? ?? ?? ? TempInt.Add(CInt(Numbers(i, j)))? ?? ?? ?? ?Next? ?? ?? ?? ?If IsDuplicate(TempInt.ToArray) Then Return False? ?? ???Next? ?? ???'判斷宮格重復? ?? ???For i = 0 To GridRank - 1 Step SubGridRank? ?? ?? ?? ?For j = 0 To GridRank - 1 Step SubGridRank? ?? ?? ?? ?? ? TempInt.Clear()? ?? ?? ?? ?? ? For i2 = 0 To SubGridRank - 1? ?? ?? ?? ?? ?? ???For j2 = 0 To SubGridRank - 1? ?? ?? ?? ?? ?? ?? ?? ?TempInt.Add(CInt(Numbers(i + i2, j + j2)))? ?? ?? ?? ?? ?? ???Next? ?? ?? ?? ?? ? Next? ?? ?? ?? ?? ? If IsDuplicate(TempInt.ToArray) Then Return False? ?? ?? ?? ?Next? ?? ???Next? ?? ???Return True? ? End Function 復制代碼
判斷當前數獨是否符合規則,檢查手機游戲拍賣每一個非空白格的數字的同行、同列、同宮是否重復。
Public Function IsImpossible(ByVal Numbers As Integer?(,)) As Boolean? ?? ???Dim temp As Integer?? ?? ???For i = 0 To GridRank - 1? ?? ?? ?? ?For j = 0 To GridRank - 1? ?? ?? ?? ?? ? If Not Numbers(i, j) = 0 Then? ?? ?? ?? ?? ?? ???temp = Numbers(i, j)? ?? ?? ?? ?? ?? ???Numbers(i, j) = 0? ?? ?? ?? ?? ?? ???If GetExisting(Numbers, i, j, CInt(temp)) Then Numbers(i, j) = temp : Return True? ?? ?? ?? ?? ?? ???Numbers(i, j) = temp? ?? ?? ?? ?? ? End If? ?? ?? ?? ?Next? ?? ???Next? ?? ???Return False? ? End Function 復制代碼
附錄
1)16階(可填數字范圍1~16,宮格4階)
?
2)VB.NET類 & C#類(在線工具轉換,僅供參考)
Public Class SudokuClass? ? Public Property Rank As Integer '數獨的階數? ?? ???Get? ?? ?? ?? ?Return GridRank? ?? ???End Get? ?? ???Set(ByVal value As Integer)? ?? ?? ?? ?GridRank = value? ?? ?? ?? ?SubGridRank = CType(Math.Sqrt(value), Integer)? ?? ?? ?? ?SubGridIncludeRank = SubGridRank? ?? ?? ?? ?DataMaxValue = value? ?? ?? ?? ?DataMinValue = 1? ?? ???End Set? ? End Property? ? Public Property GridData As Integer?(,) '數獨的數據? ? Private GridRank As Integer '數獨的階數? ? Private SubGridRank As Integer '子數獨(宮)的階數? ? Private SubGridIncludeRank As Integer '數獨包含子數獨(宮)的階數? ? Private DataMaxValue As Integer '數獨可填最大數值? ? Private DataMinValue As Integer '數獨可填最小數值? ? ''' <summary>? ? ''' 實例化一個指定階數的數獨類? ? ''' </summary>? ? ''' <param name="nRank">指定的階數</param>? ? Public Sub New(nRank As Integer)? ?? ???Me.Rank = nRank? ? End Sub? ? Public Function GenerateInitialNumbers() As Integer?(,)? ?? ???ReDim GridData(GridRank - 1, GridRank - 1)? ?? ???For i = 0 To GridRank - 1? ?? ?? ?? ?For j = 0 To GridRank - 1? ?? ?? ?? ?? ? GridData(i, j) = 0 '暫無初始數字生成規則,請從數獨文件導入? ?? ?? ?? ?Next? ?? ???Next? ?? ???Return GridData '返回一個空白數獨? ? End Function? ? Public Function IsImpossible(ByVal Numbers As Integer?(,)) As Boolean? ?? ???Dim temp As Integer?? ?? ???For i = 0 To GridRank - 1? ?? ?? ?? ?For j = 0 To GridRank - 1? ?? ?? ?? ?? ? If Not Numbers(i, j) = 0 Then? ?? ?? ?? ?? ?? ???temp = Numbers(i, j)? ?? ?? ?? ?? ?? ???Numbers(i, j) = 0? ?? ?? ?? ?? ?? ???If GetExisting(Numbers, i, j, CInt(temp)) Then Numbers(i, j) = temp : Return True? ?? ?? ?? ?? ?? ???Numbers(i, j) = temp? ?? ?? ?? ?? ? End If? ?? ?? ?? ?Next? ?? ???Next? ?? ???Return False? ? End Function? ? Public Function IsWin(ByVal Numbers As Integer?(,)) As Boolean? ?? ???For i = 0 To GridRank - 1? ?? ?? ?? ?For j = 0 To GridRank - 1? ?? ?? ?? ?? ? If Not Numbers(i, j).HasValue Then Return False '出現空格? ?? ?? ?? ?Next? ?? ???Next? ?? ???Dim TempInt As New List(Of Integer)? ?? ???'判斷行重復? ?? ???For i = 0 To GridRank - 1? ?? ?? ?? ?TempInt.Clear()? ?? ?? ?? ?For j = 0 To GridRank - 1? ?? ?? ?? ?? ? TempInt.Add(CInt(Numbers(i, j)))? ?? ?? ?? ?Next? ?? ?? ?? ?If IsDuplicate(TempInt.ToArray) Then Return False? ?? ???Next? ?? ???'判斷列重復? ?? ???For j = 0 To GridRank - 1? ?? ?? ?? ?TempInt.Clear()? ?? ?? ?? ?For i = 0 To GridRank - 1? ?? ?? ?? ?? ? TempInt.Add(CInt(Numbers(i, j)))? ?? ?? ?? ?Next? ?? ?? ?? ?If IsDuplicate(TempInt.ToArray) Then Return False? ?? ???Next? ?? ???'判斷宮格重復? ?? ???For i = 0 To GridRank - 1 Step SubGridRank? ?? ?? ?? ?For j = 0 To GridRank - 1 Step SubGridRank? ?? ?? ?? ?? ? TempInt.Clear()? ?? ?? ?? ?? ? For i2 = 0 To SubGridRank - 1? ?? ?? ?? ?? ?? ???For j2 = 0 To SubGridRank - 1? ?? ?? ?? ?? ?? ?? ?? ?TempInt.Add(CInt(Numbers(i + i2, j + j2)))? ?? ?? ?? ?? ?? ???Next? ?? ?? ?? ?? ? Next? ?? ?? ?? ?? ? If IsDuplicate(TempInt.ToArray) Then Return False? ?? ?? ?? ?Next? ?? ???Next? ?? ???Return True? ? End Function? ? ''' <summary>? ? ''' 判斷一個序列是否有重復數字? ? ''' </summary>? ? ''' <param name="Numbers"></param>? ? ''' <returns></returns>? ? Private Function IsDuplicate(ByVal Numbers() As Integer) As Boolean? ?? ???Array.Sort(Numbers)? ?? ???If Numbers.Length > 1 Then? ?? ?? ?? ?For i = 0 To Numbers.Length - 2? ?? ?? ?? ?? ? If Numbers(i) = Numbers(i + 1) Then Return True? ?? ?? ?? ?Next? ?? ???End If? ?? ???Return False? ? End Function? ? ''' <summary>? ? ''' 返回指定位置的所有可填數字的序列? ? ''' </summary>? ? ''' <param name="Numbers">原數組</param>? ? ''' <param name="gX">指定的位置的X值,從0開始</param>? ? ''' <param name="gY">指定的位置的Y值,從0開始</param>? ? ''' <returns></returns>? ? Public Function GetEnabledNum(ByVal Numbers As Integer?(,), gX As Integer, gY As Integer) As Integer()? ?? ???Dim NumList As New List(Of Integer)? ?? ???For i = DataMinValue To DataMaxValue? ?? ?? ?? ?If GetExisting(Numbers, gX, gY, i) = False Then NumList.Add(i)? ?? ???Next? ?? ???Return NumList.ToArray? ? End Function? ? '遞歸求解數獨? ? Private Function GetValue(ByVal gData As Integer?(,)) As List(Of Integer?(,))? ?? ???Dim ResultList As New List(Of Integer?(,))? ?? ???Dim i, j As Integer? ?? ???Dim tempPoint As Point = getStartPoint(gData)? ?? ???i = tempPoint.X : j = tempPoint.Y? ?? ???If i >= 0 AndAlso j >= 0 Then? ?? ?? ?? ?For value = DataMinValue To DataMaxValue? ?? ?? ?? ?? ? If GetExisting(gData, i, j, value) = False Then? ?? ?? ?? ?? ?? ???gData(i, j) = value? ?? ?? ?? ?? ?? ???GetValue(gData)? ?? ?? ?? ?? ?? ???gData(i, j) = 0? ?? ?? ?? ?? ? End If? ?? ?? ?? ?Next? ?? ???Else? ?? ?? ?? ?'新增一個結果? ?? ?? ?? ?ResultList.Add(gData)? ?? ???End If? ?? ???Return ResultList? ? End Function? ? '查找當前空白格(最佳格)? ? Private Function getStartPoint(ByRef data As Integer?(,)) As Point? ?? ???Dim gPoint As Point? ?? ???Dim tempValue As Integer? ?? ???Dim maxValue As Integer? ?? ???'查找限制最多的空白格? ?? ???For i = 0 To GridRank - 1? ?? ?? ?? ?For j = 0 To GridRank - 1? ?? ?? ?? ?? ? If data(i, j) = 0 Then? ?? ?? ?? ?? ?? ???tempValue = 0? ?? ?? ?? ?? ?? ???For k = 0 To GridRank - 1? ?? ?? ?? ?? ?? ?? ?? ?If data(i, k) > 0 Then tempValue += 1? ?? ?? ?? ?? ?? ?? ?? ?If data(k, j) > 0 Then tempValue += 1? ?? ?? ?? ?? ?? ?? ?? ?If data((i \ SubGridIncludeRank) * SubGridIncludeRank + k \ SubGridIncludeRank, (j \ SubGridIncludeRank) * SubGridIncludeRank + (k Mod SubGridIncludeRank)) > 0 Then tempValue += 1? ?? ?? ?? ?? ?? ???Next? ?? ?? ?? ?? ?? ???If tempValue > maxValue Then? ?? ?? ?? ?? ?? ?? ?? ?maxValue = tempValue? ?? ?? ?? ?? ?? ?? ?? ?gPoint.X = i? ?? ?? ?? ?? ?? ?? ?? ?gPoint.Y = j? ?? ?? ?? ?? ?? ???End If? ?? ?? ?? ?? ? End If? ?? ?? ?? ?Next? ?? ???Next? ?? ???If maxValue > 0 Then? ?? ?? ?? ?Return gPoint? ?? ???Else? ?? ?? ?? ?gPoint.X = -1? ?? ?? ?? ?gPoint.Y = -1? ?? ?? ?? ?Return gPoint? ?? ???End If? ? End Function? ? '判斷同行同列同宮是否已經存在? ? Private Function GetExisting(ByRef data As Integer?(,), ByVal gX As Integer, ByVal gY As Integer, ByVal gValue As Integer) As Boolean? ?? ???For k = 0 To GridRank - 1? ?? ?? ?? ?If data(gX, k) = gValue OrElse data(k, gY) = gValue OrElse data((gX \ SubGridIncludeRank) * SubGridIncludeRank + k \ SubGridIncludeRank, (gY \ SubGridIncludeRank) * SubGridIncludeRank + (k Mod SubGridIncludeRank)) = gValue Then? ?? ?? ?? ?? ? Return True? ?? ?? ?? ?End If? ?? ???Next? ?? ???Return False? ? End FunctionEnd Class 復制代碼
using Microsoft.VisualBasic;using System;using System.Collections;using System.Collections.Generic;using System.Data;using System.Diagnostics;public class SudokuClass{? ? public int Rank {? ?? ???//數獨的階數? ?? ???get { return GridRank; }? ?? ???set {? ?? ?? ?? ?GridRank = value;? ?? ?? ?? ?SubGridRank = Convert.ToInt32(Math.Sqrt(value));? ?? ?? ?? ?SubGridIncludeRank = SubGridRank;? ?? ?? ?? ?DataMaxValue = value;? ?? ?? ?? ?DataMinValue = 1;? ?? ???}? ? }? ? public int?[,] GridData { get; set; }? ? //數獨的數據? ?? ???//數獨的階數? ? private int GridRank;? ?? ???//子數獨(宮)的階數? ? private int SubGridRank;? ?? ???//數獨包含子數獨(宮)的階數? ? private int SubGridIncludeRank;? ?? ???//數獨可填最大數值? ? private int DataMaxValue;? ?? ???//數獨可填最小數值? ? private int DataMinValue;? ? /// <summary>? ? /// 實例化一個指定階數的數獨類? ? /// </summary>? ? /// <param name="nRank">指定的階數</param>? ? public SudokuClass(int nRank)? ? {? ?? ???this.Rank = nRank;? ? }? ? public int?[,] GenerateInitialNumbers()? ? {? ?? ???GridData = new Nullable<int>[GridRank, GridRank];? ?? ???for (i = 0; i <= GridRank - 1; i++) {? ?? ?? ?? ?for (j = 0; j <= GridRank - 1; j++) {? ?? ?? ?? ?? ? GridData[i, j] = 0;? ?? ?? ?? ?? ? //暫無初始數字生成規則,請從數獨文件導入? ?? ?? ?? ?}? ?? ???}? ?? ???return GridData;? ?? ???//返回一個空白數獨? ? }? ? public bool IsImpossible(int?[,] Numbers)? ? {? ?? ???int? temp = default(int?);? ?? ???for (i = 0; i <= GridRank - 1; i++) {? ?? ?? ?? ?for (j = 0; j <= GridRank - 1; j++) {? ?? ?? ?? ?? ? if (!(Numbers[i, j] == 0)) {? ?? ?? ?? ?? ?? ???temp = Numbers[i, j];? ?? ?? ?? ?? ?? ???Numbers[i, j] = 0;? ?? ?? ?? ?? ?? ???if (GetExisting(ref Numbers, i, j, Convert.ToInt32(temp))){Numbers[i, j] = temp;return true;}? ?? ?? ?? ?? ?? ???Numbers[i, j] = temp;? ?? ?? ?? ?? ? }? ?? ?? ?? ?}? ?? ???}? ?? ???return false;? ? }? ? public bool IsWin(int?[,] Numbers)? ? {? ?? ???for (i = 0; i <= GridRank - 1; i++) {? ?? ?? ?? ?for (j = 0; j <= GridRank - 1; j++) {? ?? ?? ?? ?? ? if (!Numbers[i, j].HasValue)? ?? ?? ?? ?? ?? ???return false;? ?? ?? ?? ?? ? //出現空格? ?? ?? ?? ?}? ?? ???}? ?? ???List<int> TempInt = new List<int>();? ?? ???//判斷行重復? ?? ???for (i = 0; i <= GridRank - 1; i++) {? ?? ?? ?? ?TempInt.Clear();? ?? ?? ?? ?for (j = 0; j <= GridRank - 1; j++) {? ?? ?? ?? ?? ? TempInt.Add(Convert.ToInt32(Numbers[i, j]));? ?? ?? ?? ?}? ?? ?? ?? ?if (IsDuplicate(TempInt.ToArray()))? ?? ?? ?? ?? ? return false;? ?? ???}? ?? ???//判斷列重復? ?? ???for (j = 0; j <= GridRank - 1; j++) {? ?? ?? ?? ?TempInt.Clear();? ?? ?? ?? ?for (i = 0; i <= GridRank - 1; i++) {? ?? ?? ?? ?? ? TempInt.Add(Convert.ToInt32(Numbers[i, j]));? ?? ?? ?? ?}? ?? ?? ?? ?if (IsDuplicate(TempInt.ToArray()))? ?? ?? ?? ?? ? return false;? ?? ???}? ?? ???//判斷宮格重復? ?? ???for (i = 0; i <= GridRank - 1; i += SubGridRank) {? ?? ?? ?? ?for (j = 0; j <= GridRank - 1; j += SubGridRank) {? ?? ?? ?? ?? ? TempInt.Clear();? ?? ?? ?? ?? ? for (i2 = 0; i2 <= SubGridRank - 1; i2++) {? ?? ?? ?? ?? ?? ???for (j2 = 0; j2 <= SubGridRank - 1; j2++) {? ?? ?? ?? ?? ?? ?? ?? ?TempInt.Add(Convert.ToInt32(Numbers[i + i2, j + j2]));? ?? ?? ?? ?? ?? ???}? ?? ?? ?? ?? ? }? ?? ?? ?? ?? ? if (IsDuplicate(TempInt.ToArray()))? ?? ?? ?? ?? ?? ???return false;? ?? ?? ?? ?}? ?? ???}? ?? ???return true;? ? }? ? /// <summary>? ? /// 判斷一個序列是否有重復數字? ? /// </summary>? ? /// <param name="Numbers"></param>? ? /// <returns></returns>? ? private bool IsDuplicate(int[] Numbers)? ? {? ?? ???Array.Sort(Numbers);? ?? ???if (Numbers.Length > 1) {? ?? ?? ?? ?for (i = 0; i <= Numbers.Length - 2; i++) {? ?? ?? ?? ?? ? if (Numbers[i] == Numbers[i + 1])? ?? ?? ?? ?? ?? ???return true;? ?? ?? ?? ?}? ?? ???}? ?? ???return false;? ? }? ? /// <summary>? ? /// 返回指定位置的所有可填數字的序列? ? /// </summary>? ? /// <param name="Numbers">原數組</param>? ? /// <param name="gX">指定的位置的X值,從0開始</param>? ? /// <param name="gY">指定的位置的Y值,從0開始</param>? ? /// <returns></returns>? ? public int[] GetEnabledNum(int?[,] Numbers, int gX, int gY)? ? {? ?? ???List<int> NumList = new List<int>();? ?? ???for (i = DataMinValue; i <= DataMaxValue; i++) {? ?? ?? ?? ?if (GetExisting(ref Numbers, gX, gY, i) == false)? ?? ?? ?? ?? ? NumList.Add(i);? ?? ???}? ?? ???return NumList.ToArray();? ? }? ? //遞歸求解數獨? ? private List<int?[,]> GetValue(int?[,] gData)? ? {? ?? ???List<int?[,]> ResultList = new List<int?[,]>();? ?? ???int i = 0;? ?? ???int j = 0;? ?? ???Point tempPoint = getStartPoint(ref gData);? ?? ???i = tempPoint.X;? ?? ???j = tempPoint.Y;? ?? ???if (i >= 0 && j >= 0) {? ?? ?? ?? ?for (value = DataMinValue; value <= DataMaxValue; value++) {? ?? ?? ?? ?? ? if (GetExisting(ref gData, i, j, value) == false) {? ?? ?? ?? ?? ?? ???gData[i, j] = value;? ?? ?? ?? ?? ?? ???GetValue(gData);? ?? ?? ?? ?? ?? ???gData[i, j] = 0;? ?? ?? ?? ?? ? }? ?? ?? ?? ?}? ?? ???} else {? ?? ?? ?? ?//新增一個結果? ?? ?? ?? ?ResultList.Add(gData);? ?? ???}? ?? ???return ResultList;? ? }? ? //查找當前空白格(最佳格)? ? private Point getStartPoint(ref int?[,] data)? ? {? ?? ???Point gPoint = default(Point);? ?? ???int tempValue = 0;? ?? ???int maxValue = 0;? ?? ???//查找限制最多的空白格? ?? ???for (i = 0; i <= GridRank - 1; i++) {? ?? ?? ?? ?for (j = 0; j <= GridRank - 1; j++) {? ?? ?? ?? ?? ? if (data[i, j] == 0) {? ?? ?? ?? ?? ?? ???tempValue = 0;? ?? ?? ?? ?? ?? ???for (k = 0; k <= GridRank - 1; k++) {? ?? ?? ?? ?? ?? ?? ?? ?if (data[i, k] > 0)? ?? ?? ?? ?? ?? ?? ?? ?? ? tempValue += 1;? ?? ?? ?? ?? ?? ?? ?? ?if (data[k, j] > 0)? ?? ?? ?? ?? ?? ?? ?? ?? ? tempValue += 1;? ?? ?? ?? ?? ?? ?? ?? ?if (data[(i / SubGridIncludeRank) * SubGridIncludeRank + k / SubGridIncludeRank, (j / SubGridIncludeRank) * SubGridIncludeRank + (k % SubGridIncludeRank)] > 0)? ?? ?? ?? ?? ?? ?? ?? ?? ? tempValue += 1;? ?? ?? ?? ?? ?? ???}? ?? ?? ?? ?? ?? ???if (tempValue > maxValue) {? ?? ?? ?? ?? ?? ?? ?? ?maxValue = tempValue;? ?? ?? ?? ?? ?? ?? ?? ?gPoint.X = i;? ?? ?? ?? ?? ?? ?? ?? ?gPoint.Y = j;? ?? ?? ?? ?? ?? ???}? ?? ?? ?? ?? ? }? ?? ?? ?? ?}? ?? ???}? ?? ???if (maxValue > 0) {? ?? ?? ?? ?return gPoint;? ?? ???} else {? ?? ?? ?? ?gPoint.X = -1;? ?? ?? ?? ?gPoint.Y = -1;? ?? ?? ?? ?return gPoint;? ?? ???}? ? }? ? //判斷同行同列同宮是否已經存在? ? private bool GetExisting(ref int?[,] data, int gX, int gY, int gValue)? ? {? ?? ???for (k = 0; k <= GridRank - 1; k++) {? ?? ?? ?? ?if (data[gX, k] == gValue || data[k, gY] == gValue || data[(gX / SubGridIncludeRank) * SubGridIncludeRank + k / SubGridIncludeRank, (gY / SubGridIncludeRank) * SubGridIncludeRank + (k % SubGridIncludeRank)] == gValue) {? ?? ?? ?? ?? ? return true;? ?? ?? ?? ?}? ?? ???}? ?? ???return false;? ? }} 復制代碼
總結
以上是生活随笔為你收集整理的数独游戏求解:解法适用于任意阶数的数独的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。