How do I count how many guesses it takes to get the correct number in Visual Basic? - vb.net

I have been struggling with this code for a while. I'm trying to make it so after the user gets the number right, the program counts how many tries it has taken them to get the number right. How can I do this?
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
'SELECTS THE SECTET NUMBER
Randomize() 'WITHOUT rANDOMIZE, THE SAME SEQUENCE OF NUMBERS APPEARS EACH RUN
secretNumber = Int(Rnd(1) * 1000 + 1) 'picks a random nubmer between 1 and 1000
'sets the initial prompts
Me.lblLow.Text = 1
Me.lblHigh.Text = 1000
Me.txtGuess.Focus()
Dim count As Integer
btnEnterGuess.Enabled = True
btnStart.Enabled = False
Dim i As Integer
For i = 1 To count
count = count + 1
Next i
Do
count = count + 1
Loop Until count = secretNumber
MessageBox.Show("It took you " & i - 1 & " tries to get the number correct.")
End Sub

I threw this piece of code togeather, hopefully it will help.
Something to note when writing this kinda code, is that all this code is running on a single thread (unless you declare it otherwise). This means your program will become unresponsive when you run that for loop.
Public Class Form1
Dim count As Integer = 0
Dim answer As Integer = 0
Dim GameRunning As Boolean = True
Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message,
ByVal keyData As System.Windows.Forms.Keys) _
As Boolean
'Gets all keystrokes on the fourm
If GameRunning Then
'converts keystroke to key ID and tests to see if the keystroke is the ENTER key
If msg.WParam.ToInt32() = CInt(Keys.Enter) Then
'try catch to prevent crash if text in entered
Try
If txtAnswer.Text = answer Then
MessageBox.Show("Congratz! It took you " & count & " tries to guess the number!")
Else
txtAnswer.Text = ""
count = (count + 1)
End If
Catch ex As Exception
End Try
End If
End If
'update label to show tries
lblTries.Text = "Tries: " & count
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
Private Sub SetupOnLoad() Handles MyBase.Load
Reset()
End Sub
Public Sub Reset()
count = 0
Randomize()
answer = Int(Rnd(1) * 1000 + 1)
txtAnswer.Text = ""
lblTries.Text = "Tries: " & count
GameRunning = True
End Sub
'the Reset() code is ran on the program launch and when you press the button to prepare the game.
Private Sub Reset_Game() Handles BtnReset.Click
Reset()
End Sub
End Class
This code gets the user input in the text box. When the user presses ENTER, the program tests to see if its the correct number.
Hope this helped!

I will try something like this, randomize need to be placed outside of the click
Public Class Form1
Dim count As Integer = 0
Dim answer As Integer = 0
Private Sub btnStart_ClicK(sender As Object, e As EventArgs) Handles btnStart.Click
Randomize()
answer = Int(Rnd(1) * 1000 + 1)
btnStart.Enabled = False
btnGuess.Enabled = True
End Sub
Private Sub btnGuess_Click(sender As Object, e As EventArgs) Handles btnGuess.Click
count += 1
If answer = TextBox1.Text Then
MessageBox.Show("It took you " & count & " tries to get the number correct.")
btnStart.Enabled = True
btnGuess.Enabled = False
count = 0
answer = 0
Else
TextBox1.Text = ""
End If
End Sub
End Class

Related

How can I get ten numbers and displays the biggest and lowest one?

