How do Make my win and loss counter on my dice roll game output the correct numbers using visual basic - vb.net

I created the craps dice game as you press play your dice rolls if you roll the winning number or losing number when you first hit play it will tell you. if you dont win or lose on first roll you have the chance to use the roll button in order to keep rolling until you win or lose against the first set of dice rolled
i tried using an if else statement to determine the win count and display to the label although it only displays wins if you win on the first roll as you hit the play button not if you win and it took you multiple rolls clicking the roll button
Imports System.IO
Public Class CrapsGame
' die roll constants
Enum DiceNames
SNAKE_EYES = 2
TREY = 3
CRAPS = 7
LUCKY_SEVEN = 7
YO_LEVEL = 11
BOX_CARS = 12
End Enum
' file name and directory constants
Const FILE_PREFIX As String = "/images/die"
Const FILE_SUFFEX As String = ".png"
' instance variables
Dim myPoint As Integer = 0
Dim randomobject As New Random()
Dim winCount As Integer
Dim lossCount As Integer
' begin new game and determine point
Private Sub PlayButton_Click(sender As Object, e As EventArgs) Handles PlayButton.Click
'intialize variables for new game
myPoint = 0
PointBox.Text = "Point"
OutputLabel.Text = " "
' remove point die images
PointDie1PictureBox.Image = Nothing
PointDie2PictureBox.Image = Nothing
Dim Sum As Integer = RollDice() ' roll dice
'check die roll
Select Case Sum
' win on first roll
Case DiceNames.LUCKY_SEVEN, DiceNames.YO_LEVEL
OutputLabel.Text = "you win!!"
' lose on first roll
Case DiceNames.SNAKE_EYES, DiceNames.TREY, DiceNames.BOX_CARS
OutputLabel.Text = "sorry you lose."
Case Else ' player must match point
myPoint = Sum
PointBox.Text = "Point is " & Sum
OutputLabel.Text = "Roll again!"
PointDie1PictureBox.Image = Die1PictureBox.Image
PointDie2PictureBox.Image = Die2PictureBox.Image
PlayButton.Enabled = False ' disable Play Button
RollButton.Enabled = True ' enable Roll Button
End Select ' sum
If (Sum = myPoint Or Sum = DiceNames.CRAPS) Then
If OutputLabel.Text = "you win!!" Then
winCount = winCount + 1
Else
lossCount = lossCount + 1
End If
Label1.Text = "Win Count - " & winCount.ToString() + Environment.NewLine + "Loss Count - " & lossCount.ToString() + Environment.NewLine
End If
End Sub ' playbutton click
' determine outcome of next roll
Private Sub rollButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RollButton.Click
Dim sum As Integer = RollDice() ' roll dice
' determine outcome of roll
If sum = myPoint Then ' player matches point
OutputLabel.Text = "You win!!!"
RollButton.Enabled = False ' disable Roll Button
PlayButton.Enabled = True ' enable Play Button
ElseIf sum = DiceNames.CRAPS Then ' player loses
OutputLabel.Text = "Sorry, you lose."
RollButton.Enabled = False ' disable Roll Button
PlayButton.Enabled = True ' enable Play Button
End If
End Sub ' rollButton_Click
' generate random die rolls
Function RollDice() As Integer
' roll the dice
Dim die1 As Integer = randomobject.Next(1, 7)
Dim die2 As Integer = randomobject.Next(1, 7)
' display image corresponding to each die
DisplayDie(Die1PictureBox, die1)
DisplayDie(Die2PictureBox, die2)
Return (die1 + die2) ' return sum of dice values
End Function ' RollDice
' display die image
Sub DisplayDie(ByVal die As PictureBox, ByVal face As Integer)
' assign die images to PictureBox
die.Image = Image.FromFile(Directory.GetCurrentDirectory & FILE_PREFIX & face & FILE_SUFFEX)
End Sub ' DisplayDie
End Class

