Память игры клик события и генератор случайных чисел
Итак, я создаю игру памяти. Это вопрос из 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