Pictures wont become visible - vb.net

So today in my Computer Programming Class, we created a project called CaseStudy. I saw a way to make the program have more replay value. I decided to morph the code and interface to be like a Hangman game. I've got the limbs to appear, but only after clicking Ok on the messageBox.
I'm wondering if anyone has a way to make these limbs appear in real time.
Here is the important code:
Dim SECRET_WORD As String = newSecretWord
Const FLAG As Char = "!"
Const GUESS_PROMPT As String = "Enter a letter or " & FLAG & " to guess word:"
Dim numGuesses As Integer = 0
Dim letterGuess As Char
Dim wordGuess As String
Dim tempWord As String
Dim endGame As Boolean
Dim wordGuessedSoFar As String = ""
Dim lenght As Integer = SECRET_WORD.Length
wordGuessedSoFar = wordGuessedSoFar.PadLeft(lenght, "_")
Me.lblSecretWord.Text = wordGuessedSoFar
Dim tempLetterGuess = InputBox(GUESS_PROMPT, Me.Text)
If tempLetterGuess = Nothing Then
endGame = True
Else
letterGuess = tempLetterGuess
End If
Do While letterGuess <> FLAG And wordGuessedSoFar <> SECRET_WORD And Not endGame
numGuesses += 1
For letterPos As Integer = 0 To SECRET_WORD.Length - 1
If SECRET_WORD.Chars(letterPos) = Char.ToUpper(letterGuess) Then
tempWord = wordGuessedSoFar.Remove(letterPos, 1)
wordGuessedSoFar = tempWord.Insert(letterPos, Char.ToUpper(letterGuess))
Me.lblSecretWord.Text = wordGuessedSoFar
End If
Next letterPos
If wordGuessedSoFar <> SECRET_WORD Then
tempLetterGuess = InputBox(GUESS_PROMPT, Me.Text)
If tempLetterGuess = Nothing Then
endGame = True
Else
letterGuess = tempLetterGuess
End If
End If
Loop
If wordGuessedSoFar = SECRET_WORD Then
MessageBox.Show("You guessed it in " & numGuesses & " guesses!")
ElseIf letterGuess = FLAG Then
wordGuess = InputBox("Enter a word: ", Me.Text)
If wordGuess.ToUpper = SECRET_WORD Then
MessageBox.Show("You guessed it in " & numGuesses & " guesses!")
Me.lblSecretWord.Text = SECRET_WORD
Else
MessageBox.Show("Sorry, you lose.")
End If
Else
MessageBox.Show("Game over.")
lblSecretWord.Text = Nothing
End If
Dim place As Integer = SECRET_WORD.Length - 1
If tempLetterGuess <> SECRET_WORD.Chars(place) Then
numWrong += 1
End If
If numWrong = 1 Then
picHead.Visible = True
End If
If numWrong = 2 Then
picBody.Visible = True
End If
End Sub
End Class
I can take any other pictures if you'd like.

If I'm understanding you right, you want to show your "pictures" before the user sees the message. If so, you need to move the following code to an area just before your MessageBox and just after the InputBox:
Dim place As Integer = SECRET_WORD.Length - 1
If tempLetterGuess <> SECRET_WORD.Chars(place) Then
numWrong += 1
End If
If numWrong = 1 Then
picHead.Visible = True
End If
If numWrong = 2 Then
picBody.Visible = True
End If

Related

Storage issue with linked list VB.NET