You need to increment your counters (winCount or lossCount) in the rollButton_Click subroutine. Currently the counters are only being updates when the Play button is clicked.

Related

Highlight specific text while user is typing

I am writing a code that highlight the duplicate words in a text. The code is working well when I add a button and the user have to press on the button to check for duplicates.
But I want to make an auto-checking code. I set my code in a subroutine that Handles RichTextBox.TextChanged. The problem is the code selects the target word and highlight it but the selection remains so when a new letter is typed, it clear what has been highlighted.
Here is my code:
Private Sub RichTextBox_TextChanged(sender As Object, e As EventArgs) Handles RichTextBox.TextChanged
Try
Call duplicate_check()
Catch ex As Exception
MessageBox.Show("error in RichTextBox.TextChanged")
End Try
End Sub
duplicate check function:
Private Sub duplicate_check()
Try
' read line by line and get input
Dim LineByLineInput() As String = RichTextBox.Lines
Dim selectionStart, selectionLength As Integer
Dim i, j As Integer
For lineNumber = 0 To UBound(LineByLineInput)
selectionStart = 0
selectionLength = 0
'get index of first char index in the current line
Dim count As Integer = lineNumber
While count <> 0
selectionStart += RichTextBox.Lines(count - 1).Length + 1
count -= 1
End While
' get line as string
Dim line As String = RichTextBox.Lines(lineNumber)
' split line into array of strings
Dim input() As String = line.Split(" ")
'check for duplicates
i = 0
For j = i + 1 To UBound(input)
If input(i) = input(j) Then 'compare each 2 consecutive words if they are the same
selectionStart += input(i).Length + 1
selectionLength = input(i).Length
RichTextBox.SelectionStart = selectionStart
RichTextBox.SelectionLength = selectionLength
RichTextBox.SelectionBackColor = Color.Yellow
Else
selectionStart += input(i).Length + 1
End If
i += 1
Next
Next
Catch ex As Exception
MessageBox.Show("error duplicate_check()")
End Try
End Sub
After your duplicate_check call, have you tried to set the selection of the RichTextBox back to the old position ?
See below :
Private Sub RichTextBox1_TextChanged(sender As Object, e As System.EventArgs) Handles RichTextBox1.TextChanged
Try
' Get current position
Dim cur_pos As Integer = Me.RichTextBox.SelectionStart
Call duplicate_check()
' Set back to old position
Me.RichTextBox.SelectionStart = cur_pos
' Unselect what your sub duplicate_check has selected
Me.RichTextBox1.SelectionLength = 0
Catch ex As Exception
MessageBox.Show("error in RichTextBox.TextChanged")
End Try
End Sub
If this solution is good for you, you should change your duplicate_check Sub to make this change and not in the RichTextBox1_TextChanged Sub

How to debug a cast execption in vb.net?

