日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2024/8/26 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数独游戏求解:解法适用于任意阶数的数独 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


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 Sub
  • End 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 Function
  • End 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;
  • ? ? }
  • }
  • 復制代碼

    總結

    以上是生活随笔為你收集整理的数独游戏求解:解法适用于任意阶数的数独的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。