Risk Game not displaying score - vb6

I'm doing an assignment for my class called "Risk!", the basis of it is that you start with 1000 points, and input a number to risk. You roll 2 dice. If it's even, you lose and the input is removed from score. If it's odd, you win and input is added to score. For some reason, the score isn't displayed correctly.
Private Sub cmdQuit_Click()
Unload Me
End Sub
Private Sub cmdRollDice_Click()
intNumOutput1 = Int(Rnd * 6) + 1
intNumOutput2 = Int(Rnd * 6) + 1
lblNumOutput1.Caption = intNumOutput1
lblNumOutput2.Caption = intNumOutput2
intBothOutputs = intNumOutput1 + intNumOutput2
If intBothOutputs Mod 2 > 0 Then
intScore = intScore + intNumInput
MsgBox "odd, win"
Else
intScore = intScore - intNumInput
MsgBox "even, lose"
End If
lblTotal.Caption = "Your new point total is " & intScore
End Sub
Private Sub Form_Load()
Randomize
Dim intScore As Integer
Dim intNumOutput1 As Integer
Dim intNumOutput2 As Integer
Dim intBothOutputs As Integer
Dim intNumInput As Integer
txtNumInput.Text = intNumInput
intScore = 1000
txtNumInput.Text = ""
lblNumOutput1.Caption = ""
lblNumOutput2.Caption = ""
End Sub

When you want to use variables in more than one method (e.g. sub, function), you declare the variables outside of any method.
Now, since you declared your variables inside Form_Load, you can't use them in cmdRollDice_Click or in any other method. So, what happens when you use them in a method other than the one they were declared in? Well, if you have Option Explicit statement on top of your code, you'll get a run-time error. If you don't (which is your current case), the variables will get initialized -with zero value- each time the method is called (note: they're now not the same variables that were declared in Form_Load).
Hence, you need to declare your variables on top of your file (before all functions/subs) like the following:
Dim intScore As Integer
Dim intNumOutput1 As Integer
Dim intNumOutput2 As Integer
Dim intBothOutputs As Integer
Dim intNumInput As Integer
' The rest of your code
Private Sub Form_Load()
End Sub
Private Sub cmdRollDice_Click()
End Sub
'
'
So, as a rule: you declare variables inside a method ONLY if you don't need to use them outside that method.
For more information about this, read Understanding the Scope of Variables
Hope that helps :)

For string concatenation its best practice to convert data types to string using cstr. e.g. CStr(intScore)
Add the event handler for txtNumInput. You have not assigned the value to intNumInput whenever button is clicked.
Try below.
Option Explicit
Private intScore As Integer
Private intNumOutput1 As Integer
Private intNumOutput2 As Integer
Private intBothOutputs As Integer
Private intNumInput As Integer
Private Sub cmdRollDice_Click()
Dim intNumOutput1 As Integer
Dim intNumOutput2 As Integer
Dim intBothOutputs As Integer
intNumOutput1 = Int(Rnd * 6) + 1
intNumOutput2 = Int(Rnd * 6) + 1
lblNumOutput1.Caption = intNumOutput1
lblNumOutput2.Caption = intNumOutput2
intBothOutputs = intNumOutput1 + intNumOutput2
If intBothOutputs Mod 2 > 0 Then
intScore = intScore + intNumInput
MsgBox "odd, win"
Else
intScore = intScore - intNumInput
MsgBox "even, lose"
End If
lblTotal.Caption = "Your new point total is " & CStr(intScore)
End Sub
Private Sub txtNumInput_Change()
If IsNumeric(txtNumInput.Text) Then
intNumInput = CInt(txtNumInput.Text)
End If
End Sub

Related

VB6 Converting a fraction to a decimal and a decimal to fraction

