Question Loop Thru Functions

inkedgfx

Well-known member
Joined
Sep 29, 2012
Messages
139
Location
USA
Programming Experience
Beginner
I am writting a Trivia Game.....there will be 12 catagories , each catagory will have at least 100 question.....I will create 10 different functions for each catagory to randomly pick a question from a list of 10 questions.....is it poosible to loop thru the 10 functions and randomly select a function to run when the user clicks the next buttoon?

Thank You for your help

InkedGFX
 
Socarsky...
where did you find all those videos?

I could really use a resource like that.

InkedGFX

There are lost of sources on youtube and othere web pages, just need to choose and download as you wish. I download a few more today to try later, topic was Crystal Report.
 
Hi,

As to your latest questions:-

1) Yes, you should be creating a class which does nothing more that hold the properties which contain the question and possible answers for each question. i.e:-

VB.NET:
Private Class QuizQuestion
  Public Property Question As String
  Public Property AvailableAnswers As New List(Of String)
  Public Property CorrectAnswer As Integer
End Class

2) Yes, all other objects are created within the Form class as either Variables, Subroutines or Events of the Form class.

3) To populate labels and radio buttons etc, we now need to expand upon what we have previously posted in the Quiz project. So somewhere you will need to put a button, for example, on the form along with your labels and radio buttons to ask a random question in the Button.Click event. i.e:-

VB.NET:
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
  'generate a random quiz question as demonstrated and explain in
  'my previous example in the Quiz Project
  Dim myRand As New Random
  Dim myCurrentCategory As QuizCategories = DirectCast(myRand.Next(0, TotalCategories), QuizCategories)
  If myQuestions(myCurrentCategory).Count > 0 Then
    Dim myRandomQuestionIndex As Integer = myRand.Next(0, myQuestions(myCurrentCategory).Count)
    myCurrentQuestion = DirectCast(myQuestions(myCurrentCategory).Item(myRandomQuestionIndex), QuizQuestion)
 
    'We can now use the myCurrenQuestion variable to access the properties of the
    'question to populate labels and radio buttons
    With myCurrentQuestion
      Label1.Text = .Question
      RadioButton1.Text = .AvailableAnswers.Item(0)
      RadioButton1.Tag = 0
      RadioButton2.Text = .AvailableAnswers.Item(1)
      RadioButton2.Tag = 1
      RadioButton3.Text = .AvailableAnswers.Item(2)
      RadioButton3.Tag = 2
    End With
    'now we delete the used question so that it is not used again
    myQuestions(myCurrentCategory).RemoveAt(myRandomQuestionIndex)
  End If
End Sub

We also now need to change the scope of the variable myCurrentQuestion so that this can be accessed by other routines and events in the project. Firstly, CHANGE all occurrences of

VB.NET:
Dim myCurrentQuestion As QuizQuestion =

to

VB.NET:
myCurrentQuestion =

Then at the class level add the following variable declaration:-

VB.NET:
Private myCurrentQuestion As QuizQuestion

You can see that when the button is pressed to ask a question we populate labels and radio buttons with the properties of the Question and possible answers. An important thing to note is that when we set the Radio button text we also set the Tag property of the radio button to the index in the list that relates to the question being displayed. We do this to that we can check in the next section of code whether the correct answer was chosen.

So now we need to wait for the user to click on the answer of their choice. Once they do we can handle the RadioButton.CheckChanged event and do whatever we need to. See the code below which does just that:-

VB.NET:
Private Sub RadioButton1_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles RadioButton1.CheckedChanged, RadioButton2.CheckedChanged, RadioButton3.CheckedChanged
  'notice that we handle all three radio buttons in the same routine here 
  'by adding each radio button to the Handles clause above
  'Next we Cast the sender object to Type Radio button so that
  'we have access to all the properties of the RadioButton control
  Dim CheckRadioButton As RadioButton = DirectCast(sender, RadioButton)
  'we then make sure the button is checked before we test the question
  If CheckRadioButton.Checked Then
    'we then check the contents of the Tag property of the RadioButton
    'to see if it matches the myCurrentQuestion.CurrectAnswer property
    'it it matches that, the answer is correct otherwise its incorrect
    If myCurrentQuestion.CorrectAnswer = Convert.ToInt32(CheckRadioButton.Tag) Then
      MsgBox("You Guessed Correctly!")
    Else
      MsgBox("You Got it Wrong!")
    End If
    'here we display the correct answer in another label for completeness
    Label2.Text = myCurrentQuestion.AvailableAnswers.Item(myCurrentQuestion.CorrectAnswer)
  End If