i am using vb.net to create a linked list, and am finding an issue with storage. the second to last value entered is always deleted. i believe this issue is in the Add() subroutine, but i cant figure out how this is caused, or how to fix it. attached is the code and ss of the console. console output
Module Program
Structure linkedList
Dim item As String
Dim position As Integer
Dim pointer As Decimal
Dim isEmpty As Boolean
End Structure
Dim tail As Integer
Dim input As String
Dim list(30) As linkedList
Dim index As Integer
Const head As Integer = 0
Dim menuChoice As Integer
Sub Main()
For i = 0 To list.Length - 1 : list(i).isEmpty = True : Next
menu()
End Sub
Sub menu()
Do
Try
Console.WriteLine("Press 1 to add values, 2 to remove them.")
menuChoice = Console.ReadLine
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Loop Until menuChoice = 1 Or menuChoice = 2
Select Case menuChoice
Case 1
add()
Case 2
remove()
End Select
End Sub
Sub add()
list(0).position = -1
list(0).item = "Head"
index = 1
Do
Console.WriteLine("Enter a value to enter into the linked list, or press X to stop: ")
input = Console.ReadLine
If input <> "X" And input <> vbNullString Then
For i = 0 To list.Length - 1
If list(i).isEmpty = True Then
list(i + 1).item = input
list(i + 1).position = index
list(i + 1).pointer = index + 1
list(i).isEmpty = False
Exit For
End If
Next
End If
list(0).pointer = findNextAvailable(0)
If input <> "X" Then : index += 1 : End If
If input = "X" Then
tail = index
End If
Loop Until input = "X" Or index = 30
showList()
End Sub
Sub remove()
Dim checked As Boolean = False
Dim removString As String
Dim removPos As Integer
Dim removPoint As Integer
Dim num1 As Integer
Do
Try
Console.WriteLine("Enter a string to remove from the Linked List:")
removString = Console.ReadLine.Trim
For i = 0 To list.Length - 1
If list(i).item = removString Then
checked = True
removPos = i
num1 = i - 1
list(i).isEmpty = True
Exit For
Else
checked = False
list(i).isEmpty = False
End If
Next
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Loop Until checked = True
list(removPos).item = vbNullString
list(removPos).pointer = fixPointer(num1)
list(num1).pointer = findPos(removPos)
showList()
End Sub
Function findPos(start As Integer) As Integer
Dim check As Boolean
Dim num1 As Integer
For i = start To list.Length - 1
If list(i).item <> vbNullString Then
check = True
num1 = i - 1
Exit For
End If
Next
If check = True Then
Return num1
Else
Return vbNullString
End If
End Function
Function findNextAvailable(startPoint As Integer) As Integer
Dim nextAvailableTrue As Boolean
Dim num1 As Integer
For i = startPoint To 0 Step -1
If list(i).item <> vbNullString Then
nextAvailableTrue = True
num1 = i
Exit For
End If
Next
If nextAvailableTrue Then
Return num1 + 1
Else
Return startPoint + 1
End If
End Function
Function fixPointer(r As Integer) As Integer
Dim i As Integer = 0
Dim check As Boolean = False
Do
If list(i).item <> vbNullString Then
check = True
End If
i += 1
Loop Until check = True
For x = 0 To list.Length - 1
If list(x).pointer <> vbNull And list(x).item = vbNullString Then
list(x).pointer = vbNull
End If
Next
list(r).pointer = list(i).position
Return list(r).pointer
End Function
Sub showList()
Dim lastPosition As Integer = 0
For x = 0 To list.Length - 1
If list(x).isEmpty Then
list(x).pointer = 0
list(x).position = x
End If
If list(x).isEmpty = False Then
lastPosition = list(x).position
End If
Next
list(lastPosition).item = vbNullString
list(lastPosition).pointer = 0.0
For i = 0 To list.Length - 1
Console.WriteLine($"{list(i).position} ¦ {list(i).item} ¦ {list(i).pointer}")
Next
Console.ReadLine()
menu()
End Sub
End Module

DataTable.Delete() Removing rows before Accept Changes

I'm having an issue where I mark several rows for deletion within a loop, but when it gets to a certain point in the loop, the rows actually start to be removed.
As you can see what I'm basically doing is checking if the row needs to be deleted and if so, add it to a new table and delete it.
The problem is this works for the first 60 ish rows, then all of a sudden the rows appear to actually be removed and it eventually throws a row with that index doesn't exist error (at 65).
The original table is a list of contacts with firstname, lastname, email and company, with 70 records.
I tried to cut the list in half, but then the issue started happening at around row 23.
dtSelectCompany = dt_data.Clone
Dim s_company As String
Dim b_add As Boolean
Dim dtCompanies As Data.DataTable
For i = 0 To dt_data.Rows.Count - 1
b_add = False
s_company = dt_data.Rows(i).Item(columnsDictionary("company")).ToString
If s_company = "" Then : b_add = True
Else
dtCompanies = crm_functions.getCompaniesByName(s_company.Replace(" ", "%"))
If dtCompanies.Rows.Count > 1 Then : b_add = True
ElseIf dtCompanies.Rows.Count = 1 Then
dt_data.Rows(i).Item(columnsDictionary("company")) = dtCompanies.Rows(0).Item("id")
Else : b_add = True
End If
End If
If b_add Then
Dim temp_row As Data.DataRow = dtSelectCompany.NewRow
temp_row.ItemArray = dt_data.Rows(i).ItemArray.Clone()
temp_row.Item("fullName") = temp_row.Item(columnsDictionary("firstname")) & " " & temp_row.Item(columnsDictionary("lastname"))
dtSelectCompany.Rows.Add(temp_row)
dt_data.Rows(i).Delete()
End If
Next
Instead of a counter, use a datarow, for example:
dtSelectCompany = dt_data.Clone
Dim s_company As String
Dim b_add As Boolean
Dim dtCompanies As Data.DataTable
Dim MyDataRow as DataRow
For Each MyDataRow IN dt_data.Rows
b_add = False
s_company = MyDataRow("company").ToString
If s_company = "" Then : b_add = True
Else
' not sure what crm_functions is, so left this alone
dtCompanies = crm_functions.getCompaniesByName(s_company.Replace(" ", "%"))
If dtCompanies.Rows.Count > 1 Then : b_add = True
ElseIf dtCompanies.Rows.Count = 1 Then
MyDataRow("company")) = dtCompanies.Rows(0).Item("id")
Else : b_add = True
End If
End If
If b_add Then
Dim temp_row As Data.DataRow = dtSelectCompany.NewRow
temp_row = MyDataRow
temp_row.Item("fullName") = temp_row.Item(columnsDictionary("firstname")) & " " & temp_row.Item(columnsDictionary("lastname"))
dtSelectCompany.Rows.Add(temp_row)
MyDataRow.Delete()
End If
Next
Wrote this off the top of my head, so .....