I am getting a cast exception and I have re-written this code a large number of times. I am getting the exception on the following line:
If (CInt(hHurricaneYear) < CInt(_strYears(hAverage))) Then
And I am only getting results in the lblNumberOfHurricans. the other two labels are not showing any results. I thought I was getting it when the cast exception showed up.
Can anyone suggest how to get the results and stop the exception?
Here is what I have so far (well at least the last try).
Option Strict On
Public Class frmHurricaneStatistics
' Class level Private variables.
Public Shared _intSizeOfArray As Integer = 20
Private _strYears(_intSizeOfArray) As String
Private _intNumberOfHurricans(_intSizeOfArray) As Integer
Private Sub frmHurricaneStatistics_Load(sender As Object, e As EventArgs
) Handles MyBase.Load
' This load event reads the inventory text file and fills
' the ComboBox object with the Hurricane Statistics.
' Initialize an instace of the streamreader object and declare variables.
Dim objReader As IO.StreamReader
Dim strHurricaneStatistics As String = "Hurricanes.txt"
Dim intCount As Integer = 0
Dim intFill As Integer
Dim strFileError As String = "The file is not available. Please restart the
application when the file is available."
' Verify the Hurricane.txt file exists.
If IO.File.Exists(strHurricaneStatistics) Then
objReader = IO.File.OpenText(strHurricaneStatistics)
' Read the file line by line until the file is completed.
Do While objReader.Peek <> -1
_strYears(intCount) = objReader.ReadLine()
_intNumberOfHurricans(intCount) = Convert.ToInt32(objReader.ReadLine())
intCount += 1
Loop
objReader.Close()
' The ComboBox objext is filled with the Years for Hurricanes.
For intFill = 0 To (_strYears.Length - 1)
cmbYears.Items.Add(_strYears(intFill))
Next
Else
MsgBox(strFileError, , "Error")
Close()
' If ComboBox is filled then enable the Display Statistics button.
'btnDisplayStatistics.Enabled = True
End If
End Sub
Private Sub btnDisplayStatistics_Click(sender As Object, e As EventArgs
) Handles btnDisplayStatistics.Click
' This click event calls the sub procedures for the selected years and
' the number of hurricans in that year.
Dim intSelectedYear As Integer
Dim strMissingSelection As String = "Missing Selection"
Dim strSelectAYearError As String = "Please Select a Year"
' If the ComboBox object has a selection, Display Statistics.
If cmbYears.SelectedIndex >= 0 Then
intSelectedYear = cmbYears.SelectedIndex
Else
MsgBox(strSelectAYearError, , strMissingSelection)
End If
Private Sub btnDisplayStatistics_Click(sender As Object, e As EventArgs
) Handles btnDisplayStatistics.Click
' This click event calls the sub procedures for the selected years and
' the number of hurricans in that year.
Dim intSelectedYear As Integer
Dim strMissingSelection As String = "Missing Selection"
Dim strSelectAYearError As String = "Please Select a Year"
' If the ComboBox object has a selection, call the Display Statistics procedure.
If cmbYears.SelectedIndex >= 0 Then
intSelectedYear = cmbYears.SelectedIndex
Else
MsgBox(strSelectAYearError, , strMissingSelection)
End If
' This procedure MakeLabelsVisible Is called to display the labels
' And the results.
MakeLabelsVisible()
Dim hHurricaneAverage As Integer
Dim hHurricaneYear As Integer = 0
For hAverage As Integer = 0 To _strYears.Length - 1
If (CInt(hHurricaneYear) < CInt(_strYears(hAverage))) Then
hHurricaneYear = CInt(CType(CInt(_strYears(hAverage)), String))
End If
hHurricaneAverage = hHurricaneAverage + CInt((_strYears.ToString))
hHurricaneAverage = CInt(hHurricaneAverage / _strYears.Length)
Next
' Display the statistics for the Storm Average in the selected Year
' and the most active year within the range of year.
lblNumberOfHurricanes.Text = "The Number of Hurricanes in the Year " &
_strYears(intSelectedYear) & " is " & _intNumberOfHurricans(intSelectedYear).ToString() & "."
lblAvergeNumberHurricanes.Text = "The Average Number of Storms was " &
hHurricaneAverage & " Hurricanes."
Dim intSizeOfArray As Integer = Nothing
lblMostStorms.Text = "The Year "(CInt(_strYears(CInt(hHurricaneYear.ToString())) & "
Had The Most Storms Between " & (_strYears(0) & _strYears(20).ToString)))
End Sub
Option strict on
Your error lies in that you are trying to convert an entire string array into an integer:
hHurricaneAverage = hHurricaneAverage + CInt((_strYears.ToString))
You will need to call the index of _strYears:
hHurricaneAverage = hHurricaneAverage + CInt((_strYears(hAverage).ToString))
This will also explain why the other labels do not update, because hHurricanAverage never gets calculated.

lockers array program VISUAL BASIC

I have to do a program in Visual Basic that displays the status of 100 lockers being either open or closed using a Boolean array. When the button Initialize is clicked, all the lockers should have a status of opened, but when Simulate is clicked, it goes through a process of closing every Nth locker (every 2nd locker, then every 3rd locker, then every 4th locker, and so on).
I have it working so that it always displays opened for every locker, but I can't figure out how to make it close every Nth locker.
Here is my code:
Public Class Form1
Dim index As Integer
Dim doors(100) As Boolean
Private Sub btnInitialize_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnInitialize.Click
Dim count As Integer
lstLockers.Items.Clear()
lstLockers.Items.Add("Locker" & vbTab & "Status")
For count = 1 To 100
doors(count) = True
If doors(count) = True Then
lstLockers.Items.Add(count & vbTab & "Opened")
End If
Next
End Sub
Private Sub btnSimulate_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSimulate.Click
lstLockers.Items.Clear()
lstLockers.Items.Add("Locker" & vbTab & "Status")
Dim count As Integer
Dim eq As Integer
For count = 1 To 100
doors(count) = True
If doors(count) = True Then
lstLockers.Items.Add(count & vbTab & "Opened")
ElseIf doors(count) = False Then
lstLockers.Items.Add(count & vbTab & "Closed")
End If
Next
End Sub
End Class
In your btnSimulate_Click method, you are setting doors index to true and then immediately checking if it is true or not. This is why it always says opened.
Regarding closing every Nth locker, you can do this with a simple counter variable.
' n represents the "Nth" locker to close.
Dim n As Integer = 2
Dim progress As Integer = 0 ' Progress to n.
For count = 1 To 100
' This line shouldn't be here. doors has already been initialized.
'doors(count) = True
' Increment progress towards n.
progress = progress + 1
' Check if Nth interval is reached.
If n = progress Then
' It is. Close the locker.
doors(count) = False
' Increment n and reset the progress counter.
n = n + 1
progress = 0
End If
If doors(count) = True Then
lstLockers.Items.Add(count & vbTab & "Opened")
ElseIf doors(count) = False Then
lstLockers.Items.Add(count & vbTab & "Closed")
End If
Next
This would close lockers:
2 (n = 2)
5 (n = 3)
9 (n = 4)
14 (n = 5)
etc.

Form don't wait for thread finish and hangs my app

This is my app, you can see 3 buttons, start button enabled, pause disabled and stop disabled.
The problem is I have a separated thread in my form to make a "process" (and to print the information in the black richtextbox), and my intention is to can pause it or stop it, but when I launch the thread, the pause button and stop button turns Enabled to disabled in a second.
I can tell the form to wait after launching the thread with a _WaitHandle_FirstThreadDone.WaitOne() and then i can see enabled the pause and the stop buttons, but then the problem is my app hangs until the "process" is done.. so I can't push any button.
Please, I need help to make this...
The important part of my form:
Public Class Form1
#Region "Append text function"
' Append Text
Public Sub AppendText(box As RichTextBox, color As Color, text As String)
Control.CheckForIllegalCrossThreadCalls = False
Dim start As Integer = box.TextLength
box.AppendText(text)
Dim [end] As Integer = box.TextLength
' Textbox may transform chars, so (end-start) != text.Length
box.[Select](start, [end] - start)
If True Then
box.SelectionColor = color
' could set box.SelectionBackColor, box.SelectionFont too.
End If
box.SelectionLength = 0
' clear
End Sub
#End Region
#Region "Thread"
Public _WaitHandle_FirstThreadDone As New System.Threading.AutoResetEvent(False)
Public Sub ThreadProc(ByVal aDir As DirectoryInfo)
Dim aFile As FileInfo
For Each aFile In aDir.GetFiles()
If accepted_extensions.ToLower.Contains(aFile.Extension.ToLower) Then
' print output
AppendText(consolebox, Color.Yellow, "Processing: ")
AppendText(consolebox, Color.White, aFile.ToString() + vbNewLine)
consolebox.ScrollToCaret()
processedfiles += 1
totalfiles_label.Text = "Processed " + processedfiles.ToString() + " of " + totalfiles.ToString() + " total video files"
' MEDIAINFO: (ac3, dts, wav and multitrack)
If ac3 = True Or dts = True Or wav = True Or multitrack = True Then
MI.Open(aFile.FullName)
Dim Pos As Integer = 0
To_Display = Nothing
While Pos < MI.Count_Get(StreamKind.Audio)
' AC-3
If ac3 = True Then
If MI.Get_(StreamKind.Audio, Pos, "Format").ToString() = "AC-3" Then
results_box.AppendText("AC3 Track: " + aFile.FullName.ToString() + vbNewLine)
results_box.SelectionStart = results_box.Text.Length
results_box.ScrollToCaret()
problems += 1
problems_label.Text = problems.ToString() + " problems found"
End If
End If
System.Math.Max(System.Threading.Interlocked.Increment(Pos), Pos - 1)
End While
End If
End If
Next
_WaitHandle_FirstThreadDone.Set()
End Sub
#End Region
#Region "Organize function"
Public Sub MediaInfo(Directory)
Dim MyDirectory As DirectoryInfo
MyDirectory = New DirectoryInfo(NameOfDirectory)
MediaInfoWorkWithDirectory(MyDirectory)
End Sub
Public Sub MediaInfoWorkWithDirectory(ByVal aDir As DirectoryInfo)
Dim nextDir As DirectoryInfo
Dim t As New Threading.Thread(AddressOf ThreadProc)
t.Start(aDir)
'
For Each nextDir In aDir.GetDirectories
If playlist = True Then
Using writer As StreamWriter = New StreamWriter(aDir.FullName & "\" & nextDir.Name & "\" & nextDir.Name & ".m3u", False, System.Text.Encoding.UTF8)
'overwrite existing playlist
End Using
End If
MediaInfoWorkWithDirectory(nextDir)
Next
End Sub
#End Region
#Region "Action buttons"
' start button
Public Sub Button2_Click(sender As Object, e As EventArgs) Handles start_button.Click
consolebox.Clear()
' pause / cancel button ON
start_button.Enabled = False
pause_button.Enabled = True
cancel_button.Enabled = True
' Organization process
NameOfDirectory = userSelectedFolderPath
MediaInfo(NameOfDirectory)
' _WaitHandle_FirstThreadDone.WaitOne()
consolebox.AppendText(vbNewLine + "[+] Organization finalized!" + vbNewLine)
consolebox.Refresh()
consolebox.SelectionStart = consolebox.Text.Length
consolebox.ScrollToCaret()
' pause / cancel button OFF
start_button.Enabled = True
pause_button.Enabled = False
cancel_button.Enabled = False
End Sub
#End Region
Private Sub pause_button_Click(sender As Object, e As EventArgs) Handles pause_button.Click
paused = True
End Sub
End Class
The reason the app hangs is the program is blasting through data sequentially. You should add an if statement inside the part that is looping to check for the pause condition in between processing. Its not a good idea to put the on/off controls inside the subroutine like you have because it can only enable the buttons after everything has completed.
I.E to stop the process
For i to 10 Do
If checkbox1.checked = True then Exit Sub 'check for stop condition
'process videos
Loop
To pause it you could implement a stop but make it remember where to start when resumed.
Also why do you have faces of death? That stuff kills braincells.

Trouble with Timer_tick not stopping

I'm very new to programming and vb.net, trying to self teach more so as a hobby, as I have an idea for a program that I would find useful, but I am having trouble getting past this issue and I believe it is to do with the timer.
I have a form of size.(600,600) with one button of size.(450,150) that is set location(100,50) on the form. When clicked I want to move down it's own height, then add a new button in it's place. The code included below works as desired for the first two clicks, but on the third click the button keeps moving and the autoscroll bar extends. I initially thought it was the autoscroll function or the location property, but realised that as the button keeps moving, the timer hasn't stopped. I am aware that the code is probably very clunky in terms of achieving the outcome, and that there are a few lines/variables that are currently skipped over by the compiler (these are from older attempts to figure this out).
I have looked around and can't find the cause of my problem. Any help would be greatly appreciated. Apologies if the code block looks messy - first go.
Public Class frmOpenScreen
Dim intWButtons, intCreateButtonY, intCreateButtonX 'intTimerTick As Integer
Dim arrWNames() As String
Dim ctrlWButtons As Control
Dim blnAddingW As Boolean
Private Sub btnCreateW_Click(sender As System.Object, e As System.EventArgs) Handles btnCreateW.Click
'Creates new Button details including handler
Dim strWName, strWShort As String
Dim intCreateButtonY2 As Integer
Static intNumW As Integer
Dim B As New Button
strWName = InputBox("Please enter the name name of the button you are creating. Please ensure the spelling is correct.", "Create W")
If strWName = "" Then
MsgBox("Nothing Entered.")
Exit Sub
End If
strWShort = strWName.Replace(" ", "")
B.Text = strWName
B.Width = 400
B.Height = 150
B.Font = New System.Drawing.Font("Arial Narrow", 21.75)
B.AutoSizeMode = Windows.Forms.AutoSizeMode.GrowAndShrink
B.Anchor = AnchorStyles.Top
B.Margin = New Windows.Forms.Padding(0, 0, 0, 0)
'Updates Crucial Data (w name array, number of w buttons inc Create New)
If intNumW = 0 Then
ReDim arrWNames(0)
Else
intNumW = UBound(arrWNames) + 1
ReDim Preserve arrWNames(intNumW)
End If
arrWNames(intNumW) = strWShort
intNumW = intNumW + 1
intWButtons = WButtonCount(intWButtons) + 1
'updates form with new button and rearranges existing buttons
intCreateButtonY = btnCreateW.Location.Y
intCreateButtonX = btnCreateW.Location.X
‘intTimerTick = 0
tmrButtonMove.Enabled = True
‘Do While intTimerTick < 16
‘ 'blank to do nothing
‘Loop
'btnCreateW.Location = New Point(intCreateButtonX, intCreateButtonY + 150)
B.Location = New Point(intCreateButtonX, intCreateButtonY)
Me.Controls.Add(B)
B.Name = "btn" & strWShort
intCreateButtonY2 = btnCreateW.Location.Y
If intCreateButtonY2 > Me.Location.Y Then
Me.AutoScroll = False
Me.AutoScroll = True
Else
Me.AutoScroll = False
End If
'MsgBox(intCreateButtonY)
End Sub
Function WButtonCount(ByRef buttoncount As Integer) As Integer
buttoncount = intWButtons
If buttoncount = 0 Then
Return 1
End If
Return buttoncount
End Function
Public Sub tmrButtonMove_Tick(sender As System.Object, e As System.EventArgs) Handles tmrButtonMove.Tick
Dim intTimerTick As Integer
If intTimerTick > 14 Then
intTimerTick = 0
End If
If btnCreateW.Location.Y <= intCreateButtonY + 150 Then
btnCreateW.Top = btnCreateW.Top + 10
End If
intTimerTick += 1
If intTimerTick = 15 Then
tmrButtonMove.Enabled = False
End If
End Sub
End Class
So my current understanding is that the tick event handler should be increasing the timertick variable every time it fires, and that once it has hits 15 it should diable the timer and stop the button moving, but it is not doing so.
Thanks in advance.
IntTimerTick is initialized to 0 at the beginning of every Tick event. This won't happen if you declare it to be static:
Static Dim intTimerTick As Integer