How can I get my code to stop in Visual Basic? - arrays

I am creating a game where the player answers a question and then if they answer correctly, then they get to flip two cards over to see if they match (bit like pairs game). However, I am struggling to figure out how I can stop the input box (how the user enters their answer), if the player gets the question right, from appearing for a period of time until the player has selected two cards.
I am using two arrays, one for holding the questions and the other for holding the answers. P.s. Excuse the last few questions, trying to get it to work before I finish them all.
Private Sub Questions()
strQuestions(0) = "A common noun refers to the name of things."
strQuestions(1) = "A pronoun is a word that takes the place of nouns."
strQuestions(2) = "'She' is a pronoun that would replace a woman's name."
strQuestions(3) = "The days of the week are proper nouns."
strQuestions(4) = "'He', 'She' and 'them' are all pronouns."
strQuestions(5) = "Spain is a proper noun."
strQuestions(6) = "Proper nouns always start with a capital letter."
strQuestions(7) = "The place 'England' is referred to as a proper noun."
strQuestions(8) = "A 'camera' is a common noun."
strQuestions(9) = "FE"
strQuestions(10) = "GR"
strAnswers(0) = "TRUE"
strAnswers(1) = "TRUE"
strAnswers(2) = "TRUE"
strAnswers(3) = "TRUE"
strAnswers(4) = "TRUE"
strAnswers(5) = "TRUE"
strAnswers(6) = "TRUE"
strAnswers(7) = "TRUE"
strAnswers(8) = "TRUE"
strAnswers(9) = "TRUE"
strAnswers(10) = "TRUE"
Dim userAnswer As String
For i = 0 To UBound(strQuestions)
userAnswer = InputBox(strQuestions(i))
If userAnswer <> strAnswers(i) Then
MsgBox("Incorrect. Try again.")
Else
MsgBox("Correct! Make your move.")
WHAT GOES HERE?
End If
Next i
End Sub
Private Sub label_click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles Label9.Click, Label8.Click, Label7.Click, Label6.Click, Label5.Click,
Label4.Click, Label3.Click, Label2.Click, Label16.Click, Label15.Click, Label14.Click, Label13.Click, Label12.Click,
Label11.Click, Label10.Click, Label1.Click
' The timer is only on after two non-matching
' icons have been shown to the player,
' so ignore any clicks if the timer is running
If Timer1.Enabled Then Exit Sub
Dim clickedLabel = TryCast(sender, Label)
If clickedLabel IsNot Nothing Then
End If
' If the clicked label is black, the player clicked
' an icon that's already been revealed --
' ignore the click
If clickedLabel.ForeColor = Color.Black Then Exit Sub
' If firstClicked is Nothing, this is the first icon
' in the pair that the player clicked,
' so set firstClicked to the label that the player
' clicked, change its color to black, and return
If firstClicked Is Nothing Then
firstClicked = clickedLabel
firstClicked.ForeColor = Color.Black
Exit Sub
End If
' If the player gets this far, the timer isn't
' running and firstClicked isn't Nothing,
' so this must be the second icon the player clicked
' Set its color to black
secondClicked = clickedLabel
secondClicked.ForeColor = Color.Black
CheckForWinner()
' If the player clicked two matching icons, keep them
' black and reset firstClicked and secondClicked
' so the player can click another icon
If firstClicked.Text = secondClicked.Text Then
firstClicked = Nothing
secondClicked = Nothing
Questions()
Exit Sub
End If
' If the player gets this far, the player
' clicked two different icons, so start the
' timer (which will wait three quarters of
' a second, and then hide the icons)
Timer1.Start()
Questions()
Exit Sub

