数独求解器编码

Sudoku solver coding

我在 Visual Studio 2010 年使用 VB 完成了数独手动求解器。我为 9x9 数独所需的 81 个盒子创建了 81 个标签。我想知道如何在没有 81 个标签点击事件的情况下点击任何标签和 运行 代码。现在我通过鼠标按下事件完成了此操作,该事件不灵活并且需要 enabled.false 模式下的标签仅用于获取坐标 X 和 Y。

Public Class Form1
    Dim sudnumfilflag As String
    Dim row(9), col(9), box(9) As String
    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        row(1) = "010203040506070809" : row(2) = "101112131415161718" : row(3) = "192021222324252627" : row(4) = "282930313233343536"
        row(5) = "373839404142434445" : row(6) = "464748495051525354" : row(7) = "555657585960616263" : row(8) = "646566676869707172"
        row(9) = "737475767778798081"

        col(1) = "011019283746556473" : col(2) = "021120293847566574" : col(3) = "031221303948576675" : col(4) = "041322314049586776"
        col(5) = "051423324150596877" : col(6) = "061524334251606978" : col(7) = "071625344352617079" : col(8) = "081726354453627180"
        col(9) = "091827364554637281"

        box(1) = "010203101112192021" : box(2) = "040506131415222324" : box(3) = "070809161718252627" : box(4) = "282930373839464748"
        box(5) = "313233404142495051" : box(6) = "343536434445525354" : box(7) = "555657646566737475" : box(8) = "585960676869767778"
        box(9) = "616263707172798081"

        Dim k, k1, k2 As Integer
        sudnumfilflag = "1"
        k = 1
        For k1 = 0 To 8
            For k2 = 0 To 8
                Me.Controls("Label" & k.ToString).Location = New Point(k2 * 46, k1 * 46)
                If k1 < 3 And k2 < 3 Then Me.Controls("Label" & k.ToString).BackColor = Color.LightGray
                If k1 > 5 And k2 > 5 Then Me.Controls("Label" & k.ToString).BackColor = Color.LightGray
                If k1 > 5 And k2 < 3 Then Me.Controls("Label" & k.ToString).BackColor = Color.LightGray
                If k1 < 3 And k2 > 5 Then Me.Controls("Label" & k.ToString).BackColor = Color.LightGray
                If k1 > 2 And k1 < 6 Then
                    If k2 > 2 And k2 < 6 Then Me.Controls("Label" & k.ToString).BackColor = Color.LightGray
                End If
                k = k + 1
            Next
        Next
        For k = 1 To 81
            Me.Controls("Label" & k.ToString).Font = New Font("Courier New", 8, FontStyle.Bold)
            Me.Controls("Label" & k.ToString).ForeColor = Color.BlueViolet
            Me.Controls("Label" & k.ToString).Text = "1 2 3 4 5 6 7 8 9"
            Me.Controls("Label" & k.ToString).Enabled = False
        Next
        RadioButton1.Text = "ENTER PUZZLE"
        RadioButton2.Text = "SOLVE PUZZLE"
    End Sub
    Private Sub RadioButton1_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles RadioButton1.CheckedChanged
        sudnumfilflag = "1"
    End Sub
    Private Sub RadioButton2_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles RadioButton2.CheckedChanged
        sudnumfilflag = "0"
    End Sub
    Private Sub Form1_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        Dim k3, k4, r, c, b As String
        Dim clue, clue1, cclue, cclue1, bclue, bclue1 As String

        clue = "" : cclue = "" : cclue1 = ""
        clue1 = "" : bclue = "" : bclue1 = ""

        k3 = 1 : k4 = 1 : r = 1 : c = 1 : b = 1

        k4 = InputBox("Enter a number between 1 and 9")
        If IsNumeric(k4) = True And k4.Length < 2 Then
            k3 = (1 + e.X \ 46) + ((1 + e.Y \ 46) - 1) * 9
            Me.Controls("Label" & k3.ToString).Enabled = True
            Me.Controls("Label" & k3.ToString).Font = New Font("Courier New", 24, FontStyle.Bold)
            If sudnumfilflag = "1" Then Me.Controls("Label" & k3.ToString).ForeColor = Color.Red
            If sudnumfilflag = "0" Then Me.Controls("Label" & k3.ToString).ForeColor = Color.Black
            Me.Controls("Label" & k3.ToString).Text = k4
        End If
        'Me.Controls("Label" & k3.ToString).Enabled = False
        '-- finding row, column and box
        For k = 1 To 9
            For k1 = 0 To 16 Step 2
                If Val(k3) = Val(row(k).Substring(k1, 2)) Then r = k
                If Val(k3) = Val(col(k).Substring(k1, 2)) Then c = k
                If Val(k3) = Val(box(k).Substring(k1, 2)) Then b = k
            Next
        Next
        '---
        For k = 0 To 16 Step 2
            If (Me.Controls("Label" & (Val(row(r).Substring(k, 2))).ToString).Text).Length > 1 Then
                '---
                clue = (Me.Controls("Label" & (Val(row(r).Substring(k, 2))).ToString).Text)
                clue1 = (Me.Controls("Label" & (Val(row(r).Substring(k, 2))).ToString).Text)
                For kk = 0 To (Me.Controls("Label" & (Val(row(r).Substring(k, 2))).ToString).Text).Length - 1
                    If clue.Substring(kk, 1) = k4 Then clue1 = clue.Substring(0, kk) & "*" & clue.Substring(kk + 1, clue.Length - kk - 1)
                Next
                '---
                Me.Controls("Label" & (Val(row(r).Substring(k, 2))).ToString).Text = clue1
            End If

            If (Me.Controls("Label" & (Val(col(c).Substring(k, 2))).ToString).Text).Length > 1 Then
                '---
                cclue = (Me.Controls("Label" & (Val(col(c).Substring(k, 2))).ToString).Text)
                cclue1 = (Me.Controls("Label" & (Val(col(c).Substring(k, 2))).ToString).Text)
                For kk = 0 To (Me.Controls("Label" & (Val(col(c).Substring(k, 2))).ToString).Text).Length - 1
                    If cclue.Substring(kk, 1) = k4 Then cclue1 = cclue.Substring(0, kk) & "*" & cclue.Substring(kk + 1, cclue.Length - kk - 1)
                Next
                '---
                Me.Controls("Label" & (Val(col(c).Substring(k, 2))).ToString).Text = cclue1
            End If

            If (Me.Controls("Label" & (Val(box(b).Substring(k, 2))).ToString).Text).Length > 1 Then
                '---
                bclue = (Me.Controls("Label" & (Val(box(b).Substring(k, 2))).ToString).Text)
                bclue1 = (Me.Controls("Label" & (Val(box(b).Substring(k, 2))).ToString).Text)
                For kk = 0 To (Me.Controls("Label" & (Val(box(b).Substring(k, 2))).ToString).Text).Length - 1
                    If bclue.Substring(kk, 1) = k4 Then bclue1 = bclue.Substring(0, kk) & "*" & bclue.Substring(kk + 1, bclue.Length - kk - 1)
                Next
                '---
                Me.Controls("Label" & (Val(box(b).Substring(k, 2))).ToString).Text = bclue1
            End If
        Next
    End Sub

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        For k = 1 To 81
            Me.Controls("Label" & k.ToString).Enabled = True
            Me.Controls("Label" & k.ToString).Font = New Font("Courier New", 8, FontStyle.Bold)
            Me.Controls("Label" & k.ToString).ForeColor = Color.Red
            Me.Controls("Label" & k.ToString).Text = "1 2 3 4 5 6 7 8 9"
            Me.Controls("Label" & k.ToString).Enabled = False
        Next
    End Sub
End Class

您可以通过在 Handles 子句中包含每个事件来使用一个方法处理多个事件,例如

Private Sub Labels_Click(sender As Object, e As EventArgs) Handles Label1.Click,
                                                                   Label2.Click,
                                                                   Label3.Click
    'Get the Label that was clicked.
    Dim lbl = DirectCast(sender, Label)

    '...
End Sub

您可以手动添加事件,但是要让它们全部自动生成,select 设计器中的所有控件,打开 Properties window , 单击工具栏上的 事件 按钮,然后单击 double-click 相应的事件。如果您以后碰巧添加了更多控件,您可以 select 来自 drop-down 事件的现有方法。

或者,您可以编写没有 Handes 子句的事件处理程序:

Private Sub Labels_Click(sender As Object, e As EventArgs)
    'Get the Label that was clicked.
    Dim lbl = DirectCast(sender, Label)

    '...
End Sub

然后在代码中附加所有事件处理程序,例如

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Form1.Load
    For Each lbl In Controls.OfType(Of Label)()
        AddHandler lbl.Click, AddressOf Labels_Click
    Next
End Sub