sorry I'm a newbie and I'm trying to write a program to get ten integers from user with a an Inputbox or Textbox and displays the biggest and lowest one in a label with visual basic. I'll be appreciated if you help me out with this.
Thank you. this is my solution. I don't know how to compare these ten numbers with each other.
Private Sub btnShow_Click(sender As Object, e As EventArgs) Handles btnShow.Click
Dim i, Container, Max, Numbers
Max = 0
i = 1
While (i <= 10)
Numbers = InputBox("please enter a number", "Enter a number")
Max = Numbers
Container = Container & " " & Numbers
i = i + 1
End While
lblresult.Text = Container
End Sub
conceptually speaking you should use a List(Of Integer) or List(Of Double), perform the loop 10 times adding the value into the list.
Suppose this is our list
Dim container As New List(Of Integer)
To get input
Dim userInput = ""
Dim input As Integer
userInput = InputBox("please enter a number", "Enter a number")
If Integer.TryParse(userInput, input) Then
container.Add(input)
End If
After the loop
Console.WriteLine($"Min: {container.Min()} Max: {container.Max()}")
Does this make sense to you ?
Edit, based on asking for Windows Forms example.
You could do the following instead of a InputBox, requires a label, a button and a TextBox.
Public Class MainForm
Private container As New List(Of Integer)
Private Sub CurrentInputTextBox_KeyPress(sender As Object, e As KeyPressEventArgs) _
Handles CurrentInputTextBox.KeyPress
If Asc(e.KeyChar) <> 8 Then
If Asc(e.KeyChar) < 48 Or Asc(e.KeyChar) > 57 Then
e.Handled = True
End If
End If
End Sub
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
CurrentLabel.Text = "Enter number 1"
End Sub
Private Sub ContinueButton_Click(sender As Object, e As EventArgs) _
Handles ContinueButton.Click
If Not String.IsNullOrWhiteSpace(CurrentInputTextBox.Text) Then
container.Add(CInt(CurrentInputTextBox.Text))
CurrentLabel.Text = $"Enter number {container.Count + 1}"
If container.Count = 10 Then
ContinueButton.Enabled = False
CurrentLabel.Text =
$"Count: {container.Count} " &
$"Max: {container.Max()} " &
$"Min: {container.Min()}"
Else
ActiveControl = CurrentInputTextBox
CurrentInputTextBox.Text = ""
End If
End If
End Sub
End Class
I really didn't want to do your homework for you but I was afraid you might be hopelesly confused.
First let's go over your code. See comments
Private Sub btnShow_Click(sender As Object, e As EventArgs) Handles btnShow.Click
Dim i, Container, Max, Numbers 'Don't declare variables without an As clause
Max = 0 'Max is an object
i = 1 'i is and object
While i <= 10 'the parenthesis are unnecessary. You can't use <= 2 with an object
Numbers = InputBox("please enter a number", "Enter a number")
Max = Numbers
Container = Container & " " & Numbers 'Container is an object; you can't use & with an object
i = i + 1 'Again with the object i can't use +
End While
lblresult.Text = Container
End Sub
Now my approach.
I created a List(Of T) at the Form level so it can be seen from different procedures. The T stands for type. I could be a built in type or type you create by creating a Class.
The first click event fills the list with the inputted numbers. I used .TryParse to test if the input is a correct value. The first parameter is a string; the input from the user. The second parameter is a variable to hold the converted string. .TryParse is very clever. It returns True or False base on whether the input string can be converted to the correct type and it fills the second parameter with the converted value.
The second click event loops through the list building a string to display in Label1. Then we use methods available to List(Of T) to get the numbers you desire.
Private NumbersList As New List(Of Integer)
Private Sub FillNumberList_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim i As Integer
While i < 10
Dim input = InputBox("Please enter a whole number")
Dim inputInt As Integer
If Integer.TryParse(input, inputInt) Then
NumbersList.Add(inputInt)
i += 1 'We only increment i if the parse is succesful
End If
End While
MessageBox.Show("Finished Input")
End Sub
Private Sub DisplayResults_Click(sender As Object, e As EventArgs) Handles Button2.Click
Label1.Text = "You input these numbers "
For Each num In NumbersList
Label1.Text &= $"{num}, "
Next
Label2.Text = $"The largest number is {NumbersList.Max}"
Label3.Text = $"The smallest number is {NumbersList.Min}"
End Sub

visual basic looping issue

