Creating a Visual Basic Hangman Game

Introduction

One of my all-time favourite games has to be Hangman. It wins loose-hands… Pardon the pun. As many of you may know, I am not the biggest gamer—not like Hangman can be classified as a gamer's game, but still, it takes a lot for me to actually sit down and play a game. I suppose time is a big factor.

Today, you will learn how to create a basic Hangman game with Visual Basic.

For the uninformed…

Hangman

Hangman is a guessing game usually played with pencil and paper by two or more players. One player thinks of a word, phrase, or sentence and the other tries to guess the correct word, phrase, or sentence by suggesting letters, within a certain number of guesses.

The word, phrase, or sentence to guess is usually represented by a row of dashes, each representing a letter of the phrase. If the guessing player suggests a letter that occurs in the word, the other player should write the letter in all its correct positions. If the suggested letter or number does not occur in the word, the other player should draw one element of a hanged man stick figure as a tally mark.

Our Project

Start Visual Studio and create a new Visual Basic Windows Forms project.

Design

Design your form so that resembles Figure 1. You can name all your objects whatever you like, but keep in mind that my object names may differ from yours.

Our Design
Figure 1: Our Design

Code

Declare the following variables:

   Dim arrTerms() As String = {"Mercedes", "Audi", _
      "BMW", "Mazda", "Volkswagen"}

   Dim rndRandom As New Random

   Dim btnLetters() As Button

   Dim lstEnteredLetters As New List(Of Label)

   Dim blnSkip As Boolean

   Dim intStage As Integer = 0

arrTerms is an array that hosts the terms that will have to be guessed during the game. There could obviously be more arrays and more terms, but this article is only a quick introduction on how to create a hangman game with Visual Basic.

rndRandom is a Random object that will assist in picking an item from the preceding array. btnLetters is a dynamic button and will aid in giving the existing buttons a consolidated event handler. lstEnteredLetters is a List of label objects. Whatever letter gets chosen by the user will have to be displayed.

blnSkip allows you to skip an already selected letter. intStage indicates the game's progress and, depending on the Stage the game is in, the hangman will be drawn at that level.

Add the Form_Load event:

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

      Me.DoubleBuffered = True

      btnLetters = Me.Controls.OfType(Of Button).Except(New Button() _
         {btnNew}).ToArray

      Array.ForEach(btnLetters, Sub(b) AddHandler b.Click, _
         AddressOf btn_click)

      Reset()

   End Sub

Setting the DoubleBuffered property of any control reduces the flickering that gets caused by progressive redrawing of parts of a displayed surface. btnLetters contains all the alphabetic buttons, and then an event handler gets added that handles the Click events for each of the buttons. Lastly, a Sub named Reset is called, which we will add later.

Add the btn_Click event to handle all the click events from the alphabetic buttons:

   Private Sub btn_click(sender As Object, e As EventArgs)

      If blnSkip Then

         Return

      End If

      Dim btnTemp As Button = DirectCast(sender, Button)

      btnTemp.Enabled = False

      Array.ForEach(lstEnteredLetters.ToArray, Sub(lbl) lbl.Text = _
         If(lbl.Tag.ToString = btnTemp.Text, btnTemp.Text, lbl.Text))

      For x As Integer = 1 To lstEnteredLetters.Count - 1

         lstEnteredLetters(x).Left = lstEnteredLetters(x - 1).Right

      Next

      If lstEnteredLetters(lstEnteredLetters.Count - 1).Right > _
            Me.ClientSize.Width - 14 Then

         Me.SetClientSizeCore(lstEnteredLetters(lstEnteredLetters.Count _
            - 1).Right + 14, 381)

      End If

      intStage += If(Not lstEnteredLetters.Any(Function(lbl) lbl.Text = _
         btnTemp.Text), 1, 0)

      blnSkip = lstEnteredLetters.All(Function(lbl) lbl.Text <> _
         " ") OrElse intStage = 10

      Me.Invalidate()

   End Sub