End Sub

As you can see there is plenty for you to get your head round again so take your time and fully follow the code through as best you can to see how it all works.

Hope that helps.

Cheers,

Ian
 
very cool...I appreciate the help....I will study this after work today.....with your help I will get my head around this....

InkedGFX
 
adding Imports System.Linq doesnt fix the "tolist" problem

I put the questions in the QuizQuestions class with the catagories enum...is this where the questions and catagory enum needs to be?

InkedGFX
 
it seems I am doing something wrong with the class QuizQuestions......whenever I add the Public sub CreateMyQuizQuestions() to the QuizQuestions class the code doesnt work , as I get an error saying the key was not found in the dictionary...but if I add the sub to the form and change the public to private ...everthing works as expected......

not sure why this would be...

InkedGFX
 
Hi,

I think I might have just uncovered why you are getting the ToList issue. After looking on the Net there seems to be a lot of references to the fact the .ToList method was introduced in VS2008. So the first question for you is what version of Visual Studio are you using? If you are using a version earlier than 2008 then replace the subroutine AddQuestionToDictionary with this one:-

VB.NET:
Private Sub AddQuestionToDictionary(ByVal SelectedCatagory As QuizCategories, ByVal NewQuizQuestion As QuizQuestion)
  If myQuestions.ContainsKey(SelectedCatagory) Then
    myQuestions(SelectedCatagory).Add(NewQuizQuestion)
  Else
    Dim myNewQuestionCategorylist As New List(Of QuizQuestion)
    myNewQuestionCategorylist.Add(NewQuizQuestion)
    myQuestions.Add(SelectedCatagory, myNewQuestionCategorylist)
  End If
End Sub

In this example you can see I have removed the .ToList method and physically created a new List for each new Quiz Category.

If you are using 2008 or above, then I also found references to the fact that in the .NET 3.5 Framework you need to add the System.Linq namespace to be able to access the ToList method? So try adding "Imports System.Linq" to the class. Guessing and hoping a bit really on that last bit.

Please let us know if that solves this particular issue with the .ToList method.

Cheers,

Ian

Yes ..this does solve the tolist problem..... thank you

InkedGFX
 
Hi,

Good to hear about the ToList issue.

With regards to your current problem you are not following what I have posted. I have already mentioned what should be in the QuizQuestion class, so if you deviate from this then you are going to get issues. You need to learn more about subroutines and how and where they are called. From what I can tell from your comments you are putting the CreateMyQuizQuestions subroutine in the QuizQuestion class but what you have to remember is that CreateMyQuizQuestions subroutine uses the QuizQuestion class to build the questions so you cannot put this in the QuizQuestion class.

Cheers,

Ian
 
Hi,

Good to hear about the ToList issue.

With regards to your current problem you are not following what I have posted. I have already mentioned what should be in the QuizQuestion class, so if you deviate from this then you are going to get issues. You need to learn more about subroutines and how and where they are called. From what I can tell from your comments you are putting the CreateMyQuizQuestions subroutine in the QuizQuestion class but what you have to remember is that CreateMyQuizQuestions subroutine uses the QuizQuestion class to build the questions so you cannot put this in the QuizQuestion class.

Cheers,

Ian

yes , that's exactly what I was doing....I thought about it for awhile and read the example you posted...I read it over and over until I thought to move the Sub to the form class.....which solved the issue and the program is working as expected.....now Im not sure if I am doing this correctly or not...but this is working , just not sure if this would be the correct way to do it...