There's a few posts on this, but none seem to provide a whole code solution, so I'm posting this up, which is culled (and credited where appropriate) from various bits and pieces of ideas on the Internet. VB6 doesn't have any function to convert from a fraction to a decimal number, which I needed for a project that I was working on which was concerned with meal recipes. I considered writing a DLL in .NET and plugging it into my application, but decided on this approach in the end. I hope this is useful for others. The solution below will do the following:
You supply a decimal number and you will be returned the fraction as a string.
You supply a fraction as a string and you will be returned with the decimal number.
In both cases, whole numbers are accounted for eg. "2 3/4" (two and three quarters) or "2.75".
I'm sure the code is not efficient, so any improvements are welcome.
Copy/Paste this as a new Class module:
Option Explicit
Private ErrorNote As String
'Properties
Public Property Get GetAsFraction(numToConvert As Double) As String
On Error GoTo GetAsFraction_Error
GetAsFraction = FncGetAsFraction(numToConvert)
On Error GoTo 0
Exit Property
GetAsFraction_Error:
ErrorNote = "Number:" & Err.number & " (" & Err.Description & ") in procedure 'GetAsFraction' in 'ClsFractionDecimal'"
MsgBox (ErrorNote)
End Property
Public Property Get GetAsDecimal(fractionString As String) As Double
On Error GoTo GetAsDecimal_Error
GetAsDecimal = FncGetAsDecimal(fractionString)
On Error GoTo 0
Exit Property
GetAsDecimal_Error:
ErrorNote = "Number:" & Err.number & " (" & Err.Description & ") in procedure 'GetAsDecimal' in 'ClsFractionDecimal'"
MsgBox (ErrorNote)
End Property
'Functions - private
Private Function FncGetAsDecimal(fractionToConvert As String) As Double
Dim result As Double
Dim wholeNumber As Integer
Dim splitStr As Variant
Dim numerator As Integer
Dim denominator As Integer
Dim fractionString As String
Dim dividedByPos As Integer
On Error GoTo FncGetAsDecimal_Error
splitStr = Split(fractionToConvert, " ")
If UBound(splitStr) = 1 Then
wholeNumber = splitStr(0)
fractionString = splitStr(1)
Else
fractionString = splitStr(0)
End If
dividedByPos = InStr(1, fractionString, "/")
numerator = Left(fractionString, dividedByPos - 1)
denominator = Mid(fractionString, dividedByPos + 1)
result = Val(numerator) / Val(denominator) + wholeNumber
FncGetAsDecimal = result
On Error GoTo 0
Exit Function
FncGetAsDecimal_Error:
ErrorNote = "Number:" & Err.number & " (" & Err.Description & ") in procedure 'FncGetAsDecimal' in 'ClsFractionDecimal'"
MsgBox (ErrorNote)
End Function
Private Function FncGetAsFraction(numToConvert As Double) As String
Dim result As String
Dim numeratorCount As Integer
Dim denominator As Single
Dim multiplierStr As String
Dim i As Integer
Dim fractionNum As Single
Dim lowestCommonDenominator As Long
Dim wholeNumber As Integer
Dim decimalPos As Integer
On Error GoTo FncGetAsFraction_Error
If numToConvert > 0 Then
decimalPos = InStr(1, CStr(numToConvert), ".")
If decimalPos > 1 Then
wholeNumber = CStr(Mid(numToConvert, 1, decimalPos - 1))
numToConvert = CStr(Mid(numToConvert, decimalPos))
End If
numeratorCount = FncCountDecimalPlaces(numToConvert)
multiplierStr = "1"
For i = 1 To numeratorCount
multiplierStr = multiplierStr & "0"
Next i
fractionNum = numToConvert * Val(multiplierStr)
denominator = 1 * Val(multiplierStr)
result = FncCrunchFraction(fractionNum, denominator)
If result = "" Then result = fractionNum & "/" & denominator
If wholeNumber <> 0 Then result = wholeNumber & " " & result
Else
result = "ERROR"
End If
FncGetAsFraction = result
On Error GoTo 0
Exit Function
FncGetAsFraction_Error:
ErrorNote = "Number:" & Err.number & " (" & Err.Description & ") in procedure 'FncGetAsFraction' in 'ClsFractionDecimal'"
MsgBox (ErrorNote)
End Function
Private Function FncCountDecimalPlaces(num As Double) As Integer
Dim result As Integer
Dim numberStr As String
Dim i As Integer
Dim decimalPointPos As Integer
On Error GoTo FncCountDecimalPlaces_Error
numberStr = CStr(num)
If Len(numberStr) > 0 Then
i = 1
Do While i <= Len(numberStr) And decimalPointPos = 0
If Mid(numberStr, i, 1) = "." Then decimalPointPos = i
i = i + 1
Loop
End If
If i > 1 Then
result = (Len(numberStr) - i + 1)
End If
FncCountDecimalPlaces = result
On Error GoTo 0
Exit Function
FncCountDecimalPlaces_Error:
ErrorNote = "Number:" & Err.number & " (" & Err.Description & ") in procedure 'FncCountDecimalPlaces' in 'ClsFractionDecimal'"
MsgBox (ErrorNote)
End Function
'Credit to:
'http://www.tek-tips.com/viewthread.cfm?qid=206890
'dsi (Programmer) - 7 Feb 02 10:38
Private Function FncCrunchFraction(num1 As Single, num2 As Single) As String
Dim num As Single
Dim dem As Single
Dim cnt1 As Integer
Dim cnt2 As Integer
Dim numFactors() As Single
Dim demFactors() As Single
Dim common As Single
Dim i As Integer
Dim j As Integer
On Error GoTo FncCrunchFraction_Error
num = num1
dem = num2
For i = 2 To Int(num / 2) Step 1
If (num Mod i = 0) Then
cnt1 = cnt1 + 1
ReDim Preserve numFactors(1 To cnt1)
numFactors(cnt1) = i
End If
Next i
cnt1 = cnt1 + 1
ReDim Preserve numFactors(1 To cnt1)
numFactors(cnt1) = num
For i = 2 To Int(dem / 2) Step 1
If (dem Mod i = 0) Then
cnt2 = cnt2 + 1
ReDim Preserve demFactors(1 To cnt2)
demFactors(cnt2) = i
End If
Next i
cnt2 = cnt2 + 1
ReDim Preserve demFactors(1 To cnt2)
demFactors(cnt2) = dem
For i = cnt1 To 1 Step -1
For j = cnt2 To 1 Step -1
If (numFactors(i) = demFactors(j)) Then
common = numFactors(i)
FncCrunchFraction = num / common & "/" & dem / common
Exit Function
End If
Next j
Next i
FncCrunchFraction = ""
On Error GoTo 0
Exit Function
FncCrunchFraction_Error:
ErrorNote = "Line:" & Erl & " Number:" & Err.number & " (" & Err.Description & ") in procedure 'FncCrunchFraction' in 'ClsFractionDecimal'"
MsgBox (ErrorNote)
End Function
Then call it with these code examples:
Public Function DecimalToFraction(number As Double) As String
Dim myFractionDecimal As New ClsFractionDecimal
DecimalToFraction = myFractionDecimal.GetAsFraction(number)
Set myFractionDecimal = Nothing
End Function
Public Function FractionToDecimal(fractionString As String) As Double
Dim myFractionDecimal As New ClsFractionDecimal
FractionToDecimal = myFractionDecimal.GetAsDecimal(fractionString)
Set myFractionDecimal = Nothing
End Function

