数独求解器编码

问题描述

我已使用VB在Visual Studio 2010中完成了Sudoku手动求解器。我为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",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

您可以手动添加事件,但是要使其全部自动生成,请在设计器中选择所有控件,打开 Properties 窗口,然后单击 Events 按钮。工具栏,然后双击相应的事件。如果您碰巧以后要添加更多控件,则可以从事件下拉菜单中选择现有方法。

或者,您可以编写没有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