Память игры клик события и генератор случайных чисел

Итак, я создаю игру памяти. Это вопрос из 2 частей. Я использую 16 ящиков, и мне нужно иметь цифры 1-8 дважды. Я настроил каждый ящик как структуру, и у меня есть генератор случайных чисел, который случайным образом выбирает число для ящика и затем случайным образом помещает в него число 1 - 8. Проблема, с которой я сталкиваюсь, заключается в следующем. Я получаю повторяющиеся номера для своих ящиков и более 2 раз для цифры, которая будет помещена в это поле, иногда последовательный номер не используется все вместе. Как я могу убедиться, что все 16 блоков создаются без необходимости создавать код для 16 различных экземпляров. Также необходимо убедиться, что каждое однозначное число от 1 до 8 используется и используется только дважды?

Вторая часть моего вопроса - у меня проблема с созданием события щелчка, когда пользователь выбирает поле. Прямо сейчас я не могу понять, как связать, в каком окне пользователь нажимает. Я не хочу писать код для 16 различных блоков, связывать массив с каждым блоком, а затем заполнять каждый блок номером предположения массива. Есть ли способ, которым я могу упростить этот код до чего-то короткого?

Я включил весь код до сих пор.

Option Strict On
Option Explicit On
Option Infer Off

Public Class Form1

    Structure MemoryBox
        Public intBox As Integer
        Public intGuess As Integer
        Public strGuess As String
    End Structure

    Private gameScore() As Integer

    Private memoryGame(15) As MemoryBox

    Dim countLoad As Integer = 0
    Dim countScore As Integer = 0
    Dim intScore As Integer

    Private Sub LoadGame()

        'this is where I am using the random numbers to make each box and populate it with a guess
        Dim randomGen As New Random
        Dim intMemBox As Integer
        Dim intMemGuess As Integer

        intScore = 0


        If countLoad <= 15 Then

            intMemBox = randomGen.Next(1, 16)
            intMemGuess = randomGen.Next(1, 8)

            memoryGame(countLoad).intBox = intMemBox
            memoryGame(countLoad).intGuess = intMemGuess
            memoryGame(countLoad).strGuess = intMemGuess.ToString

            countLoad += 1
        End If

    End Sub

    Private Sub GuessClick()

        'trying to use this area for click event for each box click

        lblMemory1.BackColor = Color.Green
        lblMemory1.Text = memoryGame()

        intScore += 1

        lblScore.Text = intScore.ToString

    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        Call LoadGame()

    End Sub

    Private Sub btnNewGame_Click(sender As Object, e As EventArgs) Handles btnNewGame.Click

        gameScore(countScore) = intScore
        countScore += 1

        Dim outFile As IO.StreamWriter

        outFile = IO.File.AppendText("score.txt")
        outFile.WriteLine(intScore)

        outFile.Close()

        Call LoadGame()

    End Sub

    Private Sub btnHighScore_Click(sender As Object, e As EventArgs) Handles btnHighScore.Click

        Array.Sort(gameScore)
        lblHighScore.Text = gameScore(0).ToString

    End Sub

    Private Sub btnAllScores_Click(sender As Object, e As EventArgs) Handles btnAllScores.Click

        Dim inFile As IO.StreamReader
        Dim strInfo As String

        If IO.File.Exists("score.txt") Then
            inFile = IO.File.OpenText("score.txt")
            Do Until inFile.Peek = -1
                strInfo = inFile.ReadLine
            Loop
            inFile.Close()

        Else
            MessageBox.Show("Can't find the score.txt file", "High Score", MessageBoxButtons.OK, MessageBoxIcon.Information)

        End If

        MessageBox.Show(strInfo, "All Scores", MessageBoxButtons.OK, MessageBoxIcon.Information)

    End Sub
End Class

1 ответ

Решение

Одним из вариантов является заполнение массива нужными числами, а затем случайное перемешивание. Используйте цикл, который выполняется как минимум в один раз больше длины массива, и используйте значение итератора как один индекс и меняйте его случайным образом выбранным индексом.

Что-то вроде этого:

Dim memoryGame(15) As MemoryBox
Dim randomarray() As Integer = {1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8}
Dim rnd As New Random(Now.Millisecond)
For I = 0 To 15
    Dim randindex As Integer = rnd.Next(0, 16)
    Dim temp As Integer = randomarray(I)
    randomarray(I) = randomarray(randindex)
    randomarray(randindex) = temp
Next
For I = 0 To 15
    memoryGame(I).intBox = randomarray(I)
Next

Отсюда просто перебираем массив и присваиваем значения вашим боксам

Для обработки событий клика:

Используйте один и тот же обработчик для каждой коробки. Одним из способов является добавление предложения Handles для каждого поля. С 16 коробками это может стать немного неуклюжим. Я бы предложил в обработчике события загрузки перебирать поля и использовать инструкцию AddHandler, чтобы добавить обработчик в каждое поле. С этой точки зрения sender всегда будет указывать на поле, которое было нажато. Для того, чтобы получить доступ ко всем свойствам коробки, нужно просто передать отправителю любой тип поля.

Если поля представляют собой кнопки (Box1, Box2 и т. Д.), Это будет выглядеть примерно так:

For Each b As Button In Me.Controls.OfType(Of Button).Where(Function(x) x.Name.StartsWith("Box"))
    AddHandler b.Click, AddressOf Button_Click
Next

Private Sub Button_Click(sender As Object, e As EventArgs)
    Dim clickedbutton As Button = DirectCast(sender, Button)
    'access the properties here
End Sub
Другие вопросы по тегам