2016-07-16 32 views
-2

我在VB.NET中編寫了一個Sudoku應用程序。目前我正在開發Sudoku智力發生器的實現。我寫的一個有一個奇怪的問題,應用程序剛剛停頓。起初我只是理性地認爲我的代碼中有一個無限循環。所以我添加了一個功能,如果do ... while循環連續運行超過50次,函數將被重置。但那沒有做任何事情!對於我的生活我不能弄清楚我的程序正在發生什麼。如果有人能解釋這個凍結,我會所以感激不盡。我的程序被困在奇怪的凍結/無限循環中

這裏是我的功能/子/子過程:

Private Sub CreatePuzzle(ByVal Dificulty As Integer) 
    Dim Rand As New Random() 
    For Each Row As List(Of Box) In Rows 
     Dim UsedNumbers As New List(Of Integer) 
     Dim Column As Integer = 0 
     For Each Cell As Box In Row 
      Column = Cell.Column 
      Dim I As Integer 
      Do 
       I = Math.Floor(Rand.NextDouble() * 9) + 1 
      Loop While Arrays.Contains(UsedNumbers.ToArray(), I) Or _ 
         Arrays.Contains(Box.GetValues(Columns(Column)), I) Or _ 
         Arrays.Contains(Box.GetValues(Squares(Math.Floor(Column/3D))), I) 
      Cell.Val(I) 
      UsedNumbers.Add(I) 
      Debug.Print("Row: " & "ABCDEFGHI"(Cell.Row) & ", Column: " & _ 
       (Cell.Column + 1).ToString() & ", Square: " & Cell.Square.ToString() & _ 
       ", (Predicted) Square: " & Math.Floor(Column/3D).ToString()) 
      Debug.Print("I: " & I.ToString()) 
      Debug.Print("") 
     Next 
    Next 
End Sub 

而且,這裏是我用來表示在數獨謎題的細胞自定義Box類的實現:

Public Class Box 
Private _Value As Integer = 0 
Private _Row As Integer 
Private _Column As Integer 
Private _Square As Integer 
Private Label As Label 
Private _Name As String 

Public ReadOnly Property Value As Integer 
    Get 
     Return _Value 
    End Get 
End Property 

Public ReadOnly Property Row As Integer 
    Get 
     Return _Row 
    End Get 
End Property 

Public ReadOnly Property Column As Integer 
    Get 
     Return _Column 
    End Get 
End Property 

Public ReadOnly Property Square As Integer 
    Get 
     Return _Square 
    End Get 
End Property 

Public ReadOnly Property Name As String 
    Get 
     Return Label.Name 
    End Get 
End Property 

Public Sub New(ByRef Box As Label) 
    Dim Values As String() = Box.Tag.ToString.Split(",") 
    If Not Box.Text = "" Then 
     _Value = Integer.Parse(Box.Text) 
    End If 
    _Row = Integer.Parse(Values(0)) 
    _Column = Integer.Parse(Values(1)) 
    _Square = Integer.Parse(Values(2)) 
    Label = Box 
End Sub 

Public Sub Val(ByVal Digit As Char, ByRef PreVal As Integer, ByRef PrevSelect As Label) 
    Dim Value As Integer 
    If Integer.TryParse(Digit, Value) AndAlso Not Value = 0 Then 
     If Label.Text = "" Then 
      PreVal = 0 
     Else 
      PreVal = Integer.Parse(PrevSelect.Text) 
     End If 
     PrevSelect = Label 
     Label.Text = Digit 
     _Value = Value 
    End If 
End Sub 

Public Sub Val(ByVal Digit As Integer) 
    If Digit = 0 Then 
     Label.Text = "" 
    Else 
     Label.Text = Digit.ToString() 
    End If 
    _Value = Digit 
End Sub 

Public Shared Function GetValues(ByVal Boxes As List(Of Box)) As Integer() 
    Dim Output(Boxes.Count - 1) As Integer 
    For I As Integer = 0 To Output.GetUpperBound(0) 
     Output(I) = Boxes(I).Value 
    Next 
    Return Output 
End Function 
End Class 

編輯:這裏是陣列的代碼.Contains()

Function Contains(ByVal HayStack() As Integer, ByVal Needle As Integer) As Boolean 
    For I As Integer = 0 To HayStack.GetUpperBound(0) 
     If HayStack(I) = Needle Then 
      Return True 
     End If 
    Next 
    Return False 
End Function 

Please writ writ如果有任何您需要查看的自定義實現,請參閱此處。

+0

哪個是無限循環?你有沒有調試過,看看你的代碼無限循環? –

+0

@Josh部分Do ... while CreatePuzzle循環() –

+0

我的問題有什麼問題嗎?如果有人向我解釋爲什麼他們低估了這個問題,我會很樂意解決這個問題。 –

回答

0

好的......所以事實證明,這不是一個無限循環,而是一種效率低下的算法,需要10分鐘來創建這個難題。

+0