I am a new programmer learning Visual Basic. Right now, I'm working on a project about a softball scoreboard. I have been working on this project for a bit, and I am confused on 1 thing.
The thing I am confused on is the proper place to place my loop. I am trying to do a while loop, but when I try it allows me to enter the 7 innings, but once I do it is an infinate loop with the message only seven innings are allowed and it does not display the lblTotal. It works without the loop, but it just doesnt allow me to enter all of the innings back to back. I would really appreciate if you could help me. I feel like I placed the loop in the wrong place.
Public Class frmSoftballScoreboard
Const VALID_MESSAGE As String = "Enter valid runs value"
Const ONLY_MESSAGE As String = "Only seven innings are allowed"
'Declaring array
Dim scores(6) As Double
'declaring variables
Dim runs As String
Dim runningScore As Integer = 0
Dim i As Integer = 0
Dim out As Double
'page load event
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
lstScores.Items.Add("Runs : Running Score")
End Sub
'Enter score button
Private Sub btnScore_Click(sender As Object, e As EventArgs) Handles btnScore.Click
Do While runs <= 7
If i < scores.Length Then
'display inputbox to the user
runs = InputBox("Enter score for " & (i + 1) & " innings", "Score")
'if runs is entered
If runs < 0 Then
MessageBox.Show(VALID_MESSAGE)
Exit Sub
ElseIf runs <> "" Then
'parse the value of runs
If (Double.TryParse(runs, out)) Then
'parse the runs and add it to the array scores()
scores(i) = Double.Parse(runs)
runningScore += scores(i)
'add the rainfall value to the listbox along with month name
lstScores.Items.Add(scores(i) & " :" & runningScore)
'increment the value of i
i = i + 1
Else
'display error message
MessageBox.Show(VALID_MESSAGE)
lblTotal.Text = ""
End If
Else
'if runs is empty then display error message
MessageBox.Show("Enter runs for " & i & "innings")
End If
Else
MessageBox.Show(ONLY_MESSAGE)
End If
If runs < 0 Then
MessageBox.Show(VALID_MESSAGE)
End If
Loop
'calculate total runs And display on the lable
If scores(6) = 7 Then
lblTotal.Text = String.Format("final score is {0}", scores.Sum())
End If
End Sub
Private Sub mnuClear_Click(sender As Object, e As EventArgs) Handles mnuClear.Click
lstScores.Items.Clear()
lblTotal.Text = ""
'reset i to 0
i = 0
End Sub
'Exit Menu click
Private Sub mnuExit_Click(sender As Object, e As EventArgs) Handles mnuExit.Click
'close application
Application.Exit()
End Sub
End Class
Do While runs <= 7
'runs' variable should be updated (adding +1) within the 'Do While' loop in order to be able to satisfy the condition and break out.
(...)
runs += 1
Loop

How can limit how many times an operator shows up in my maths quiz in vb?

My task was to create a 10 question maths quiz with 2 random numbers and a random operator (only +, - or *) for each question. Also the program must ask for the users name. Which I have done.
But as my quiz has only 10 questions, there is a very small probability that one of the operators will be in the majority or that one may not show up. So basically I need something that can limit how many times each operator shows up, for example each operator can only show up 4 times.
As you can see from my code, I'm coding in form. I would be very grateful if you could help me with this as I couldn't find anything on the internet for it and I'm also not too sure how to go about solving this problem either.
Private Sub StartTheQuiz()
number1 = randomizer.Next(1, 13)
number2 = randomizer.Next(1, number1)
leftpluslbl.Text = number1.ToString
rightpluslbl.Text = number2.ToString
userinput.Value = 0
Correct.Visible = False
Incorrect.Visible = False
End Sub
Public Sub TheOperator()
Randomize()
operation = randomizer.Next(1, 4)
addmintime = operation
If addmintime = 1 Then
answer = number1 + number2
operatorlbl.Text = "+"
Userinput.Value = useranswer
ElseIf addmintime = 2 Then
answer = number1 - number2
operatorlbl.Text = "-"
Userinput.Value = useranswer
ElseIf addmintime = 3 Then
answer = number1 * number2
operatorlbl.Text = "x"
Userinput.Value = useranswer
End If
End Sub
Public Function CheckTheAnswer()
If userinput.Value = answer Then
Return True
Else
Return False
End If
End Function
Private Sub Start_Click(sender As Object, e As EventArgs) Handles Start.Click
If NameBox.Text = "What is your name? Enter your name here" Then
NameBox.BackColor = Color.Red
NextBtn.Visible = False
Check.Visible = False
Else
StartTheQuiz()
NameBox.BackColor = Color.LimeGreen
Start.Enabled = False
Start.Visible = False
TheOperator()
question = 0
score = 0
Check.Visible = True
NameBox.Enabled = False
End If
End Sub
Private Sub Check_Click(sender As Object, e As EventArgs) Handles Check.Click
If CheckTheAnswer() = True Then
Correct.Visible = True
Incorrect.Visible = False
question = question + 1
score = score + 1
ElseIf CheckTheAnswer() = False Then
Correct.Visible = False
Incorrect.Visible = True
question = question + 1
score = score + 0
End If
NextBtn.Visible = True
Check.Visible = False
End Sub
Private Sub NextBtn_Click(sender As Object, e As EventArgs) Handles NextBtn.Click
If question < 10 Then
StartTheQuiz()
TheOperator()
Check.Visible = True
NextBtn.Visible = False
ElseIf question >= 10 Then
MessageBox.Show("You have scored " & score & "/10")
MessageBox.Show("Goodbye")
Me.Close()
End If
End Sub
End Class
Here's an example of what I mentioned in the comments. It builds a list of the desired number of operations in equal quantities, then shows how to pull a random one from that list:
Public Class Form1
Private Operations As New List(Of String)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Operations = CreateOperations(10)
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
If Operations.Count > 0 Then
Dim operation As String = NextRandomOperation()
Debug.Print(operation)
Else
Debug.Print("No more operations in list!")
End If
End Sub
Private Function CreateOperations(ByVal NumberOperations As Integer) As List(Of String)
Dim operators() As String = {"+", "-", "X"}
Dim operations As New List(Of String)
While Operations.Count < NumberOperations
Operations.AddRange(operators)
End While
While Operations.Count > NumberOperations
Operations.RemoveAt(Operations.Count - 1)
End While
Return operations
End Function
Private Function NextRandomOperation() As String
Static R As New Random
If Operations.Count > 0 Then
Dim index As Integer = R.Next(Operations.Count)
Dim operation As String = Operations(index)
Operations.RemoveAt(index)
Return operation
End If
Return ""
End Function
End Class
The proposed solution above will always produce four +, three - and three X. If you want a more random distribution you need to randomize the operators() array.
Dim rnd As New System.Random
Dim operators() As String = New String() {"+", "-", "X"}.OrderBy(Function() rnd.Next).ToArray

