Я уже разместил ответ, где я сосредоточился на алгоритме. Код алгоритма был непосредственно интегрирован в форму. Это работает, но не является хорошей практикой. Код был бы более пригодным для повторного использования, более понятным и мог бы быть более легко протестирован, если бы он был извлечен в отдельный класс.
Public Class RandomTextRevealer
Private _indexes As Integer()
Private _currentIndex As Integer
Private _chars As Char()
Private _template As String
Private _result As String
Public Sub New(ByVal templateText As String)
Dim rnd = New Random()
_template = templateText
' Create indexes that are randomly sorted
_indexes = Enumerable _
.Range(0, _template.Length) _
.OrderBy(Function(i) rnd.Next()) _
.ToArray()
'Create an array of chars with stars '****'.
_chars = HiddenText.ToCharArray()
_currentIndex = 0
End Sub
Public Function RevealNext() As String
If _currentIndex < _template.Length Then
Dim index As Integer = _indexes(_currentIndex)
_currentIndex += 1
_chars(index) = _template(index)
_result = New String(_chars)
End If
Return _result
End Function
Public ReadOnly Property HiddenText() As String
Get
Return New String("*"c, _template.Length)
End Get
End Property
End Class
Мы можем протестировать класс таким образом в небольшом консольном приложении без формы:
Module Programm
Public Sub Main()
Dim revealer = New RandomTextRevealer("Just a test")
Console.WriteLine(revealer.HiddenText)
For i As Integer = 1 To 12
Console.WriteLine(revealer.RevealNext())
Next
Console.ReadKey()
End Sub
End Module
Теперь мы можем интегрировать его в такую форму (я добавил кнопку сброса, чтобы можно было повторить тест с разными случайными значениями):
Public Class Form2
Dim revealer As RandomTextRevealer
Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Reset()
End Sub
Private Sub btnReveal_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReveal.Click
Label1.Text = revealer.RevealNext()
End Sub
Private Sub btnReset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReset.Click
Reset()
End Sub
Private Sub Reset()
revealer = New RandomTextRevealer("ABCD")
Label1.Text = revealer.HiddenText
End Sub
End Class
Теперь наш код формы выглядит намного чище.