Question Logic Errors in Hangman Game

TomAwesome

New member
Joined
Jul 16, 2013
Messages
2
Programming Experience
Beginner
So... it's the inevitable Hangman Game question that every new programmer must tackle :)
I'm just stuck and going in circles. I think I need an extra set of trained eyes to help me out.
I know my code is not so eloquent to look at, but I have only been studying vb.net for about 5 weeks.
My hangman game seems to be working fine, until I start a new game, then everything goes a little funky.
I've stepped through my code over and over and just don't see the logic error. Would anyone be willing to take a look and find problems?
I am using button controls for the alphabet and declaring a win or lose by whether the pieces of my hangman are all visible (lose) or all of my answer labels are visible (win). Like I said, the code works flawlessly on first iteration, but after a new game is started, words and labels and such don't match up. Sometimes the game says I won when I press any alphabet button, or (even if I know the word) the labels will not show up correctly and it counts as an incorrect guess. Anyways, here's the code I've been working with. I hope you find it is long, but commented well.
Imports System.IO

Public Class HangmanForm
    ' Declare constants
    Private Const HINT_String As String = " Letter Word"
    Private Const YOU_WIN_String As String = "You win!"

    ' Declare variables
    Private score_Decimal As Decimal
    Private numOfGuessesInteger As Integer
    Private randomNumberInteger As Integer
    Private wordListStreamReader As StreamReader
    Private generateRandom As Random = New Random(DateTime.Now.Millisecond)
    Private newWordString As String
    Private newWordLengthInteger As Integer
    Private indexInteger As Integer = 0
    Private answerLabel As Label
    Private guessString As String
    Private guessControlVar As Integer = 0

    ' Delcare counters and accumulators
    Private numOfGamesPlayedInteger As Integer = 0
    Private numOfGamesWonInteger As Integer = 0
    Private numOfWordsAvailableInteger As Integer = 0

    Private Sub NewGameToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NewGameToolStripMenuItem.Click, newGameButton.Click
        EnableAllButtons() ' Enables all buttons
        ClearLabels() ' Makes answer labels invisible
        ResetHangman() ' Makes hangman invisible
        ' Generate random number for word selection
        randomNumberInteger = generateRandom.Next(0, numOfWordsAvailableInteger - 1)
        ' Select a word
        wordsComboBox.SelectedIndex = randomNumberInteger
        newWordString = wordsComboBox.SelectedItem.ToString
        ' Show hint to player
        newWordLengthInteger = newWordString.Length
        hintTextBox.Text = newWordLengthInteger.ToString & HINT_String
        ' Fill letter labels with new word
        Dim newWordLetters(newWordLengthInteger - 1) As String
        For x As Integer = 0 To newWordLengthInteger - 1
            newWordLetters(x) = newWordString.Substring(x, 1) ' Initialize array with characters from new word
        Next x
        For Each Me.answerLabel In Me.answerGroupBox.Controls
            If indexInteger < newWordLengthInteger Then
                Me.answerLabel.Text = newWordLetters(indexInteger)
                indexInteger += 1
            Else
                Me.answerLabel.Text = ""
            End If
        Next
        ' Hide answer labels with no letter assigned
        For Each Me.answerLabel In Me.answerGroupBox.Controls
            If answerLabel.Text = "" Then
                answerLabel.Visible = True
            Else
                answerLabel.Visible = False
            End If
        Next
    End Sub

    Private Sub labelCheck()
        guessControlVar = 0 ' Resets control variable for incorrect guess
        ' This subroutine checks whether a guess is correct
        For Each Me.answerLabel In Me.answerGroupBox.Controls
            If guessString = Me.answerLabel.Text.ToUpper Then
                ' Correct guess by player
                Me.answerLabel.Visible = True
                guessControlVar += 1
            End If
        Next
        ' Check to see if all labels are visible (game won)
        If Label1.Visible And Label2.Visible And Label3.Visible And Label4.Visible And Label5.Visible And Label6.Visible And Label7.Visible And Label8.Visible And Label9.Visible And Label10.Visible And Label11.Visible And Label12.Visible And Label13.Visible And Label14.Visible Then
            ' Disable all alphabet buttons
            DisableAllButtons()
            ' Display wining message to player
            MessageBox.Show(YOU_WIN_String)
            ' Increment game and score counters
            numOfGamesPlayedInteger += 1
            numOfGamesWonInteger += 1
            ' Show score to player
            scoreButton.PerformClick()
        End If
        If guessControlVar = 0 Then ' Show a piece of the hangman
            If nooseShape.Visible = False Then
                nooseShape.Visible = True
            ElseIf headShape.Visible = False Then
                headShape.Visible = True
            ElseIf bodyShape.Visible = False Then
                bodyShape.Visible = True
            ElseIf leftArmShape.Visible = False Then
                leftArmShape.Visible = True
            ElseIf rightArmShape.Visible = False Then
                rightArmShape.Visible = True
            ElseIf leftLegShape.Visible = False Then
                leftLegShape.Visible = True
            ElseIf rightLegShape.Visible = False Then
                rightLegShape.Visible = True
            End If
        End If
        If nooseShape.Visible And headShape.Visible And bodyShape.Visible And leftArmShape.Visible And rightArmShape.Visible And leftLegShape.Visible And rightLegShape.Visible Then
            ' Display losing message to player
            MessageBox.Show("You're hung!")
            ' Increment games played
            numOfGamesPlayedInteger += 1
            ' Disable alphabet buttons
            DisableAllButtons()
            ' Display score to user
            scoreButton.PerformClick()
        End If
    End Sub
    Private Sub DisableAllButtons()
        ' Disables all the alphabet buttons
        aButton.Enabled = False
        bButton.Enabled = False
        cButton.Enabled = False
        dButton.Enabled = False
        eButton.Enabled = False
        fButton.Enabled = False
        gButton.Enabled = False
        hButton.Enabled = False
        iButton.Enabled = False
        jButton.Enabled = False
        kButton.Enabled = False
        lButton.Enabled = False
        mButton.Enabled = False
        nButton.Enabled = False
        oButton.Enabled = False
        pButton.Enabled = False
        qButton.Enabled = False
        rButton.Enabled = False
        sButton.Enabled = False
        tButton.Enabled = False
        uButton.Enabled = False
        vButton.Enabled = False
        wButton.Enabled = False
        xButton.Enabled = False
        yButton.Enabled = False
        zButton.Enabled = False
    End Sub
    Private Sub EnableAllButtons()
        ' Enables all the alphabet buttons
        aButton.Enabled = True
        bButton.Enabled = True
        cButton.Enabled = True
        dButton.Enabled = True
        eButton.Enabled = True
        fButton.Enabled = True
        gButton.Enabled = True
        hButton.Enabled = True
        iButton.Enabled = True
        jButton.Enabled = True
        kButton.Enabled = True
        lButton.Enabled = True
        mButton.Enabled = True
        nButton.Enabled = True
        oButton.Enabled = True
        pButton.Enabled = True
        qButton.Enabled = True
        rButton.Enabled = True
        sButton.Enabled = True
        tButton.Enabled = True
        uButton.Enabled = True
        vButton.Enabled = True
        wButton.Enabled = True
        xButton.Enabled = True
        yButton.Enabled = True
        zButton.Enabled = True
    End Sub
    Private Sub ClearLabels()
        For Each Me.answerLabel In Me.answerGroupBox.Controls
            answerLabel.Visible = False
        Next
    End Sub
    Private Sub ResetHangman()
        ' Makes all parts of hangman invisible
        nooseShape.Visible = False
        headShape.Visible = False
        leftArmShape.Visible = False
        rightArmShape.Visible = False
        bodyShape.Visible = False
        rightLegShape.Visible = False
        leftLegShape.Visible = False
    End Sub

    Private Sub ButtonClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles aButton.Click, bButton.Click, cButton.Click,
        dButton.Click, eButton.Click, fButton.Click, gButton.Click, hButton.Click, iButton.Click, jButton.Click, kButton.Click, lButton.Click,
        mButton.Click, nButton.Click, oButton.Click, pButton.Click, qButton.Click, rButton.Click, sButton.Click, tButton.Click, uButton.Click,
        vButton.Click, wButton.Click, xButton.Click, yButton.Click, zButton.Click
        ' Handles any button click with select case structure
        Select Case DirectCast(sender, Button).Name
            ' Select a case depending on the name of the case and process 
            ' the commands under the selected case as an event.
            Case "aButton"
                aButton.Enabled = False ' Disables button after it has been pressed
                guessString = "A" ' Sets guessString to letter
                labelCheck() ' Calls labelCheck()
            Case "bButton"
                bButton.Enabled = False
                guessString = "B"
                labelCheck()
            Case "cButton"
                cButton.Enabled = False
                guessString = "C"
                labelCheck()
            Case "dButton"
                dButton.Enabled = False
                guessString = "D"
                labelCheck()
            Case "eButton"
                eButton.Enabled = False
                guessString = "E"
                labelCheck()
            Case "fButton"
                fButton.Enabled = False
                guessString = "F"
                labelCheck()
            Case "gButton"
                gButton.Enabled = False
                guessString = "G"
                labelCheck()
            Case "hButton"
                hButton.Enabled = False
                guessString = "H"
                labelCheck()
            Case "iButton"
                iButton.Enabled = False
                guessString = "I"
                labelCheck()
            Case "jButton"
                jButton.Enabled = False
                guessString = "J"
                labelCheck()
            Case "kButton"
                kButton.Enabled = False
                guessString = "K"
                labelCheck()
            Case "lButton"
                lButton.Enabled = False
                guessString = "L"
                labelCheck()
            Case "mButton"
                mButton.Enabled = False
                guessString = "M"
                labelCheck()
            Case "nButton"
                nButton.Enabled = False
                guessString = "N"
                labelCheck()
            Case "oButton"
                oButton.Enabled = False
                guessString = "O"
                labelCheck()
            Case "pButton"
                pButton.Enabled = False
                guessString = "P"
                labelCheck()
            Case "qButton"
                qButton.Enabled = False
                guessString = "Q"
                labelCheck()
            Case "rButton"
                rButton.Enabled = False
                guessString = "R"
                labelCheck()
            Case "sButton"
                sButton.Enabled = False
                guessString = "S"
                labelCheck()
            Case "tButton"
                tButton.Enabled = False
                guessString = "T"
                labelCheck()
            Case "uButton"
                uButton.Enabled = False
                guessString = "U"
                labelCheck()
            Case "vButton"
                vButton.Enabled = False
                guessString = "V"
                labelCheck()
            Case "wButton"
                wButton.Enabled = False
                guessString = "W"
                labelCheck()
            Case "xButton"
                xButton.Enabled = False
                guessString = "X"
                labelCheck()
            Case "yButton"
                yButton.Enabled = False
                guessString = "Y"
                labelCheck()
            Case "zButton"
                zButton.Enabled = False
                guessString = "Z"
                labelCheck()
        End Select

    End Sub

    Private Sub ScoreToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ScoreToolStripMenuItem.Click, scoreButton.Click
        Try
            ' Calculate score_Decimal as games won divided by total games played
            score_Decimal = (numOfGamesWonInteger \ numOfGamesPlayedInteger) * 100
            ' Display score to player
            MessageBox.Show("Games Played: " & numOfGamesPlayedInteger & Environment.NewLine &
                            "Games Won: " & numOfGamesWonInteger & Environment.NewLine &
                            "Score Percentage: " & score_Decimal & "%")
        Catch
            MessageBox.Show("No score yet!")
        End Try
    End Sub

    Private Sub HangmanForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' Open word list file
        wordListStreamReader = New StreamReader("WordList.txt")

        While wordListStreamReader.Peek <> -1
            wordsComboBox.Items.Add(wordListStreamReader.ReadLine()) ' Adds words to hidden list
            numOfWordsAvailableInteger += 1
        End While

        ' Close file
        wordListStreamReader.Close()
        newGameButton.PerformClick()
    End Sub
End Class
 
Last edited by a moderator:
Okay, found the mistake this morning. Sometimes it just takes a fresh new day to sharpen my eye.
I never rest the value of indexInteger to zero, which was making my answerLabels incorrect.
I also found a problem in my score calculations and decided it was easier to format score_Decimal.ToString("P") when displaying the score to the player/user.
 
Back
Top