Overview






This is an original Maths and Grammar quiz game. The aim of the game is to climb the board to the end square.

Youtube video - (If the embedded video doesn't appear, use this external link: https://youtu.be/J1RaU9vLXf4) - 



To play, you spin the number spinner by pressing the spin button. Each time you pass over a '?' square, you will be asked a question. There are three possible outcomes...

Possible outcomes



You can Pass

You decline answering the question. If you have remaining moves, you continue to climb the board. If not, you will be asked another question.

You answer correctly

Your remaining moves will be increased, and you continue to climb the board.
Remaining moves * 2 + 1

You answer incorrectly

You lose your remaining moves and you are sent back to the previous question square, or if there isn't a previous question square, you are sent back to the start.





The Grammar Question Form



The Grammar questions along with their multi-choice answers and their correct answers are stored in a My.Resources text file.





Public Class frmGrammar
 
    ''' <summary>
    ''' Used to stop questions being randomly repeated
    ''' </summary>
    ''' <remarks></remarks>
    Private _used As List(Of Integer)
    Public Property indicesUsed() As List(Of Integer)
        Get
            Return _used
        End Get
        Set(ByVal value As List(Of Integer))
            _used = value
        End Set
    End Property
 
    ''' <summary>
    ''' Constructor
    ''' </summary>
    ''' <param name="r"></param>
    ''' <param name="used"></param>
    ''' <remarks>Selects a random question and puts the multi-choice answers in labels</remarks>
    Public Sub New(ByVal r As Random, ByVal used As List(Of Integer))
        InitializeComponent()
        Dim lines() As String = My.Resources.quiz.Split(New String() {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
        If used.Count = lines.Length Then
            used.Clear()
        End If
        Dim i As Integer = r.Next(0, lines.Length)
        While used.Contains(i)
            i = r.Next(0, lines.Length)
        End While
        used.Add(i)
        indicesUsed = used
 
        Dim parts() As String = lines(i).Split(":"c)
        Dim s1 As String = parts(0).Substring(0, parts(0).IndexOf("{"))
        Dim s2 As String = parts(0).Substring(parts(0).IndexOf("}") + 1)
        Dim s3 As String = parts(0).Substring(parts(0).IndexOf("{") + 1, parts(0).IndexOf("}") - parts(0).IndexOf("{") - 1)
        Dim words() As String = s3.Split("|"c)
 
        Label1.Text = s1 & "_____" & s2
        Dim labels() As Label = {Label2, Label3, Label4, Label5}
        For x As Integer = 0 To 3
            If x <= words.GetUpperBound(0) Then
                labels(x).Text = words(x)
            Else
                labels(x).Text = ""
                labels(x).Visible = False
            End If
        Next
 
        Dim w As Integer = Label6.Width + Label7.Width
        For x As Integer = 0 To 3
            If labels(x).Text <> "" Then
                w += labels(x).Width + 6
            End If
        Next
        w -= 6
 
        Dim xp As Integer = (Me.ClientSize.Width - w) \ 2
 
        Label6.Left = xp
        labels(0).Left = Label6.Right
        For x As Integer = 1 To 3
            If labels(x).Text <> "" Then
                labels(x).Left = labels(x - 1).Right + 6
                Label7.Left = labels(x).Right
            End If
        Next
 
 
        correctAnswer = CInt(parts(1))
        'Stop
    End Sub
 
    Private correctAnswer As Integer
    Private selectedAnswer As Integer
 
    ''' <summary>
    ''' btnPass
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>Clicked when user declines question</remarks>
    Private Sub btnPass_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPass.Click
        Me.DialogResult = Windows.Forms.DialogResult.Cancel
    End Sub
 
    ''' <summary>
    ''' btnSolve
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>Form.DialogResult depends on whether the answer is correct</remarks>
    Private Sub btnSolve_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSolve.Click
        If selectedAnswer = correctAnswer Then
            Label8.Text = "✔"
            Label8.Refresh()
            Threading.Thread.Sleep(500)
            Me.DialogResult = Windows.Forms.DialogResult.Yes
        Else
            Label8.Text = "X"
            Label8.Refresh()
            Threading.Thread.Sleep(500)
            Me.DialogResult = Windows.Forms.DialogResult.No
        End If
    End Sub
 
    ''' <summary>
    ''' Labels_Click
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>Onclick the Label forecolor and fontsize changes.
    ''' This resets all of the other labels, so only one appears selected.
    ''' Adjust locations to centre multi-choice Labels in Form</remarks>
    Private Sub Labels_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label5.Click, Label4.Click, Label3.Click, Label2.Click
        Dim labels() As Label = {Label2, Label3, Label4, Label5}
        For x As Integer = 0 To 3
            labels(x).ForeColor = Color.Silver
            labels(x).Font = New Font(labels(x).Font.FontFamily, 10)
            labels(x).Top = 109
        Next
        Dim i As Integer = Array.IndexOf(labels, sender)
        selectedAnswer = i
        labels(i).ForeColor = Color.SteelBlue
        labels(i).Font = New Font(labels(i).Font.FontFamily, 14)
        labels(i).Top = 125 - labels(i).Height + 3
 
        Dim w As Integer = Label6.Width + Label7.Width
        For x As Integer = 0 To 3
            If labels(x).Text <> "" Then
                w += labels(x).Width + 6
            End If
        Next
        w -= 6
 
        Dim xp As Integer = (Me.ClientSize.Width - w) \ 2
 
        Label6.Left = xp
        labels(0).Left = Label6.Right
        For x As Integer = 1 To 3
            If labels(x).Text <> "" Then
                labels(x).Left = labels(x - 1).Right + 6
                Label7.Left = labels(x).Right
            End If
        Next
 
        btnSolve.Enabled = True
    End Sub
End Class



The Maths Question Form




Public Class frmMaths
 
    Private correctAnswer As Integer
 
    Dim x As Integer
 
    Dim dt As New DataTable
    Dim operands(,) As String = {{"+", "-"}, {"/", "*"}}
 
    ''' <summary>
    ''' Constructor
    ''' </summary>
    ''' <param name="r"></param>
    ''' <remarks>Sets up NumericUpDown1.TextChanged
    ''' Formulates a random equation string with a hidden value
    ''' </remarks>
    Public Sub New(ByVal r As Random)
        InitializeComponent()
 
        AddHandler DirectCast(NumericUpDown1.Controls(1), TextBox).TextChanged, AddressOf txtChanged
 
        Dim i1 As Integer = r.Next(2, 11)
        Dim i2 As Integer = r.Next(2, 11)
        Dim i3 As Integer = r.Next(2, 11)
 
        Do While i2 = i1
            i2 = r.Next(1, 11)
        Loop
 
        Do While i3 = i1 Or i3 = i2
            i3 = r.Next(1, 11)
        Loop
 
        Dim s1 As String = operands(0, r.Next(0, 2)) & " " & i1.ToString
        Dim s2 As String = operands(1, r.Next(0, 2)) & " " & i2.ToString
        Dim s3 As String = operands(0, r.Next(0, 2)) & " " & i3.ToString
 
        x = r.Next(1, 101)
        Dim s4 As String = String.Format("((({0} {1}) {2}) {3})", x, s1, s2, s3)
        Do While CDec(dt.Compute(s4, Nothing)) Mod 1 <> 0
            x = r.Next(1, 101)
            s4 = String.Format("((({0} {1}) {2}) {3})", x, s1, s2, s3)
        Loop
 
        Label1.Text = String.Format("x {0} {1} {2}", s1, s2, s3) & " = " & CInt(dt.Compute(s4, Nothing)).ToString
 
        correctAnswer = x
    End Sub
 
    ''' <summary>
    ''' Pass Button
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>Clicked if user declines the question</remarks>
    Private Sub btnPass_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPass.Click
        Me.DialogResult = Windows.Forms.DialogResult.Cancel
    End Sub
 
    ''' <summary>
    ''' Solve Button
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>Form.DialogResult depends on whether the answer is correct</remarks>
    Private Sub btnSolve_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSolve.Click
        If CInt(NumericUpDown1.Value) = correctAnswer Then
            Label8.Text = "✔"
            Label8.Refresh()
            Threading.Thread.Sleep(500)
            Me.DialogResult = Windows.Forms.DialogResult.Yes
        Else
            Label8.Text = "X"
            Label8.Refresh()
            Threading.Thread.Sleep(500)
            Me.DialogResult = Windows.Forms.DialogResult.No
        End If
    End Sub
 
    ''' <summary>
    ''' NumericUpDown1.ValueChanged
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>Enables/disable btnSolve depending if NumericUpDown1.Value > 0D</remarks>
    Private Sub NumericUpDown1_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NumericUpDown1.ValueChanged
        btnSolve.Enabled = NumericUpDown1.Value > 0D
    End Sub
 
    ''' <summary>
    ''' NumericUpDown1.TextChanged
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>Enables/disable btnSolve depending if NumericUpDown1.Value > 0</remarks>
    Private Sub txtChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim tb As TextBox = DirectCast(sender, TextBox)
        btnSolve.Enabled = Val(tb.Text) > 0
    End Sub
 
    ''' <summary>
    ''' Details1.Resize
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>Resizes Form when the dropdown calculator is shown/hidden</remarks>
    Private Sub Details1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Details1.Resize
        Me.Height = 205 + Details1.Height
    End Sub
 
End Class



Conclusion


In VB.Net, a lot can be accomplished, while using only minimal controls, and effective coding. The Game 'board' in the main form of this game uses only one image, two Buttons, a PictureBox, and another (custom) PictureBox which has a circular region. All of the question forms also use minimal resources.


Download


MSDN Code Gallery version...
Download here...

Articles related to game programming



VB.Net - Vertex
VB.Net - WordSearch
VB.Net - MasterMind
VB.Net - OOP BlackJack
VB.Net - Numbers Game
VB.Net - HangMan
Console BlackJack - VB.Net | C#
TicTacToe - VB.Net | C#
OOP Conway's Game of Life - VB.Net | C#
OOP Sudoku - VB.Net | C#
OctoWords VB.Net | C#
OOP Buttons Guessing Game VB.Net | C#
OOP Tangram Shapes Game VB.Net | C#
VB.Net - Three-card Monte
VB.Net - Split Decisions
VB.Net - Pascal's Pyramid
VB.Net - Random Maze Games
(Office) Wordsearch Creator
VB.Net - Event Driven Programming - LockWords Game
C# - Crack the Lock