Private Sub CreateGeneralKnowledgeQuestions()
        Dim myQuizQuestion1 As New QuizQuestion
        With myQuizQuestion1
            .Question = "What is the surname of the Hungarian inventor whose multicolored, rotatable cube became a world cult?"
            .AvailableAnswers.Add("Chacofski")
            .AvailableAnswers.Add("Rubik")
            .AvailableAnswers.Add("Rollins")
            .CorrectAnswer = 1
        End With
        AddQuestionToDictionary(TriviaCatagories.GeneralKnowledge, myQuizQuestion1)
        Dim myQuizQuestion2 As New QuizQuestion
        With myQuizQuestion2
            .Question = "How long is the appointed term of office of the secretary general of the United Nations?"
            .AvailableAnswers.Add("12 Years")
            .AvailableAnswers.Add("5 Years")
            .AvailableAnswers.Add("2 Years")
            .CorrectAnswer = 1
        End With
        AddQuestionToDictionary(TriviaCatagories.GeneralKnowledge, myQuizQuestion2)
        Dim myQuizQuestion3 As New QuizQuestion
        With myQuizQuestion3
            .Question = "What is the term for a person with assets of over 1,000 million dollars?"
            .AvailableAnswers.Add("Billionaire")
            .AvailableAnswers.Add("Millionaire")
            .AvailableAnswers.Add("Zillionaire")
            .CorrectAnswer = 0
        End With
        AddQuestionToDictionary(TriviaCatagories.GeneralKnowledge, myQuizQuestion3)
        Dim myQuizQuestion4 As New QuizQuestion
        With myQuizQuestion4
            .Question = "Carlo Collodi wrote a story about a wooden puppet which became human. What is its title?"
            .AvailableAnswers.Add("Dumbo")
            .AvailableAnswers.Add("Chuckie")
            .AvailableAnswers.Add("Pinocchio")
            .CorrectAnswer = 2
        End With
        AddQuestionToDictionary(TriviaCatagories.GeneralKnowledge, myQuizQuestion4)
        Dim myQuizQuestion5 As New QuizQuestion
        With myQuizQuestion5
            .Question = "What is the acronym for the agency set up in 1923 to provide co-operation between police forces worldwide?"
            .AvailableAnswers.Add("Interpol")
            .AvailableAnswers.Add("United Nations")
            .AvailableAnswers.Add("FBI")
            .CorrectAnswer = 0
        End With
        AddQuestionToDictionary(TriviaCatagories.GeneralKnowledge, myQuizQuestion5)
End Sub


now as the list gets longer I just dim a new myQuizQuestion as New QuizQuestion and add the new question.... is this correct?

InkedGFX
 
Hi,

Yep, that's it. See, you are getting there. As mentioned before, just take your time, and everything will become clear in the end.

For now, and to get your quiz working, just keep doing what you are doing for the questions, but as you have already guessed your code is going to get massive with all the questions that you are about to add.

So, FOR THE FUTURE, and just to add some other stuff to the mix, you may want to think about putting your questions in a file or a database which can then be read into your project at runtime, thereby reducing your code. As said though, one for the future, but this is how you would do it correctly.

Hope that helps.

Cheers,

Ian
 
Thank You Very much for your help...I couldn't have gotten this far with out it.....

InkedGFX
 
Haaaaaa!

I think something clicked today...I finally think I understand the basic structure of OOP and classes in VB.NET

I create a PUBLIC class that can be called anywhere in the program...but inside the class I dim private variables and functions and subs so those variables and subs or functions can only be used inside the class it is created in......then I create a new object of the class to use it somewhere else in the program.......is this correct?

InkedGFX
 
Hi,

Yes, that's it. Just remember that if you declare something Private within the class, i.e property / variable / function / subroutine, then these can only be used by other routines within the same class and are NOT visible to the outside world when you declare an instance of the class. If you want something to be visible to the outside world when an instance of the class is declared then you must declare these properties / variables / functions / subroutines as Public.

There are other Keywords used is classes to declare objects but Private and Public are the basic ones to get your head round to begin with.

Hope that helps.

Cheers,

Ian
 
Hi,

Yes, that's it. Just remember that if you declare something Private within the class, i.e property / variable / function / subroutine, then these can only be used by other routines within the same class and are NOT visible to the outside world when you declare an instance of the class. If you want something to be visible to the outside world when an instance of the class is declared then you must declare these properties / variables / functions / subroutines as Public.

There are other Keywords used is classes to declare objects but Private and Public are the basic ones to get your head round to begin with.

Hope that helps.

Cheers,

Ian

I'm seeing how massive the VB.NET namespace is , this is going to take awhile

InkedGFX
 
Back
Top