Share via


VB.Net - Perspective

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) - View

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...

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
VB.Net - Totris