Using MailMessage with semi cologn seperation

If I manually put my address in for EmailMessage.To.Add(GetDelimitedField(x, strEmailRep, ";")) It sends me the message just fine. However If I use the code as is below which is using a list that looks like ;email1#mail.com;email2.mail.com
Then it gives an error that email address cannot be blank
Somewhere in GetDelimitedField is erasing addresses. I'm not sure where the problem is actually occurring. Here is all the code involved with this.
strmsg = "LOW STOCK ALERT: Component (" & rsMPCS("MTI_PART_NO") & ") has reached or fallen below it's minimum quantity(" & rsMPCS("MIN_QTY") & ")."
Dim EmailMessage As MailMessage = New MailMessage
EmailMessage.From = New MailAddress("noreply#mail.com")
For x = 1 To GetCommaCount(strEmailRep) + 1
EmailMessage.To.Add(GetDelimitedField(x, strEmailRep, ";"))
Next
EmailMessage.Subject = ("LOW STOCK ALERT!")
EmailMessage.Body = strmsg
EmailMessage.Priority = MailPriority.High
EmailMessage.IsBodyHtml = True
Dim smtp As New SmtpClient("smtp.mycompany.com")
smtp.UseDefaultCredentials = True
smtp.Send(EmailMessage)
Public Function GetCommaCount(ByVal sText As String)
Dim X As Integer
Dim Count As Integer
Dim Look As String
For X = 1 To Len(sText)
Look = Microsoft.VisualBasic.Left(sText, X)
If InStr(X, Look, ";", 1) > 0 Then
Count = Count + 1
End If
Next
GetCommaCount = Count
End Function
Public Function GetDelimitedField(ByRef FieldNum As Short, ByRef DelimitedString As String, ByRef Delimiter As String) As String
Dim NewPos As Short
Dim FieldCounter As Short
Dim FieldData As String
Dim RightLength As Short
Dim NextDelimiter As Short
If (DelimitedString = "") Or (Delimiter = "") Or (FieldNum = 0) Then
GetDelimitedField = ""
Exit Function
End If
NewPos = 1
FieldCounter = 1
While (FieldCounter < FieldNum) And (NewPos <> 0)
NewPos = InStr(NewPos, DelimitedString, Delimiter, CompareMethod.Text)
If NewPos <> 0 Then
FieldCounter = FieldCounter + 1
NewPos = NewPos + 1
End If
End While
RightLength = Len(DelimitedString) - NewPos + 1
FieldData = Microsoft.VisualBasic.Right(DelimitedString, RightLength)
NextDelimiter = InStr(1, FieldData, Delimiter, CompareMethod.Text)
If NextDelimiter <> 0 Then
FieldData = Microsoft.VisualBasic.Left(FieldData, NextDelimiter - 1)
End If
GetDelimitedField = FieldData
End Function
You can split the list easier using string.Split:
Dim strEmails = "a#test.com;b#test.com;c#test.com;"
Dim lstEmails = strEmails.Split(";").ToList()
'In case the last one had a semicolon:
If (lstEmails(lstEmails.Count - 1).Trim() = String.Empty) Then
lstEmails.RemoveAt(lstEmails.Count - 1)
End If
If (lstEmails.Count > 0) Then
lstEmails.AddRange(lstEmails)
End If

Visual Basic Split() returning null

