Full disclosure: This is my last stop. I have already done a fair amount of research on this issue. While I've come across lots of implementations of this project, I've not seen this weird behavior anywhere else.
The project: As one of the projects for my Advanced Visual Basic course, I'm implementing a Concentration game very much like this project: http://www.vb6.us/source-code/full-vb6-game-concentration
The issue: I've got most of the logic working but I'm getting really weird behavior when I flip the cards. The first one flips fine. The second one is *supposed* to flip and hold for a second (I use a Thread.Threading.sleep(1000)) then flip back to covered if they're not a match.
If they match it works as intended.
For some reason, if they don't match it never flips the second card over so that you can see the picture underneath. It evaluates correctly but if the pics don't match, you never get to see the 2nd card.
Secondary issue (not as critical): At lines 67-79 there are some bits of code that are commented out. I'm trying to use a For Each loop to go through all my picture box controls and assign them to the array of structures and then assign the cover image without having to do it one at a time. It would save me about 250 lines of code and help me to still respect myself in the morning. Advice here is welcome as well.
In addition to including my code, I will upload a copy of the entire project folder in case anyone wants to compile it and see the behavior for themselves. Any help is much appreciated!
I tried to comment the bejesus out of my code:
Public Class hard
'declare arrays
Friend pic(19) As pics
Dim picBoxes(35) As picBox
'Declare structures
Friend Structure pics
Dim pictures As Image
Dim used As Integer
Dim pos As Integer
End Structure
Friend Structure picBox
Dim photo As Image
Dim cover As Image
Dim pictureBox As PictureBox
Dim pos As Integer
End Structure
'Declare global variables
Dim clicked As Integer = 0
Dim pb1 As picBox
Dim pb2 As picBox
Dim matches As Integer = 0
Dim attempts As Integer = 0
'Set up Game board
Private Sub hard_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'generate new random seed
Randomize()
'Populate pictures array
pic(0).pictures = My.Resources.ImperialLogo
pic(1).pictures = My.Resources.picard
pic(2).pictures = My.Resources.arwen
pic(3).pictures = My.Resources.chewie
pic(4).pictures = My.Resources.deathStar
pic(5).pictures = My.Resources.enterprise
pic(6).pictures = My.Resources.fett
pic(7).pictures = My.Resources.freeman
pic(8).pictures = My.Resources.gandalf
pic(9).pictures = My.Resources.han
pic(10).pictures = My.Resources.interceptor
pic(11).pictures = My.Resources.kirk
pic(12).pictures = My.Resources.sam
pic(13).pictures = My.Resources.saruman
pic(14).pictures = My.Resources.scotty
pic(15).pictures = My.Resources.starTrek
pic(16).pictures = My.Resources.trooper
pic(17).pictures = My.Resources.wheaton
pic(18).pictures = My.Resources.yoda
'
'BEGIN BOARD INIT
'
'assign PictureBoxes to all 36 elements of the picBoxes array of Structures
'assign ImperialLogo to the cover member of picBoxes array of structures
'Cover member (ImperialLogo) is visible by default
'For Each pictureBox As PictureBox In Me.Controls
' Dim x As Integer = 1
' Dim pbName As String = "PictureBox" + x.ToString
' If TypeOf pictureBox Is PictureBox Then
' With picBoxes(x)
' .pictureBox = pictureBox.Name
' .cover = My.Resources.ImperialLogo
' .pictureBox.Image = .cover
' End With
' End If
' x += 1
'Next
With picBoxes(0)
.pictureBox = PictureBox1
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(1)
.pictureBox = PictureBox2
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(2)
.pictureBox = PictureBox3
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(3)
.pictureBox = PictureBox4
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(4)
.pictureBox = PictureBox5
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(5)
.pictureBox = PictureBox6
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(6)
.pictureBox = PictureBox7
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(7)
.pictureBox = PictureBox8
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(8)
.pictureBox = PictureBox9
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(9)
.pictureBox = PictureBox10
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(10)
.pictureBox = PictureBox11
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(11)
.pictureBox = PictureBox12
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(12)
.pictureBox = PictureBox13
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(13)
.pictureBox = PictureBox14
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(14)
.pictureBox = PictureBox15
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(15)
.pictureBox = PictureBox16
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(16)
.pictureBox = PictureBox17
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(17)
.pictureBox = PictureBox18
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(18)
.pictureBox = PictureBox19
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(19)
.pictureBox = PictureBox20
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(20)
.pictureBox = PictureBox21
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(21)
.pictureBox = PictureBox22
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(22)
.pictureBox = PictureBox23
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(23)
.pictureBox = PictureBox24
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(24)
.pictureBox = PictureBox25
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(25)
.pictureBox = PictureBox26
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(26)
.pictureBox = PictureBox27
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(27)
.pictureBox = PictureBox28
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(28)
.pictureBox = PictureBox29
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(29)
.pictureBox = PictureBox30
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(30)
.pictureBox = PictureBox31
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(31)
.pictureBox = PictureBox32
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(32)
.pictureBox = PictureBox33
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(33)
.pictureBox = PictureBox34
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(34)
.pictureBox = PictureBox35
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
With picBoxes(35)
.pictureBox = PictureBox36
.cover = My.Resources.ImperialLogo
.pictureBox.Image = .cover
End With
'
'END BOARD INIT
'
'intialize counters
Dim i As Integer = 0
Dim j As Integer = 1
'load board with random pics
For i = 0 To 36
Dim rand As Integer
'create randome integer to assign
rand = (Rnd() * 17) + 1
'if pic has already been used twice, systematically check
'each picture's used member in pics
While pic(rand).used >= 2
If pic(j).used >= 2 Then
j = j + 1
Else
rand = j
Exit While
End If
End While
'if the picture has been used fewer than two times,
'then assign it to a random picturebox
'Assign the matching index of the picture from the pics Array to .pos
If pic(rand).used < 2 Then
picBoxes(i).photo = pic(rand).pictures
picBoxes(i).pos = rand
pic(rand).used = pic(rand).used + 1
End If
Next
End Sub
'method to test whether a match has been made
Private Sub testForMatch(ByVal incPb As picBox)
Dim thisPB As picBox
thisPB = incPb
'A turn (or attempt) is two clicks
'On the first click, only increment the clicked field
If clicked < 1 Then
'set incoming PictureBox to temporary object
pb1 = thisPB
pb1.pictureBox.Image = pb1.photo
clicked = clicked + 1
'On the second click, increment clicked again
ElseIf clicked < 2 Then
'set incoming PictureBox to temporary object
pb2 = thisPB
pb2.pictureBox.Image = pb2.photo
clicked = clicked + 1
'log the attempt whether successful or not, display it in the attemptsL.text
attempts = attempts + 1
attemptsL.Text = attempts
'On the second click, compare the integers associated with each photo
If pb1.pos = pb2.pos Then 'If they match...
'Log the match and display it in the matchesL.text
matches = matches + 1
MatchesL.Text = matches
'reset clicked for the next attempt
clicked = 0
'disable the PictureBoxes
pb1.pictureBox.Enabled = False
pb2.pictureBox.Enabled = False
Else 'if they are not a match
'hold for 1 second before switching back
Threading.Thread.Sleep(1000)
'reset clicked
clicked = 0
'reset the cards back to .cover
pb1.pictureBox.Image = pb1.cover
pb2.pictureBox.Image = pb2.cover
End If
End If
End Sub
'Any time the mouse hovers, perform a check to see if the player has won.
Private Sub hard_MouseHover(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseHover
If matches >= 18 Then
MsgBox("YOU WIN!!")
Me.Close()
End If
End Sub
'method to handle click events for the picture boxes
Private Sub PictureBox1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox1.Click, PictureBox2.Click, PictureBox3.Click, PictureBox4.Click, _
PictureBox5.Click, PictureBox6.Click, PictureBox7.Click, PictureBox8.Click, PictureBox9.Click, PictureBox10.Click, PictureBox11.Click, PictureBox12.Click, _
PictureBox13.Click, PictureBox14.Click, PictureBox15.Click, PictureBox16.Click, PictureBox17.Click, PictureBox18.Click, PictureBox19.Click, PictureBox20.Click, _
PictureBox21.Click, PictureBox22.Click, PictureBox23.Click, PictureBox24.Click, PictureBox25.Click, PictureBox26.Click, PictureBox27.Click, PictureBox28.Click, _
PictureBox29.Click, PictureBox30.Click, PictureBox31.Click, PictureBox32.Click, PictureBox33.Click, PictureBox34.Click, PictureBox35.Click, PictureBox36.Click
'When a pictureBox is clicked...
'create a local object to be sent to oneTurn()
Dim thisPicBox As picBox
Dim pbNum As Integer
Dim pbNumString As String
'get the index of the pictureBox clicked
thisPicBox.pictureBox = TryCast(sender, PictureBox)
pbNumString = thisPicBox.pictureBox.Name.Substring(10)
pbNum = Convert.ToInt32(pbNumString) - 1
'set thisPicBox to the picbox clicked
thisPicBox = picBoxes(pbNum)
' 'flip' the card
thisPicBox.pictureBox.Image = thisPicBox.photo
'call oneTurn() to evaluate whether a match has been made
testForMatch(thisPicBox)
End Sub
End Class