You need to restructure your program so that the part where the questions are asked is not in a loop. Instead consider using a sub which asks for the next answer. If the correct answer is given, the sub exits and the application waits for the user to pick a card.
Once the cards are selected, you call the ask a question sub again. The position through the list of questions is stored as a variable in the form. Each time the ask a question sub is executed, it checks if the end of the list has been reached and if so ends the game.
Something like this (although its been a while since I wrote any VB!)
Private CurrentQuestion As Integer
Private Sub Questions()
CurrentQuestion = 0
...
AskQuestion
End Sub
Private Sub AskQuestion
If CurrentQuestion = UBound(strQuestions)
EndGame
Else
userAnswer = InputBox(strQuestions(CurrentQuestion))
If userAnswer <> strAnswers(CurrentQuestion) Then
MsgBox("Incorrect. Try again.")
AskQuestion
Else
CurrentQuestion = CurrentQuestion + 1
MsgBox("Correct! Make your move.")
End If
End If
End Sub
Private Sub label_click(ByVal sender As System.Object,
....
AskQuestion
End Sub

Related

Get the Selection Type in WPF RichTextBox Bullet List in VB.NET

After discovering there is a way to change a WPF RichTextBox Bullet List ListMarker style in VB.NET, I've run into a problem involving partial selections.
The following code can change the bullet types on a WPF Rich Text Box:
Private Sub BulletList(intType As Integer)
With rtfActiveEdit
' Tries to avoid crashing...
Try
' Only operates if there's something selected...
If Not IsNothing(.Selection.Start.Paragraph) And Not IsNothing(.Selection.End.Paragraph) Then
' Sets up data processing variables...
Dim phStart As Block = .Selection.Start.Paragraph
Dim phEnd As Block = .Selection.End.Paragraph
Dim strSelect As String = .Selection.Text
Dim strList() As String
Dim lstOutput As List
Dim itmAdd As ListItem
Dim strPickup As String = ""
Dim phHold As Paragraph
Dim intItem As Integer = 0
Dim intCount As Integer = 0
Dim strBreak As String = vbCrLf
Dim strTab As String = vbTab
Dim blnList As Boolean = False
Dim blnPlain As Boolean = False
' Obtains the highlighted material...
strList = Split(strSelect, strBreak)
' Counts up items in the highlighted material...
intCount = strList.Length
' Sets up the bullet point style...
Dim nowStyle As TextMarkerStyle
Dim tmStyle As TextMarkerStyle
' Responds based on user input...
Select Case intType
Case 0 ' NONE
tmStyle = TextMarkerStyle.None
Case 1 ' DISC (Default)
tmStyle = TextMarkerStyle.Disc
Case 2 ' BOX
tmStyle = TextMarkerStyle.Box
Case 3 ' CIRCLE
tmStyle = TextMarkerStyle.Circle
Case 4 ' SQUARE
tmStyle = TextMarkerStyle.Square
Case 5 ' DECIMAL NUMBERS
tmStyle = TextMarkerStyle.Decimal
Case 6 ' LOWERCASE
tmStyle = TextMarkerStyle.LowerLatin
Case 7 ' UPPERCASE
tmStyle = TextMarkerStyle.UpperLatin
Case 8 ' LOWERCASE ROMAN
tmStyle = TextMarkerStyle.LowerRoman
Case 9 ' UPPERCASE ROMAN
tmStyle = TextMarkerStyle.UpperRoman
End Select
' Reacts based on whether selected contents include a list...
If phStart.Parent.GetType() Is GetType(ListItem) And phEnd.Parent.GetType() Is GetType(ListItem) Then
' Loads the current list type...
nowStyle = CType(phStart.Parent, ListItem).List.MarkerStyle
' Responds based on the list type...
Select Case nowStyle.ToString
Case "Disc", "Box", "Circle", "Square"
' Removes BULLET LIST formatting
EditingCommands.ToggleBullets.Execute(vbNull, rtfActiveEdit)
Case "Decimal", "LowerLatin", "UpperLatin", "LowerRoman", "UpperRoman"
' Removes ORDERED LIST formatting...
EditingCommands.ToggleNumbering.Execute(vbNull, rtfActiveEdit)
Case Else
' Should NEVER happen...
End Select
' Triggers list reprocessing...
blnList = True
' Only triggers complete list removal if the user chooses...
If intType = 0 Then
' Triggers list removal...
blnPlain = True
End If
Else
' Only triggers complete list blockage if the user chooses "None" on a NON-LIST...
If intType = 0 Then
' Prevents reformatting "NONE" as a list (YIKES!!!)...
blnPlain = True
Beep()
End If
End If
' Only operates if the list needs formatting...
If blnPlain = False Then
' Prepares to add items to the new list...
lstOutput = New List
' Sets the style for the list...
lstOutput.MarkerStyle = tmStyle
' Loops through the selected text...
For intItem = 0 To intCount - 1
' Collects the item from the array...
strPickup = strList(intItem)
' Removes unwanted list markers that survived formatting removal...
If blnList = True Then
' Strips unwanted formatting...
strPickup = Right(strList(intItem), Len(strList(intItem)) - InStr(strList(intItem), strTab))
' Only strips off leading tab characters...
While Strings.Left(strPickup, 1) = strTab
' Removes the tab...
strPickup = Right(strPickup, Len(strPickup) - 1)
End While
End If
' Creates a new paragraph...
phHold = New Paragraph
' Adds text to the paragraph...
phHold.Inlines.Add(strPickup)
' Adds the paragraph to a new list item...
itmAdd = New ListItem(phHold)
' Adds the new list item to the new list...
lstOutput.ListItems.Add(itmAdd)
Next
' Attempts to resolve how to handle the selection...
Dim objPlace As Type
' Attempts to get the element just before this one...
objPlace = .Selection.GetType
' Operates based on whether the item just before the selection is a list item...
If objPlace Is GetType(List) Then
MsgBox("This is the part that needs to be changed...")
' needs to select the affected list item
' list item needs to get a new paragraph
' new paragraph needs to get a new list
' new list needs to be the output
Else
MsgBox("This part only works on fully selected lists")
' Clears the selection (YIKES!!!)...
.Selection.Text = ""
' Attempts to clear a leading carriage return from the list (YIKES!!!)...
.Document.Blocks.Remove(.CaretPosition.Paragraph)
' This step constistently fails when part of a list is selected...
' REWRITE IT TO FIX THE PROBLEM
' Inserts the list directly into the document...
.Document.Blocks.InsertBefore(.CaretPosition.Paragraph, lstOutput)
End If
End If
End If
Catch ex As Exception
' Notifies the user...
MsgBox("Try selecting something simpler." & vbCrLf & ex.Message, vbExclamation, "Formatting Failed")
End Try
End With
End Sub
This code is activated by a menu with the different bullet point styles assigned a value. When the user selects a style from the menu, the buttons send the appropriate value.
I have tried to determine what the selection type is, in an attempt to force the partially selected part of the bullet list or numbered list to be nested according to what's in the link. But the best I've gotten is "System.Runtime.Type," with the current code. An earlier configuration could get the element adjacent to the selection, but the only type that ever gave was "Run." If the system could identify that the selection has a "ListItem," it would be possible to move on from there.
Creating Nested Bullet List At Runtime is possible, and that involved adding to a list after it was included in the document.
If my program could identify the type of element being selected, it could be programmed to branch and handle the partial selection.
It turns out that getting the parent requires iterating through the type of object by moving the text pointer.
' Attempts to resolve how to handle the selection...
Dim objPlace As DependencyObject
' Identifies the caret position to begin the loop...
Dim tpPlace As TextPointer = .CaretPosition
' Gets the first object type...
objPlace = .CaretPosition.GetAdjacentElement(LogicalDirection.Backward)
' Sets up a feedback variable that's easier to read or translate...
Dim strPlace As String = ""
Dim intPlace As Integer = 0
' Attempts to loop through parent objects...
Do While Not (objPlace.GetType Is GetType(List))
' Increments the counter...
intPlace += 1
' Moves the text pointer one unit farther over...
tpPlace = tpPlace.GetNextContextPosition(LogicalDirection.Backward)
' Gets the object...
objPlace = tpPlace.GetAdjacentElement(LogicalDirection.Backward)
' Exits the loop if it runs too long, or if nothing is found...
If intPlace < 1000 And Not IsNothing(objPlace) Then
' Gets the object type...
strPlace = objPlace.GetType.ToString
Else
' Exits the loop...
Exit Do
End If
Loop
The code above identifies the object type, then creates a text pointer that can be moved by the program to find the desired object type if the current object isn't a match. It keeps moving the text pointer earlier and earlier, until it locates something it can work with. A condition limits the code from running endlessly by counting the number of loops that have run.
EDIT: The loop is modified to allow the program to abort if objPlace is nothing. This prevents crashing if the text pointer reaches the beginning of the document, where adjacent elements would be impossible to find.

Object returned as null when reading a file

My task is to make a program that allows the user to input a question and an answer (true or false) in the same array, which if you were to read the file would look like:
"Question 1", "T"
It then needs to take the questions and randomly select five to display for output. My problem is that whenever I try to debug, it cannot read the file and instead returns an error.
Private Sub Quiz(sender As System.Object, e As System.EventArgs) Handles btnQuiz.Click
If Viewed = True Then
LoadData()
RandomizeStrings()
Duplicates()
frmQuiz.Show()
correct = 0
answers = 0
count = 0
Else : MsgBox("You must view the slide show before you take the quiz!", MsgBoxStyle.Information, "View Slide Show")
End If
End Sub
Private Sub AddQuestion(sender As System.Object, e As System.EventArgs) Handles btnQuestions.Click
pass = "sample01"
response = InputBox("Please enter the administrator password.", "Password")
If response = pass Then
Do
FileOpen(1, "W:\Visual Studio 2010\Projects\Culminating\assets\questions.txt", OpenMode.Append)
question = InputBox("Enter new question (true or false format).", "New Question")
If question = String.Empty Then
Exit Do
FileClose(1)
End If
answer = InputBox("Enter new answer (either 'T' or 'F').", "New Answer")
answer = StrConv(answer, vbUpperCase)
If answer = String.Empty Then
question = String.Empty
Exit Do
FileClose(1)
End If
WriteLine(1, question, answer)
Loop
Else : MsgBox("Incorrect password. Please enter again.", MsgBoxStyle.Critical, "Incorrect Password")
End If
End Sub
Public Sub LoadData()
FileOpen(1, "W:\Visual Studio 2010\Projects\Culminating\assets\questions.txt", OpenMode.Input)
Do While Not EOF(1)
count = count + 1
Input(1, question(count))
Input(1, answer(count))
Loop
FileClose(1)
End Sub
Public Sub RandomizeStrings()
Dim x As Object
Randomize()
For x = 1 To 5
num(x) = Int((count - 1 + 1) * Rnd() + 1)
Next x
End Sub
Public Sub Duplicates()
Dim y As Object
Dim x As Object
For x = 1 To 4
For y = (x + 1) To 5
If num(x) = num(y) Then
num(x) = Int((count - 1 + 1) * Rnd() + 1)
x = 1
End If
Next y
Next x
End Sub
My problems arise at this line in the LoadData() sub:
Input(1, question(count))
At this point, it gives me this error:
Object reference not set to an instance of an object.
I really don't know my way around this as I'm following the exemplar our teacher has given us and I don't want to go out on a limb and use a different method to complete this task (even though I think this is obsolete).

Checking if an index in a array in empty VB6

I have been getting into some object-oriented features of VB6. I've done lots of OOP with Java, and I'm trying to get this to work:
I have a array of Card objects, I want to check if an object in the index in the array has been created.
Dim cardsPlayer1(1 To 10) As Card
I created objects like this:
Set cardsPlayer1(index) = New Card
If tried using this to test if I have assigned an object to an index yet:
For counter = 1 To 10
If (cardsPlayer1(counter) Is Nothing) Then
Set cardsPlayer1(counter) = New Card
End If
Next counter
But it gave me a true value everytime and creating a new object to the whole array.
Here's the relevant code:
'Jordan Mathewson
'May 31, 2013
Dim cardsPlayer1(1 To 10) As Card
Dim cardsPlayer2(1 To 10) As Card
Private Sub cmdStartGame_Click()
Call addCard(1)
End Sub
'Called to add a card to one of the player's stacks
Private Sub addCard(player As Integer)
Dim counter As Integer
'To add a card to player1..
If (player = 1) Then
For counter = 1 To 10
If (cardsPlayer1(counter) Is Nothing) Then
Print "Object created." '<- Printed 10 times.
Set cardsPlayer1(counter) = New Card
End If
Next counter
'To add a card to player2..
Else
For counter = 1 To 10
If (cardsPlayer2(counter) Is Nothing) Then
Set cardsPlayer2(counter) = New Card
End If
Next counter
End If
Call refreshForm
End Sub
If I understand you correctly, the addCard sub should add one card but it adds all of them, when only called once. This isn't because it can't tell which array element is empty. It's just because it doesn't stop after successfully adding one.
For counter = 1 To 10
If (cardsPlayer1(counter) Is Nothing) Then
Set cardsPlayer1(counter) = New Card
Exit For ' <-- Add this
End If
Next counter
Without the Exit For, it will keep looping through the array and initialize the rest of it.
I suspect you might have a scoping issue. This gives me the expected results:
Sub Test()
Dim objectsArray(1 To 5) As TestObject
If objectsArray(1) Is Nothing Then
MsgBox "objectsArray(1) Is Nothing" ' <----- displayed
End If
Set objectsArray(1) = New TestObject
If objectsArray(1) Is Nothing Then
MsgBox "objectsArray(1) Is Nothing"
Else
MsgBox "Not objectsArray(1) Is Nothing" ' <----- displayed
End If
End Sub
Where do you declare objectsArray; where do you create the object; where is the loop? (Are these code snippets in different modules/class modules/functions?)

Making every variable in this code Dynamic Visual Basic 2010

Sorry for the long piece of code. In a game I'm designing, I have this code starting at the checkbox.checked if statement currently repeated 5 times for each checkbox clicked--each checkbox is equal to a card within the players hand in the game.
What I'd like to know is what can I do to make it mostly dynamic. Namely the CardCheckBox1.Checked Object/Method. As stated above the code is repeated 5 times, as I have 5 existing checkboxes. Is there a way to place the checkboxes into an array or collection so when I click a check box and hit the play button it will be the equivalent of hitting CardCheckBox2.checked = true, CardCheckBox2.checked = true, etc. Once I figure how to make that part dynamic I can finally start making the rest of the code dynamic, because I assume procedure for making a dynamic label code would be very similar to the checkboxes, etc.
I've had
Dim CardCheckBoxArray() As CheckBox = {CardCheckBox1, CardCheckBox2, CardCheckBox3, CardCheckBox4, CardCheckBox5}
posted at the Modular Level, in the Form_Load Procedure, and even the Play_Button Procedure, but I always end up with a nullreference exception on the CardCheckBox(n).Checked Portion of the code when I do
If CardCheckBoxArray(0).Checked = True And Player1HandGroup(Number1).QuantityInteger > 0 Then
So I don't know where to go with it. The long piece of code is my entire PlayButton_Click procedure, except for the other CardCheckBox if statements.
Private Sub PlayButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PlayButton.Click
Dim n As Integer
Dim WeaponDiscardInteger As Integer = 1
AtkPlayerDialog.ShowDialog()
'Code for choosing which player to attack
If AtkPlayerDialog.DialogResult = Windows.Forms.DialogResult.Cancel Then
n = 2
ElseIf AtkPlayerDialog.DialogResult = Windows.Forms.DialogResult.OK Then
n = 1
ElseIf AtkPlayerDialog.DialogResult = Windows.Forms.DialogResult.Abort Then
n = 3
ElseIf AtkPlayerDialog.DialogResult = Windows.Forms.DialogResult.Retry Then
n = 4
ElseIf AtkPlayerDialog.DialogResult = Windows.Forms.DialogResult.Ignore Then
n = 5
End If
'playing card 1
If CardCheckBox1.Checked = True And Player1HandGroup(Number1).QuantityInteger > 0 Then
'Subtract Hitpoints when damage is delt
Player1HandGroup(n).HitPoints -= Player1HandGroup(Number1).DamageInteger
HitPoints1.Text = Player1HandGroup(1).HitPoints.ToString
HitPoints2.Text = Player1HandGroup(2).HitPoints.ToString
HitPoints3.Text = Player1HandGroup(3).HitPoints.ToString
HitPoints4.Text = Player1HandGroup(4).HitPoints.ToString
HitPoints5.Text = Player1HandGroup(5).HitPoints.ToString
'When player plays hand, card quantity is removed from hand to discard pile.
Player1HandGroup(Number1).QuantityInteger -= 1
DiscardGroup(Number1).QuantityInteger += 1
'Shuffle Deck from Discard Pile if Deck is out of cards
Call DiscardPile()
'Reset Number Generator, unless weapon isn't discard
Number = (DeckGroup(Rnd.Next(0, DeckGroup.Count)).ID)
If DeckGroup(Number).QuantityInteger > 0 Then
'Grab New Card From Deck
DeckGroup(Number).QuantityInteger -= 1
Player1HandGroup(Number).QuantityInteger += 1
Card1Type = Player1HandGroup(Number).CardType
CardCheckBox1.Text = Player1HandGroup(Number).CardNameString
Number1 = Number
Else
Call PlayElse()
End If
I f you use the checkbox array inside/through most your form code then move it out o the form load event right the way up to the form level scope. when it is inside the forn_load event subroutine, that is not the same as module level scope.
so you would have......
Dim CardCheckBoxArray() As CheckBox = {CardCheckBox1, CardCheckBox2, CardCheckBox3, CardCheckBox4, CardCheckBox5}
Sub Form_Load(blah blah blah)
...
End Sub
Sub Play_Button(blah blah blah)
...
End Sub
etc etc

Circulate playing audio with MediaElement in WPF

I am developing a video player with WPF.(in VB)
I have already created a MediaElement ,ListBox, "Next" button,
then start playing through reading ListBox,
and use "Next" to skip to next audio/video.
In "MediaEnded" event, i just copy all code in "Next" button.
Now, problem is coming,
Assume the Listbox has four audios(.mp3), "test1.mp3", "test2.mp3", ......
now playing is "test1.mp3", i push "Next" button, then now playing is "test2.mp3".
However, when i just let "test1.mp3" play completed, my player will not play "test2.mp3",
it plays "test3.mp3" or others in random.
This situation like "MediaEnded" event was processed for many times.
Private Sub MediaElement1_MediaEnded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MediaElement1.MediaEnded
nextmedia()
End Sub
Private Sub nextmedia()
Try
'pi is play index, start from 1, 0 is non playing
If pi <> 0 Then
If pi = ListBox_temp.Items.Count Then
Dim filename As String = ListBox_temp.Items.Item(0).ToString
MediaElement1.Source = New Uri(filename)
pi = 1
Else
Dim filename As String = ListBox_temp.Items.Item(pi).ToString
MediaElement1.Source = New Uri(filename)
pi = pi + 1
End If
End If
Catch ex As Exception
End Try
Window1.Title = "Video Sampler - " + CStr(pi) + ". " + CStr(ListBox1.Items.Item(pi - 1))
End Sub
Who can help me....
I haven't tested it, but try the following.
Try
pi = If(pi < ListBox_temp.Items.Count - 1, pi + 1, 0)
Dim filename As String = ListBox_temp.Items.Item(pi).ToString
MediaElement1.Source = New Uri(filename)
Catch ex As Exception
End Try
This increments pi unless the last ListBoxItem is selected, in which case it sets it to zero.

Resources