Issue with Progressbar in VB2012

I am trying to add a ProgressBar to my program. The program basically compares two values of time and when the values are equal a MessageBox appears to indicate that time is up. I need the ProgressBar to load based on the time difference of the two values. One of the values in a clock and the other is input by the user (similar to an alarm).
My code:
Imports System.Net.Mime.MediaTypeNames
Public Class Form1
Private hour As Integer = 0
Private minute As Integer = 0
Private second As Integer = 0
Public Sub show_time()
second += 1
If second = 59 Then
second = 0
minute += 1
If minute = 59 Then
minute += 1
hour += 1
End If
End If
Label3PrgressStdPC.Text = hour.ToString.PadLeft(2, "0") & ":"
Label3PrgressStdPC.Text &= minute.ToString.PadLeft(2, "0") & ":"
Label3PrgressStdPC.Text &= second.ToString.PadLeft(2, "0")
Label3PrgressStdPC.Refresh()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
show_time()
If TextBox1.SelectedText = TextBox1.Text Then Exit Sub
If TextBox1.Text = Label3PrgressStdPC.Text Then
Timer1.Stop()
MsgBox("time is up")
End If
End Sub
Private Sub Bn_start_St01_Click(sender As Object, e As EventArgs) Handles Bn_start_St01.Click
Timer1.Start()
Timer1.Enabled = True
Timer2.Start()
Timer2.Enabled = True
End Sub
**Private Sub ProgressBar1_Click(sender As Object, e As EventArgs) Handles ProgressBar1.Click
ProgressBar1.Maximum = , the max progrssbr will be determine by user input
ProgressBar1.Minimum = 0**
End Sub
**Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
progresbar1.value = ,Not so sure how to write the logic here**
End Sub
End Class
Can anyone help me out i am really getting frustrated.....thanks
How about something like this...
Private Ticker As Timer = New Timer 'Create a timer
Private Start As DateTime 'Store when we start
Private Expire As DateTime 'and when we end
'Call this to get things going
Sub Begin(EndHour As Integer, EndMinute As Integer, EndSecond As Integer)
Start = DateTime.Now
'If input is a time today ...
Expire = DateTime.Now.Date.Add(New TimeSpan(EndHour, EndMinute, EndSecond))
'or just a number of hours/mins/secs from now...
Expire = DateTime.Now.Add(New TimeSpan(EndHour, EndMinute, EndSecond))
'When the timer fires, call Tick()
AddHandler Ticker.Elapsed, Sub() Tick()
Ticker.Enabled = True
Ticker.Interval = 1000
Ticker.Start
End Sub
Private Sub Tick()
If DateTime.Now < Expire Then
'Not Finished
Dim Elapsed = DateTime.Now.Subtract(Start)
Dim TotalMillis = Expire.Subtract(Start).TotalMilliseconds
Dim ProgressDouble = Elapsed.TotalMilliseconds / TotalMillis
'Me.Invoke is used here as the timer Tick() occurs on a different thread to the
'one used to create the UI. This passes a message to the UI telling it to
'update the progress bar.
Me.Invoke(Sub()
ProgressBar1.Value = CInt(ProgressDouble * ProgressBar1.Maximum)
Label3PrgressStdPC.Text = Elapsed.ToString
End Sub)
Else
'Done
MessageBox.Show("Done")
Ticker.Stop
End If
End Sub
See VB.NET Delegates and Invoke - can somebody explain these to me? for more information on Invoking.