看到我的答案的一些想法。 – dbasnett

0

我在創建一個數獨謎題的粗略嘗試。使用這個類。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
    Dim foo As New Puzzle() 
    RichTextBox1.Text = foo.Display 
    RichTextBox1.Refresh() 
End Sub 

Public Class Puzzle 
    Private Shared PRNG As New Random 
    Private _thePuzzle As New List(Of List(Of Integer)) 
    Public thePuzzle As New List(Of List(Of Integer)) 

    Private base As List(Of Integer) = Enumerable.Range(1, 9).OrderBy(Function(x) PRNG.Next).ToList 
    Public Sub New(Optional empties As Integer = 27) 
     'creat base puzzle 
     For x As Integer = 0 To 2 'first three rows 
      Me._thePuzzle.Add(New List(Of Integer)) 
      Me.thePuzzle.Add(New List(Of Integer)) 
      Me._thePuzzle(x).AddRange(base) 
      'blocks of three from front to rear 
      base.AddRange(base.GetRange(0, 3)) 
      base.RemoveRange(0, 3) 
     Next 

     'DebugHelp(Me._thePuzzle) 

     For x As Integer = 0 To 5 'next six rows 
      base.Clear() 
      base.AddRange(Me._thePuzzle(x)) 
      base.Add(base(0)) 
      base.RemoveAt(0) 
      Me._thePuzzle.Add(New List(Of Integer)) 
      Me.thePuzzle.Add(New List(Of Integer)) 
      Me._thePuzzle(Me._thePuzzle.Count - 1).AddRange(base) 
     Next 

     'DebugHelp(Me._thePuzzle) 

     '' shuffle 
     Const shuffles As Integer = 3 

     For sh As Integer = 1 To shuffles 
      Me.Shuffle() 
     Next 

     'visible 
     For r As Integer = 0 To Me._thePuzzle.Count - 1 
      Me.thePuzzle(r).AddRange(Me._thePuzzle(r)) 
     Next 

     DebugHelp(Me.thePuzzle) 
     'set certain entries to zero 
     Dim idxs As List(Of Integer) = Enumerable.Range(0, 81).ToList 
     For x As Integer = 1 To empties 
      Dim rmx As Integer = PRNG.Next(idxs.Count) 
      Dim idx As Integer = idxs(rmx) 
      idxs.RemoveAt(rmx) 
      Dim r As Integer 
      Dim c As Integer 
      r = Math.DivRem(idx, 9, c) 
      Me.thePuzzle(r)(c) = 0 
      Threading.Thread.Sleep(0) 
     Next 

     ' DebugHelp(Me.thePuzzle) 
    End Sub 

    Public Function Display() As String 
     Dim rv As New System.Text.StringBuilder 
     Dim fmt As String = "{0,3}" 
     For r As Integer = 0 To 8 
      For c As Integer = 0 To 8 
       If Me.thePuzzle(r)(c) = 0 Then 
        rv.AppendFormat(fmt, "□") 
       Else 
        rv.AppendFormat(fmt, Me.thePuzzle(r)(c)) 
       End If 
       If c Mod 3 = 2 AndAlso c <> 8 Then rv.AppendFormat(fmt, "|") 
      Next 
      rv.AppendLine() 
      If r Mod 3 = 2 AndAlso r <> 8 Then 
       rv.AppendLine("---------------------------------") 
       'rv.AppendLine("_________________________________") 
      End If 
     Next 
     Return rv.ToString 
    End Function 

    Private Sub Shuffle() 
     Dim temp As Integer 
     Dim agrp As Integer 
     Dim IDT As Integer 
     Dim IDF As Integer 

     agrp = PRNG.Next(Me._thePuzzle.Count \ 3) * 3 
     Do 
      IDT = PRNG.Next(3) + agrp 
      IDF = PRNG.Next(3) + agrp 
     Loop While IDT = IDF 

     'swap rows 
     base.Clear() 
     base.AddRange(Me._thePuzzle(IDT)) 
     Me._thePuzzle(IDT).Clear() 
     Me._thePuzzle(IDT).AddRange(Me._thePuzzle(IDF)) 
     Me._thePuzzle(IDF).Clear() 
     Me._thePuzzle(IDF).AddRange(base) 

     'swap columns 
     For rw As Integer = 0 To Me._thePuzzle.Count - 1 
      temp = Me._thePuzzle(rw)(IDF) 
      Me._thePuzzle(rw)(IDF) = Me._thePuzzle(rw)(IDT) 
      Me._thePuzzle(rw)(IDT) = temp 
     Next 
    End Sub 

    Private Sub DebugHelp(sl As List(Of List(Of Integer))) 
     Debug.WriteLine("") 
     For r As Integer = 0 To sl.Count - 1 
      Debug.Write("'") 
      For c As Integer = 0 To sl(r).Count - 1 
       Debug.Write(sl(r)(c) & " ") 
      Next 
      Debug.WriteLine("") 
     Next 
    End Sub 
End Class