When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
Related Web Technologies
User Tips!
Coding Tips

Book Reviews
Sample Chapters
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Stump the SQL Guru!
Web Hosts
Author an Article

Print this Page!
Published: Wednesday, December 11, 2002

Hangman in ASP.NET, Part 2

By Scott Mitchell

  • Read Part 1

  • In Part 1 we examined the code needed to choose a secret word and to start the game. In this second and final part, we'll look at the functions and subroutines needed to handle the event that is raised when the user guesses a letter, and the algorithm needed to determine whether a user has won or lost the game based on their letter selection.

    - continued -

    Guessing a Letter

    The player guesses a letter by clicking one of the lettered hyperlinks. For example, to guess the letter "E", the player would simply click the "E" hyperlink. The "A" through "Z" hyperlinks are created a LinkButton controls. When the LinkButton control is clicked, two events fire: the Click event and the Command event. The Click event merely signals that the button was clicked, but the Command event can be used to pass up additional information. Specifically, the LinkButton class contains a CommandArgument property, that can be used to uniquely identify a series of LinkButtons who all call the same Command event handler.

    In our hangman user interface, there are 26 LinkButton controls, each of which has specified that when their Command event fires, the LetterGuessed event handler should be executed. These 26 LinkButton controls are differentiated by their ID and CommandArgument properties, which equal the letter represented by the particular LinkButton.

    The LetterGuessed event handler, whose code is shown below, performs two high-level tasks. First, it disables the LinkButton that triggered the event, since in hangman a user cannot guess the same letter multiple times. Next, it determines if the letter guessed appears in the secret word or not, and handles the two possible cases. To disable the currently selected LinkButton control, it finds the control using the FindControl method, and then sets its Enabled property to False. This has the effect of turning the hyperlink into plain text. It also sets the clicked LinkButton's ForeColor property to red. This is accomplished via the following code:

    Sub LetterGuessed(sender as Object, e as CommandEventArgs)
      'First, make the letter selected disabled
      Dim clickedButton as LinkButton = FindControl(e.CommandArgument)
      clickedButton.Enabled = False
      clickedButton.ForeColor = Color.Red

    Note that we can determine the letter corresponding to the clicked LinkButton by examining the e.CommandArgument property.

    Next, we need to determine if the letter selected by the user was in the secret word. We can accomplish this via the following conditional:

      'Now, determine if the letter is in the word 
      '(the below two lines should be on one line of code!)
      If Session("hangman_word").ToString().ToLower().
              IndexOf(e.CommandArgument.ToLower()) >= 0 then
        'The letter was found
        'The letter was not found, increment the # of wrong guesses
      End If
    End Sub

    Note that the ToLower() method is used on both the hangman_word session variable and with the e.CommandArgument. This is because the IndexOf() method is case sensitive, so we make both lowercase so as to not have a match not appear due to case differences. Now, if the letter is found we want to update the current_word session variable with the selected letter. If it was not found, we want to update the number of wrong guesses and display a new hangman image.

    For both cases we need to check if the game has ended. If the player guessed a correct letter, the game may have ended if all of the letters have been filled in; if the player guessed an incorrect letter, the game may have ended if it was the player's sixth incorrect guess. The below code is the code from the previous code snippet, but with the If ... then and Else portions filled in.

      'Now, determine if the letter is in the word 
      '(the below two lines should be on one line of code!)
      If Session("hangman_word").ToString().ToLower().
              IndexOf(e.CommandArgument.ToLower()) >= 0 then
        'The letter was found
        Dim i as Integer
        Dim current as String = String.Empty
        For i = 0 to Session("hangman_word").ToString().Length - 1
          If Session("hangman_word").ToString().Substring(i,1).ToLower() = _
                           e.CommandArgument.ToLower() then
            current &= Session("hangman_word").ToString().Substring(i,1)
            current &= Session("current_word").ToString().Substring(i,1)
          End If
        Next i
        Session("current_word") = current
        'See if they have guessed the word correctly!
        If Session("hangman_word").ToString() = _
              Session("current_word").ToString() then
        End If
        'The letter was not found, increment the # of wrong guesses
        Session("wrong_guesses") = _
             Convert.ToInt32(Session("wrong_guesses")) + 1
        'Update the hangman image
        hangmanImage.ImageUrl = "/images/hang_" & _
                 Session("wrong_guesses").ToString() & ".gif"
        If Convert.ToInt32(Session("wrong_guesses")) >= 6 then
          'Eep, the person has lost
        End If  
      End If
    End Sub

    If the game has ended the EndGame() subroutine is called, passing in a Boolean value indicating whether the player has won (True) or lost (False). This subroutine, which can be seen below, simply displays an appropriate message and provides a link to allow the user to play again. Note that the link to play again simply redirects the user to the current page. However, since the page will not have been visited on a postback, the ResetGame() subroutine will be called (since the Page_Load event handler is setup to call ResetGame() when Page.IsPostBack is False, as shown below).

    Sub EndGame(won as Boolean)
      If won then
        lblEndGameMessage.Text = "Congratulations!  You won!"
        lblEndGameMessage.Text = "Sorry, you lost.  The correct " & _
           "word was: " & Session("hangman_word").ToString().ToUpper() 
        lblEndGameMessage.ForeColor = Color.Red
      End If
      lblEndGameMessage.Text &= "<p><a href=""hangman.aspx"">Play Again!</a>"
    End Sub
    Sub Page_Load(sender as Object, e as EventArgs)
      If Not Page.IsPostBack then
      End If
    End Sub
    [View a Live Demo!]


    This wraps up the hangman example! Hopefully you found this article to be lighthearted and fun. If it caught your fancy there are a number of enhancements you can add. First, I think such an "application" would be well-suited to be wrapped up in a User Control. By encapsulating the functionality in a User Control, you could drop the hangman game on any Web page simply by using a standard ASP.NET Web control tag. (To learn more about User Controls be sure to read: Building an ASP.NET User Control.)

    Another enhancement would to be to allow words with spaces. Currently the simple algorithm employed in this demo does not work for words with spaces. Additionally, it would be nice to allow the user to guess the word if they know it instead of having to select all of the letters. That is, imagine that it's a long word, and the user knows what the answer is. Currently, the only way to win is to click on the remaining letters for the words, one letter at a time. It would be nice to allow the user to type in the answer in a TextBox. Once you allowed for spaces and for guessing the word/phrase, I would imagine it wouldn't be much more difficult to extend the code to create a Wheel of Fortune type game.

    Happy Programming!

  • By Scott Mitchell

  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article