Running Different Processes In Multiple Threads Without Overlapping In VB.NET 2

I have a sub-procedure which I want to run a different process, depending on what is currently running. I thought the easiest way to do this was by using an ArrayList of each of the campaign details & adding an 'Inuse' field to check to see if the Inuse field is set to 0 or 1. The problem that I have is that when running the process it is all happening at once & the integer hasn't been changed before the next thread kicks in so my threads are running the same campaigns.
I tried to avoid the problem by adding a Thread.Sleep(100) delay inbetween starting threads but this led to exactly the same problem.
Here's an example of what I am trying to do:
Imports System.Threading
Public Class Form1
Private Campaigns As New ArrayList
Private ProcessRunning As Boolean = False
Friend StopProcess As Boolean = False
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
For i = 0 To Campaigns.Count - 1
Dim objNewThread As New Thread(AddressOf RunProcess)
objNewThread.IsBackground = True
objNewThread.Start()
Next
End Sub
Private Sub UpdateCells(ByVal CampID As Integer, ByVal Column As String, ByVal newText As String)
Dim CellItemNum As Integer
If Column = "Status" Then CellItemNum = 4
DataGridView2.Rows(CampID).Cells.Item(CellItemNum).Value = newText
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For i As Integer = 0 To 10
Campaigns.Add({Campaigns.Count(), "Campaign " & i, "Keywords " & i, "Link " & i, 5, True, 0, 0})
Next
DataGridView2.Rows.Clear()
For Each Campaign In Campaigns
DataGridView2.Rows.Add(New String() {Campaign(1), Campaign(2), Campaign(3), Campaign(6), ""})
Next
End Sub
Private Sub RunProcess()
' Set Variables
Dim CampID As Integer
Dim CampName As String
Dim Keywords As String
Dim Link As String
Dim CheckEvery As Integer
Dim OkToUse As Boolean
Dim Sent As Integer
' Find A Free Campaign
For i As Integer = 0 To Campaigns.Count - 1
' Check If Inuse
If Campaigns(i)(7) = 1 Then Continue For Else Campaigns(i)(7) = 1 ' This Line Sets Campaign To Inuse
' Most of the time only campaign(0) and campaign(1) are selected & multiple threads are running them instead of choosing unique campaigns
' Set Campaign Details
CampID = Campaigns(i)(0)
CampName = Campaigns(i)(1)
Keywords = Campaigns(i)(2)
Link = Campaigns(i)(3)
CheckEvery = Campaigns(i)(4)
OkToUse = Campaigns(i)(5)
Sent = Campaigns(i)(6)
' Start Process
UpdateCells(CampID, "Status", "Looking Up New Links (" & CampID & ")")
Exit For
Next
While StopProcess = False
Thread.Sleep(1000)
UpdateCells(CampID, "Status", "Running Process (" & CampID & ")")
Thread.Sleep(1000)
For i = 0 To CheckEvery
UpdateCells(CampID, "Status", "Re-Checking In " & (CheckEvery - i) & " Seconds")
Thread.Sleep(1000)
Next
End While
' Closing Processes
Campaigns(CampID)(7) = 0
End Sub
End Class
You can use SyncLock to force your threads to wait.
class level so all threads access same lock
private myLock as new Object
Then use syncLock when you start your process and end it when you are done.
SyncLock myLock
'process code here
End SyncLock
More MSDN info on the subject
Try looking into QueueUserWorkItem():
Private Sub Button1_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles Button1.Click
For i = 0 To Campaigns.Count - 1
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf RunProcess), Campaigns[i])
Next
End Sub
Then change the RunProcess() method to include the Campaign object sent in by the work item:
Private Sub RunProcess(ByVal o As System.Object)
' Process the Campaign
Dim campaign As Campaign = Ctype(o, Campaign)
End Sub
There will be no need for inuse, plus threads will be managed by the managed ThreadPool!