I want to make a little quiz about me using visual studio. My goal is to have 10 questions and 4 choices each. I've tried to stack buttons and then change 10 labels at different times and it's getting a little complicated... using arrays or/and loops how could i make this more efficient? This is what I have
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.WindowState = FormWindowState.Maximized
Form1.Visible = False
Button2.Visible = False
Button3.Visible = False
Button4.Visible = False
Button5.Visible = False
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If RadioButton4.Checked = True Then
Label3.Text = "1/10"
Label4.Text = "Nice! That was Correct!
Great job!"
Label4.ForeColor = Color.LimeGreen
End If
If Label3.Text = "1/10" Then
Button2.Visible = True
End If
If RadioButton1.Checked = True Or RadioButton2.Checked = True Or RadioButton3.Checked = True Then
Label4.ForeColor = Color.DarkRed
Label4.Text = "Oh no! that was incorrect!
Try Again!"
End If
Button2.Text = "next"
End Sub
Private Sub Button2_click(sender As Object, e As EventArgs) Handles Button2.Click
Label1.Text = "What is Luke Lopez's favorite color?"
RadioButton4.Checked = False
RadioButton1.Text = "Purple"
RadioButton2.Text = "Burgundy"
RadioButton3.Text = "Turqoise"
RadioButton4.Text = "Brown"
If RadioButton1.Checked = True Then
Label3.Text = "2/10"
Label4.Text = "Nice! That was Correct!
Great job!"
Label4.ForeColor = Color.LimeGreen
End If
If Label3.Text = "2/10" Then
Button4.Visible = True
End If
If RadioButton3.Checked = True Or RadioButton2.Checked = True Or RadioButton4.Checked = True Then
Label4.ForeColor = Color.DarkRed
Label4.Text = "Oh no! that was incorrect!
Try Again!"
End If
Button2.Text = "check"
Button4.Text = "next"
If Label3.Text = "2/10" Then
Button3.Text = "next"
Button4.Text = "Check"
End If
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Button3.Visible = False
Label1.Text = "What is Luke Lopez's shoe size?"
RadioButton1.Checked = False
RadioButton1.Text = "7"
RadioButton2.Text = "8.5"
RadioButton3.Text = "7.5"
RadioButton4.Text = "8"
Button3.Visible = False
If RadioButton2.Checked = True Then
Label3.Text = "3/10"
Label4.Text = "Nice! That was Correct!
Great job!"
Label4.ForeColor = Color.LimeGreen
End If
If Label3.Text = "3/10" Then
Button5.Visible = True
Button4.Visible = False
Button3.Visible = False
Button2.Visible = False
Button1.Visible = False
End If
If RadioButton1.Checked = True Or RadioButton4.Checked = True Or RadioButton3.Checked = True Then
Label4.ForeColor = Color.DarkRed
Label4.Text = "Oh no! that was incorrect!
Try Again!"
End If
End Sub
Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
End Sub
It's my first three questions and there are all the buttons and labels and radiobuttons checking and changing every click but I need this to be more efficient because I don't want to waste a lot of time and computer memory on this mini project.
CodePudding user response:
You can save questions, options and answers to a database and then read them to a DataTable, every time you want to show the question, just use a DataRow from the DataTable. That means you don't need to edit questions like:
Use 'Label.TextChanged' event to handle 'Label3.Text':
Private Sub Label3_TextChanged(sender As Object, e As EventArgs) Handles Label3.TextChanged
Select Case Label3.Text
Case "1/10"
Button2.Visible = True
Case "2/10"
Button4.Visible = True
Button3.Text = "next"
Button4.Text = "Check"
Case "3/10"
...
...
End Select
End Sub
Use 'If ... Else ...' statement. For Example:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
'...
If RadioButton1.Checked = True Then
Label3.Text = "2/10"
Label4.Text = "Nice! That was Correct! Great job!"
Label4.ForeColor = Color.LimeGreen
Else
Label4.ForeColor = Color.DarkRed
Label4.Text = "Oh no! that was incorrect! Try Again!"
End If
'If RadioButton3.Checked = True Or RadioButton2.Checked = True Or RadioButton4.Checked = True Then
' Label4.ForeColor = Color.DarkRed
' Label4.Text = "Oh no! that was incorrect! Try Again!"
'End If
'...
End Sub
CodePudding user response:
In comments I talked about storing your data in a text file. This is what my text file looks like. Each record is on a single line and each field is separated by a pipe character |. I chose a pipe because you won't have any of that character in the text of your questions and answers.
1|Largest planet?|Jupiter|Venus|Saturn|Mars|1
2|Smallest planet?|Earth|Uranus|Mercury|Neptune|3
3|Comes closest to Earth?|Mars|Venus|Mercury|Jupiter|2
4|What planet is called the red planet?|Venus|Mars|Saturn|Neptune|2
5|What planet is furthest from Earth?|Saturn|Jupiter|Uranus|Neptune|4
6|How many planets in our solar system?|7|8|9|10|2
7|How many planets between Earth and Sun?|1|2|3|4|2
8|Which planet is said to have rings?|Jupiter|Uranus|Saturn|Neptune|3
You have been working with classes all along because a Form
is a class. Classes can have Properties, methods and Events among other things. Now to the class, QuestionAnswer
. The properties are pretty straight forward. The Sub New
creates a new instance of the class and uses parameters to set all the properties of the class.
In the Form.Load
FillQuestionList
is called. This method uses the File
class in System.IO
(need to add an Imports
for this). ReadAllLines
returns an array of the all the lines in the file. We can loop through these lines and then split each line into fields. The little c
after the "|"
tells compiler that you intend a Char
not a String
. Now we can call the Sub New
of QuestionAnswer
providing all the properties from the parts of the line. This new instance is then added to the QuestionList
so we can use it in the program.
Next, the Load
event calls DisplayQuestion
. This method will also be called from the btnNext
click event. We get the index we want to display from the form level variable CurrentQuestionIndex
. See how handy the class is to set the values we need. Loop through all the radio buttons clearing the Tag
from the last question and clearing the check. The file provided the number of the correct answer. This is stored in the radio button's Tag
property.
When the user clicks btnAnswer
we get which radio button was selected and check the Tag
property to see if the answer was correct. If yes, increment Score
and display the score.
The btnNext.Click
simply checks if we have reached the end of the list before incrementing the index and displaying the next question.
Public Class QuestionGame
Private QuestionList As New List(Of QuestionAnswer)
Private CurrentQuestionIndex As Integer
Private Score As Integer
Private Sub QuestionGame_Load(sender As Object, e As System.EventArgs) Handles MyBase.Load
FillQuestionList()
DisplayQuestion()
End Sub
Private Sub DisplayQuestion()
Dim QA = QuestionList(CurrentQuestionIndex)
lblQuestion.Text = QA.Question
RadioButton1.Text = QA.Answer1
RadioButton2.Text = QA.Answer2
RadioButton3.Text = QA.Answer3
RadioButton4.Text = QA.Answer4
For Each rb In Controls.OfType(Of RadioButton)
rb.Tag = ""
rb.Checked = False
Next
Select Case QA.Correct
Case 1
RadioButton1.Tag = "Correct"
Case 2
RadioButton2.Tag = "Correct"
Case 3
RadioButton3.Tag = "Correct"
Case 4
RadioButton4.Tag = "Correct"
End Select
End Sub
Private Sub FillQuestionList()
Dim lines = File.ReadAllLines("C:\Users\xxxxxxxx\Questions.txt")
For Each line In lines
Dim parts = line.Split("|"c)
QuestionList.Add(New QuestionAnswer(CInt(parts(0)), parts(1), parts(2), parts(3), parts(4), parts(5), CInt(parts(6))))
Next
End Sub
Private Sub btnAnswer_Click(sender As Object, e As EventArgs) Handles btnAnswer.Click
Dim rb = Controls.OfType(Of RadioButton)().FirstOrDefault(Function(r) r.Checked = True)
If rb IsNot Nothing AndAlso rb.Tag.ToString = "Correct" Then
Score = 1
lblScore.Text = Score.ToString
MessageBox.Show("Correct!")
btnAnswer.Enabled = False 'The user can't increase his score by clicking answer several times
Else
MessageBox.Show("Sorry, wrong answer")
End If
btnNext.Enabled = True
End Sub
Private Sub btnNext_Click(sender As Object, e As EventArgs) Handles btnNext.Click
btnNext.Enabled = False 'user can't move to next question until he answers current question
If CurrentQuestionIndex = QuestionList.Count - 1 Then
MessageBox.Show("This is the last question")
Else
CurrentQuestionIndex = 1
DisplayQuestion()
End If
End Sub
End Class
Public Class QuestionAnswer
Public Property QuestionNumber As Integer
Public Property Question As String
Public Property Answer1 As String
Public Property Answer2 As String
Public Property Answer3 As String
Public Property Answer4 As String
Public Property Correct As Integer
Public Sub New(Num As Integer, Ques As String, Ans1 As String, Ans2 As String, Ans3 As String, Ans4 As String, Cor As Integer)
QuestionNumber = Num
Question = Ques
Answer1 = Ans1
Answer2 = Ans2
Answer3 = Ans3
Answer4 = Ans4
Correct = Cor
End Sub
End Class