radomly add strings to this code i have

text1.text = "Mayweather vs McGregor: Los Angeles Press Conference"
text2.text returns count of space.
my custom value say = "love"
now on each button click , i want to randomly add that custom string to each position the space.
so first click
text1.text = "Mayweather vs love McGregor: Los Angeles Press Conference"
second click
text1.text = "Mayweather vs McGregor: ;love Los Angeles Press Conference"
and so on depending on the code were it detects the space then add it their only once per click.
Code:
Dim Count As Integer
Dim i As Integer
For i = 1 To Len(Text1.Text)
If Mid(Text1.Text, i, 1) = " " Then Count = Count + 1
Text2.Text = Count
Next
Here is a small test project:
Option Explicit
' 1 form with:
' 2 textbox controls: name=Text1 and name=Text2
' 1 command button : name=Command1
Private mstrText As String
Private Sub Command1_Click()
Static intCount As Integer 'declare as static to remember value of intCount on next click
Dim intLoop As Integer
Dim intSpace As Integer
intCount = intCount + 1
'find correct space
intLoop = 0
intSpace = 0
Do While intLoop < intCount
intSpace = InStr(intSpace + 1, mstrText, " ")
intLoop = intLoop + 1
Loop
Text1.Text = Left$(mstrText, intSpace) & "love " & Mid$(mstrText, intSpace + 1)
Caption = CStr(intSpace)
End Sub
Private Sub Form_Load()
mstrText = "Mayweather vs McGregor: Los Angeles Press Conference"
Text1.Text = mstrText
End Sub
Private Sub Text1_Change()
'show number of spaces
Dim intSpace As Integer
intSpace = Len(Text1.Text) - Len(Replace(Text1.Text, " ", ""))
Text2.Text = CStr(intSpace)
End Sub
Is this what you mean?