If a letter has already been selected, nothing must happen. In other words: The button must be skipped. Once a button has been pressed, the item gets added to the lstEnteredLetters list. After the selected button's text has been added to the lstEnteredLetters list, the letter gets displayed on the dynamically created label, and the width of the Letters' display area gets dynamically adjusted to compensate for the width of the entered letter.

Add the Reset sub:

   Private Sub Reset()

      SetClientSizeCore(403, 486)

      Dim strTerm As String = arrTerms(rndRandom.Next(0, _
         arrTerms.Length)).ToUpper

      Array.ForEach(Me.Controls.OfType(Of Label).ToArray, _
         Sub(lbl) lbl.Dispose())

      Array.ForEach(btnLetters, Sub(b) b.Enabled = True)

      lstEnteredLetters = New List(Of Label)

      Dim intX As Integer = 14

      For Each c As Char In strTerm

         Dim lblTemp As New Label

         lblTemp.Text = " "
         lblTemp.Font = New Font(Me.Font.Name, 18, _
            FontStyle.Underline)
         lblTemp.Location = New Point(intX, 250)

         lblTemp.Tag = c.ToString
         lblTemp.AutoSize = True

         Controls.Add(lblTemp)
         lstEnteredLetters.Add(lblTemp)
         intX = lblTemp.Right

      Next

      blnSkip = False

      intStage = 0

      Me.Invalidate()

   End Sub

The Reset sub simply returns all the variables to their default values and disposes the event handlers created during execution of the program. Also, it creates and formats the labels according the text inside the Terms array.

Add the following code for the 'New' button that restarts the game by calling Reset:

   Private Sub Button1_Click(sender As Object, e As EventArgs) _
         Handles btnNew.Click

      Reset()

   End Sub

Add the last part of code, which is the Form's Paint event:

   Private Sub Form1_Paint(ByVal sender As Object, ByVal e As _
      System.Windows.Forms.PaintEventArgs) Handles Me.Paint

      If intStage >= 1 Then

         e.Graphics.DrawLine(New Pen(Color.Black, 2), 85, 190, 210, 190)

      End If

      If intStage >= 2 Then

         e.Graphics.DrawLine(New Pen(Color.Black, 2), 150, 190, 150, 50)

      End If

      If intStage >= 3 Then

         e.Graphics.DrawLine(New Pen(Color.Black, 2), 150, 50, 198, 50)

      End If

      If intStage >= 4 Then

         e.Graphics.DrawLine(New Pen(Color.Black, 2), 198, 50, 198, 70)

      End If

      If intStage >= 5 Then

         e.Graphics.DrawEllipse(New Pen(Color.Blue, 2), _
            New Rectangle(188, 70, 20, 20))

      End If

      If intStage >= 6 Then

         e.Graphics.DrawLine(New Pen(Color.Blue, 2), 198, 90, 198, 130)

      End If

      If intStage >= 7 Then

         e.Graphics.DrawLine(New Pen(Color.Blue, 2), 198, 95, 183, 115)

      End If

      If intStage >= 8 Then

         e.Graphics.DrawLine(New Pen(Color.Blue, 2), 198, 95, 213, 115)

      End If

      If intStage >= 9 Then

         e.Graphics.DrawLine(New Pen(Color.Blue, 2), 198, 130, 183, 170)

      End If

      If intStage >= 10 Then

         e.Graphics.DrawLine(New Pen(Color.Blue, 2), 198, 130, 213, 170)

      End If

   End Sub

Depending on the number of guesses, the progress of the game is shown in the form of drawn objects that create the gallows and the man and his limbs. Because the Form keeps repainting itself, you have to ensure that the previously drawn stages are continuously shown.

Our game in action:

Game Play
Figure 2: Game Play

Conclusion

Making games improves your logic tremendously. Although there was not much coding involved, there was still some complicated logic. I hope you have enjoyed today's article.



About the Author

Hannes DuPreez

Hannes du Preez is a Microsoft MVP for Visual Basic for the ninth consecutive year. He loves technology and loves Visual Basic. He loves writing articles and proving that Visual Basic is more powerful than what most believe. His ultimate dream is to write a Visual Basic book, hopefully one day that dream will come true. You are most welcome to reach him at: ojdupreez1978@gmail.com

Related Articles

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date