Code for reading and splitting from file:
Public Sub LoadAccount()
currentfilereader = New StreamReader(filename)
Dim Seperator As Char = " "c
For count As Integer = 0 To NumUsers - 1
textstring = currentfilereader.ReadLine
Dim words() As String = currentfilereader.ReadLine.Split(Seperator)
Username = words(0)
Password = words(1)
If words(2) = "1" Then
AccessGranted = True
Else
AccessGranted = False
End If
Users(count, 0) = Username
Users(count, 1) = Password
Users(count, 2) = AccessGranted
Next
currentfilereader.Close()
End Sub
Code for logging in:
Public Sub Login()
Dim InvalidUsername, InvalidPassword As Boolean
InvalidUsername = True
InvalidPassword = True
LoginName = Form1.tbun.Text
LoginPassword = Form1.tbpw.Text
For count As Integer = 0 To NumUsers - 1
If LoginName = Users(count, 0) Then
InvalidUsername = False
If LoginPassword = Users(count, 1) Then
InvalidPassword = False
CurrentUsername = LoginName
CurrentPassword = LoginPassword
CurrentAccessGranted = Users(count, 2)
loggedin = True
Else
MsgBox("Invalid Password")
End If
Else
MsgBox("Invalid Username")
End If
Next
End Sub
Code for calculating number of users:
Public Sub NumberOfUsers()
currentfilereader = New StreamReader(filename)
NumUsers = File.ReadAllLines("Accounts.txt").Length
MsgBox("There are " & NumUsers & " users")
End Sub
I have added a MsgBox to show the number of users to make sure all is working fine which returns the value of 2, since I currently have 2 lines in the text file, "a a 1" and "b b 1".
However when this line runs, Dim words() As String = currentfilereader.ReadLine.Split(Seperator), it returns null.
The purpose of subtracting 1 from the NumUsers in the count is since the count starts at zero along with the array. Meaning that if I didn't it would check 3 times if there is only 2 users in the file. But I just can't seem to figure out what is wrong and why it is returning null.
You call ReadLine twice for each user:
textstring = currentfilereader.ReadLine
Dim words() As String = currentfilereader.ReadLine.Split(Seperator)
This means that for the first user you read both lines, and for the second user you read nothing, leading to the empty split array.
Replace
Dim words() As String = currentfilereader.ReadLine.Split(Seperator)
With
Dim words() As String = textstring.Split(Seperator)

Hangman vb.net only first letter showing

Basically I generate a random word for example
"Tree" and when I press the T button it changes the label into a T but then when I choose R it doesnt show, can someone else see what i've done wrong?
here is my code
Sub GuessLetter(ByVal LetterGuess As String)
Dim strGuessedSoFar As String = Lbltempword.Text
Dim LengthOfSecretWord As Integer
LengthOfSecretWord = secret.Length - 1
tempWord = ""
Dim letterPosition As Integer
For letterPosition = 0 To LengthOfSecretWord
If secret.Substring(letterPosition, 1) = LetterGuess Then
tempWord = tempWord & LetterGuess
Else
tempWord = tempWord & Lbltempword.Text.Substring(letterPosition, 1)
End If
Next
Lbltempword.Text = tempWord
If Lbltempword.Text = secret Then 'YOU WIN
DisableButtons()
BtnStart.Enabled = True
MsgBox("YOU WIN")
End If
If Lbltempword.Text = strGuessedSoFar Then
NumWrong = NumWrong + 1
End If
DisplayHangman(NumWrong)
End Sub
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnStart.Click
randomword()
MsgBox(secret)
EnableButtons()
BtnStart.Enabled = False
'Load up the temp word label with dashes
Secret_Word = secret
LoadLabelDisplay()
NumWrong = 0
DisplayHangman(NumWrong)
End Sub
Sub LoadLabelDisplay()
Lbltempword.Text = ""
Dim LengthOfSecretWord As Integer
LengthOfSecretWord = secret.Length - 1
Dim LetterPosition As Integer
For LetterPosition = 0 To LengthOfSecretWord
Lbltempword.Text = Lbltempword.Text & "-"
Next
End Sub
I also generate the random words by doing this.
Sub randomword()
Dim RAND(16)
Dim rng As New System.Random()
For i = 0 To 16
RAND(0) = "Tree"
RAND(1) = "Star"
RAND(2) = "Jesus"
RAND(3) = "Present"
RAND(4) = "advent"
RAND(5) = "Calender"
RAND(6) = "Jinglebell"
RAND(7) = "skint"
RAND(8) = "lapland"
RAND(9) = "Santa"
RAND(10) = "raindeer"
RAND(11) = "Cookies"
RAND(12) = "Milk"
RAND(13) = "nothing"
RAND(14) = "play"
RAND(15) = "sack"
Next
secret = RAND(rng.Next(RAND.Count()))
End Sub