Iterate through a treeview in VB6

I have a treeview control on the form which looks like:
I want to iterate the treeview and write the contents of the treeview to ini file. So the ini file for the given tree would look like:
[EnvironmentSystem]
UpdateRate=50.0
InclinationAngle=20.7
Latitude=34.0
[Reflection]
NumReflectionLevel=5
NumSunLightLevel=5
NumWeatherLevel=3
TextureNameFormat=Reflection%01d%01d%02d.tga
[CloudsClear]
MaxClouds=48
MaxCloudParticles=51
3DCloudMaterial=CloudMaterial
3DCloudHorizontalSize=1400.0
3DCloudVerticalSize=600.0
3DCloudSizeDeviation=0.6
3DCloudParticleDensity=2.4
ParticleSize=300.0
ParticleSizeDeviation=0.3
MinBaseAltitude=400.0
MaxBaseAltitude=2450.0
UseBottomRow=TRUE
Here is the code that I have written:
Private Sub TvSaveToIniBtn_Click()
Dim nodx As Node
Dim i As Long
Dim sectionCount As Integer
sectionCount = TreeView1.Nodes(1).Children
Set nodx = TreeView1.Nodes(1).Child.FirstSibling
For i = 1 To sectionCount
SaveNodesToIni (nodx.Text)
Set nodx = nodx.Next
Next
End Sub
Sub SaveNodesToIni(sName As Variant)
Dim tvn As Node
Set tvn = TreeView1.Nodes(sName)
Dim chil As Integer
Dim a As Integer
Dim ret As Integer
Dim keyValuePair() As String
Dim nElements As Integer
chil = tvn.Children: If chil = 0 Then Exit Sub ' if no children the exit
Set tvn = tvn.Child.FirstSibling
For a = 1 To chil
keyValuePair = Split(tvn.Text, "=")
nElements = UBound(keyValuePair) - LBound(keyValuePair) + 1
If nElements > 0 Then
ret = WritePrivateProfileString(sName, keyValuePair(0), keyValuePair(1), "C:\\MyPrograms\\config.ini")
End If
Set tvn = tvn.Next
Next
End Sub
It is not giving the correct output, it gets stuck at the second section of reflection and is not able to read the third one. Something wrong with the code.

How to reduce the decimal length

I want to reduce the decimal length
text1.text = 2137.2198231578
From the above, i want to show only first 2 digit decimal number
Expected Output
text1.text = 2137.21
How to do this.
Format("2137.2198231578", "####.##")
I was about to post use Format() when I noticed p0rter comment.
Format(text1.text, "000.00")
I guess Int() will round down for you.
Been many years since I used VB6...
This function should do what you want (inline comments should explain what is happening):
Private Function FormatDecimals(ByVal Number As Double, ByVal DecimalPlaces As Integer) As String
Dim NumberString As String
Dim DecimalLocation As Integer
Dim i As Integer
Dim LeftHandSide As String
Dim RightHandSide As String
'convert the number to a string
NumberString = CStr(Number)
'find the decimal point
DecimalLocation = InStr(1, NumberString, ".")
'check to see if the decimal point was found
If DecimalLocation = 0 Then
'return the number if no decimal places required
If DecimalPlaces = 0 Then
FormatDecimals = NumberString
Exit Function
End If
'not a floating point number so add on the required number of zeros
NumberString = NumberString & "."
For i = 0 To DecimalPlaces
NumberString = NumberString & "0"
Next
FormatDecimals = NumberString
Exit Function
Else
'decimal point found
'split out the string based on the location of the decimal point
LeftHandSide = Mid(NumberString, 1, DecimalLocation - 1)
RightHandSide = Mid(NumberString, DecimalLocation + 1)
'if we don't want any decimal places just return the left hand side
If DecimalPlaces = 0 Then
FormatDecimals = LeftHandSide
Exit Function
End If
'make sure the right hand side if the required length
Do Until Len(RightHandSide) >= DecimalPlaces
RightHandSide = RightHandSide & "0"
Loop
'strip off any extra didgits that we dont want
RightHandSide = Left(RightHandSide, DecimalPlaces)
'return the new value
FormatDecimals = LeftHandSide & "." & RightHandSide
Exit Function
End If
End Function
Usage:
Debug.Print FormatDecimals(2137.2198231578, 2) 'outputs 2137.21
Looks fairly simple, but I must be missing something subtle here. What about:
Option Explicit
Private Function Fmt2Places(ByVal Value As Double) As String
Fmt2Places = Format$(Fix(Value * 100#) / 100#, "0.00")
End Function
Private Sub Form_Load()
Text1.Text = Fmt2Places(2137.2198231578)
End Sub
This also works in locales where the decimal point character is a comma.

How to give a name to each list item in Visual Basic 6

I am making a music player using the list control. I want to let the user change the name of the song on the list, but i want some property of THAT list item to contain its path.
Please help me in this. Any kind of help will be appreciated. Thanks in advance.
EDIT
Private Sub AddToList(ByVal txtFileName As String)
Dim I As Integer
Dim blnFileAlreadyexists As Boolean
txtFileName = Trim(txtFileName)
If txtFileName <> "" Then
blnFileAlreadyexists = False
For I = 0 To List1.ListCount - 1
If Trim(List1.List(I)) = txtFileName Then
blnFileAlreadyexists = True
End If
Next
If Not blnFileAlreadyexists Then
List1.AddItem (txtFileName)
List1.ItemData (txtFileName)
End If
End If
End Sub
For a listbox, after you add an item set its x.itemdata(x.newindex) to the index of an array (or UDT array) that contains the corresponding data.
For a listview you can similarly use an individual items .Tag or .Key to store an array (or collection) index.
Linking a listbox example;
Option Explicit
Private Type TFileData
OriginalFilePath As String
ListBoxIndex As Integer
MoreBlaBla As String
'//any more members
End Type
Private maFiles() As TFileData
Private Sub Form_Load()
'//initial alloc
ReDim maFiles(0)
AddToList "AAAA"
AddToList "BBBB"
AddToList "AAAA"
AddToList "CCCC"
'//test by looping listbox;
Dim i As Integer
For i = 0 To List1.ListCount - 1
MsgBox List1.List(i) & " - " & maFiles(List1.ItemData(i)).OriginalFilePath
Next
'// a better type centric test;
For i = 0 To UBound(maFiles) - 1
MsgBox maFiles(i).OriginalFilePath & " - List entry: " & List1.List(maFiles(i).ListBoxIndex)
Next
End Sub
Private Sub AddToList(ByVal txtFileName As String)
Dim i As Integer
Dim blnFileAlreadyexists As Boolean
txtFileName = Trim(txtFileName)
If txtFileName <> "" Then
blnFileAlreadyexists = False
For i = 0 To List1.ListCount - 1
If Trim(List1.List(i)) = txtFileName Then
blnFileAlreadyexists = True
End If
Next
If Not blnFileAlreadyexists Then
'//add to list
List1.AddItem (txtFileName)
'//store the original value in the array;
maFiles(UBound(maFiles)).OriginalFilePath = "TEST: " & txtFileName
'//store the index of the array in the list;
List1.ItemData(List1.NewIndex) = UBound(maFiles)
'//or better store in the type
maFiles(UBound(maFiles)).ListBoxIndex = List1.NewIndex
'//increment the array for the next item;
ReDim Preserve maFiles(UBound(maFiles) + 1)
End If
End If
End Sub

Resources