Removing value from a List in VB - vb.net

I'm making a 'Deal or No Deal' type game for a project in Visual Basic 2008.
I'm having a problem assigning the 5 values randomly to 5 boxes.
For example, in one game, the boxes could hold these values:
Box 1 = 1000
Box 2 = 35000
Box 3 = 25000
Box 4 = 75000
Box 5 = 5000
and in another game, they could hold these values
Box 1 = 75000
Box 2 = 25000
Box 3 = 1000
Box 4 = 5000
Box 5 = 35000
The main aim is to randomly assign these values to each box, and once a value has been assigned, it cannot be assigned to another box at the same time.
Here is the code that I have at the moment:
Dim values As New List(Of Integer)
Dim box(4) As Integer
Dim randNum(4) As Integer
'adding values to the Value list
values.Add(1000)
values.Add(5000)
values.Add(25000)
values.Add(35000)
values.Add(75000)
Dim i As Integer
For i = 0 To 4
Dim RandomClass As New Random()
Dim RandomNumber As Integer
RandomNumber = RandomClass.Next(0, 4)
'assigning a box a random value form the list
box(i) = values(RandomNumber)
'removing that value from the list
values.RemoveAt(i)
Next
Console.WriteLine("Box 1 = " & box(0))
Console.WriteLine("Box 2 = " & box(1))
Console.WriteLine("Box 3 = " & box(2))
Console.WriteLine("Box 4 = " & box(3))
Console.WriteLine("Box 5 = " & box(4))
Console.Read()
VB keeps returning this error message when I try t run the application:
Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index
Thanks in advance for any answers.

When you remove an item, the length of the list gets smaller. So on the second loop, index of 4 no longer exists. On the third loop, 3 no longer exists and so on. Try this instead:
Dim RandomClass As New Random()
Dim RandomNumber As Integer
For i = 0 To 4
RandomNumber = RandomClass.Next(0, values.count - 1)
'assigning a box a random value form the list
box(i) = values(RandomNumber)
'removing that value from the list
values.RemoveAt(i)
Next

The answer from Steve prevents the error from occurring, but I think it's still not doing quite what you want. values.RemoveAt(i) will always remove the first item from the list the first time, the second, next time, etc... it is not removing the value that you have just put in the box. To do that you should use values.RemoveAt(RandomNumber) instead.
For i = 0 To 4
RandomNumber = RandomClass.Next(0, values.count - 1)
'assigning a box a random value form the list
box(i) = values(RandomNumber)
'removing that value from the list
values.RemoveAt(RandomNumber)
Next

Related

Short any value in VB.Net

I'm quite a beginner in programming, and I want to make it shorter: code:
For y as integer = 1 to 5
'Code'
Next
Using sw As New StreamWriter(filepath)
sw.WriteLine("[TxtStringNumP1]")
sw.WriteLine(TxtStringNumP1.Text)
sw.WriteLine("[TxtStringNumP2]")
sw.WriteLine(TxtStringNumP2.Text)
sw.WriteLine("[TxtStringNumP3]")
sw.WriteLine(TxtStringNumP3.Text)
sw.WriteLine("[TxtStringNumP4]")
sw.WriteLine(TxtStringNumP4.Text)
sw.WriteLine("[TxtStringNumP5]")
sw.WriteLine(TxtStringNumP5.Text)
End Using
MsgBox("Ok", vbInformation)
You can make this bit shorter:
For y as integer = 1 to 5
For y = 1 to 5
And you can then rely on the fact that your control have names that differ only by a number, and there is some collection of them that knows them by name:
For y = 1 To 5
Dim n = "TxtStringNumP" & y 'formulate the name
Dim c = Me.Controls.Find(n, True) 'find all controls with a matcing name, returns a collection of controls
sw.WriteLine($"[{n}]") 'write the name we formulated
sw.WriteLine(c(0).Text) 'write the text of the first control. All controls have a Text property, we don't need to convert it to textbox
Next

Is there a way to add up items(numbers) in the listbox and display them in the same box in visual basic

So I'm a beginner in vb class and am wondering how I can add up all products of Modnumber(variable name) Mod 2 so that i can attach them into one single line at the bottom of my listbox. What line should i add so the program runs like the pic below?
Dim number As Integer
Dim Modnumber As String
number = InputBox("I'm kindly asking you to tell me a number", "Number")
LstNumber.Items.Clear()
Do Until number = 1
Modnumber = number
LstNumber.Items.Add(number & vbTab & Modnumber Mod 2)
'each time it devides the number by two until number = 1
number \= 2
Loop
This is what I get
This is what I'm supposed to get in my lstbox
'capture your original input to use in the final result
Dim input = InputBox("I'm kindly asking you to tell me a number", "Number")
Dim number As Integer = input
Dim modNumber As Integer 'Changed this to a number
Dim result As New StringBuilder 'Used to store the product of doing Mod 2
LstNumber.Items.Clear()
Do Until number = 0 'loop until 0 instead of 1
modNumber = number Mod 2 'Do mod outside of LstNumber add so u can retain the value
LstNumber.Items.Add(number & vbTab & modNumber)
result.Insert(0, modNumber) 'Build your result string
number \= 2
Loop
'Add your additional stuff
LstNumber.Items.Add("Therefore")
LstNumber.Items.Add($"{input} = {result.ToString}") 'Original input plus built string

VB: Random Shuffler Duplicating Values

I am trying to make a Deal or no Deal game, however my problem at the moment is assigning set values to cases randomly. I have had no luck with randomly generating a number and checking if it already exists, so I am now attempting to simply shuffle the array. The problem is, for some reason, values get duplicated.
The code:
Dim nCaseValues(26) As Integer 'The different possible values for a case
Dim nCaseNumbers(26) As Integer 'The different case numbers
Dim nShadowNumber As Integer 'This holds the first number in the shuffle
Dim nShuffleNumber1 As Integer 'The first random position
Dim nShuffleNumber2 As Integer 'The second random position
'Clear the list if it already has content
listArray1.Items.Clear()
listArray2.Items.Clear()
listArray3.Items.Clear()
'Declare array for case values
nCaseValues(0) = 1500
nCaseValues(1) = 1
nCaseValues(2) = 2
nCaseValues(3) = 5
nCaseValues(4) = 10
nCaseValues(5) = 20
nCaseValues(6) = 50
nCaseValues(7) = 100
nCaseValues(8) = 150
nCaseValues(9) = 200
nCaseValues(10) = 250
nCaseValues(11) = 500
nCaseValues(12) = 750
nCaseValues(13) = 1000
nCaseValues(14) = 2000
nCaseValues(15) = 3000
nCaseValues(16) = 4000
nCaseValues(17) = 5000
nCaseValues(18) = 10000
nCaseValues(19) = 15000
nCaseValues(20) = 20000
nCaseValues(21) = 30000
nCaseValues(22) = 50000
nCaseValues(23) = 75000
nCaseValues(24) = 100000
nCaseValues(25) = 200000
'Declare array for case numbers
For genCaseNumArray = 0 To 25
nCaseNumbers(genCaseNumArray) = 0
listArray1.Items.Add(genCaseNumArray)
Next
'The shuffle
For J = 0 To 25 'This assigns case values to case numbers (It's probably moot, as I can just use the nCaseValues position, but it's here for now)
nCaseNumbers(J) = nCaseValues(J)
Next
For K = 0 To 25 'Lists the items below, this could possibly be an error
For I = 0 To 50 'Shuffles the list 50 times
nShuffleNumber1 = (Int(Rnd() * 26)) 'Gets a random number and assigns it
nShuffleNumber2 = (Int(Rnd() * 26))'Gets a random number and assigns it
nShadowNumber = nCaseNumbers(nShuffleNumber1) 'This holds the first value during the shuffle
nCaseNumbers(nShuffleNumber1) = nCaseNumbers(nShuffleNumber2)'First value now equals second value...
nCaseNumbers(nShuffleNumber2) = nShadowNumber 'And now second value holds first value.
Next 'Lists items in lists objects on the form
listArray1.Items.Add(K)
listArray2.Items.Add(nCaseValues(K))
listArray3.Items.Add(nCaseNumbers(K))
Next
I need each value to be unique. I am pretty sure it is a logic error in my code. Any help on why the numbers are duplicating would be great.
Here are a couple of outputs:
The first list is the Case Number, second is possible values in order, third is the final outcome - The individual case value. As you can see, some are duplicated, and the first list is repeated twice..
EDIT: I found out why it repeated twice - I was stupid enough to leave another for loop that was also adding to the list. I have solved my problem, see the answer below.
I figured out the problem (well, more just luck) - the internal For loop shouldn't of been internal. I moved it out, and voila - it works like a charm. So far. Let's just wait.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Randomize() 'Make the form random
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'State Variables
Dim nCaseValues(26) As Integer 'The different possible values for a case
Dim nShadowNumber As Integer
Dim nShuffleNumber1 As Integer
Dim nShuffleNumber2 As Integer
'Clear the list if it already has content
listArray1.Items.Clear()
listArray2.Items.Clear()
listArray3.Items.Clear()
'Declare array for case values
nCaseValues(0) = 1500 'If you're wondering why this is here, it's because I couldn't be bothered to work with a "car" value.
nCaseValues(1) = 1
nCaseValues(2) = 2
nCaseValues(3) = 5
nCaseValues(4) = 10
nCaseValues(5) = 20
nCaseValues(6) = 50
nCaseValues(7) = 100
nCaseValues(8) = 150
nCaseValues(9) = 200
nCaseValues(10) = 250
nCaseValues(11) = 500
nCaseValues(12) = 750
nCaseValues(13) = 1000
nCaseValues(14) = 2000
nCaseValues(15) = 3000
nCaseValues(16) = 4000
nCaseValues(17) = 5000
nCaseValues(18) = 10000
nCaseValues(19) = 15000
nCaseValues(20) = 20000
nCaseValues(21) = 30000
nCaseValues(22) = 50000
nCaseValues(23) = 75000
nCaseValues(24) = 100000
nCaseValues(25) = 200000
'Declare array for case numbers, probably obsolete
For genCaseNumArray = 0 To 25
nCaseNumbers(genCaseNumArray) = 0
Next
For J = 0 To 25 'Assigning case values to case numbers
nCaseNumbers(J) = nCaseValues(J)
Next
For I = 0 To 26 'The main shuffle.
nShuffleNumber1 = (Int(Rnd() * 26)) 'This selects a random number between 0 and 25, somehow.
nShuffleNumber2 = (Int(Rnd() * 26)) 'Ditto
nShadowNumber = nCaseNumbers(nShuffleNumber1) 'This "Shadow Number" will be used to temporarily hold the value of the first case
nCaseNumbers(nShuffleNumber1) = nCaseNumbers(nShuffleNumber2) 'The value of the first case now equals the value of the second case...
nCaseNumbers(nShuffleNumber2) = nShadowNumber '... and vice versa.
Next 'Display the cases, case values and shuffled case values in the lists.
For K = 0 To 25
listArray1.Items.Add(K)
listArray2.Items.Add(nCaseValues(K))
listArray3.Items.Add(nCaseNumbers(K))
Next
I found this to be a really simple and (maybe) efficient way of shuffling an array. A lot easier than writing a script for a MERN.
I used to recommend randomising an array like this:
Dim rng As New Random
myArray = myArray.OrderBy(Function(element) rng.NextDouble()).ToArray()
It has since been pointed out to me that there is a serious issue with that because it will generate a new random number for the same element multiple times and thus comparing the same two elements could produce different results on different occasions. There's also the lesser issue that it creates a new array object. The following overcomes both those issues:
Dim rng As New Random
Dim keys = myArray.Select(Function(element) rng.NextDouble()).ToArray()
Array.Sort(keys, myArray)
That generates one random number per element and then sorts the original array in-place by those keys.

How can an item be added to a ListBox a specific number of times?

I want to add items to ListBox a specific number of times based on input. For example, if I input 5, it should add say, "DOG" 5 times to the ListBox. My code so far:
Dim number As Integer
number = TextBox1.Text
Dim add As String
add = POS.DescriptionText.Text
While number = add
POS.ListBox1.Items.Add(number)
End While
Use this code:
Dim text = "DOG" // maybe POS.DescriptionText.Text according to your code
For X As Integer = 1 To Integer.Parse(TextBox1.Text)
POS.ListBox1.Items.Add(text)
Next

Not able to add values in second Combobox

Here is my code.
for example TextBox1.Text= 12,34,45,67,67
Dim process_string As String() = TextBox1.Text.Split(New Char() {","})
Dim process As Integer
For Each process In process_string
Combo1.Items.Add(process)
count = count + 1
Next process
total_process.Text = count
End If
Dim array(count) As String
Dim a As Integer
For a = 0 To count - 1
array(a) = Combo1.Items(a).ToString
Next
a = 0
For a = count To 0
Combo2.Items.Add(array(a).ToString)
Next
i want to add values in reversed order in combobox2 that are available in combobox1
but when i run the application the second combobox remains empty and not showing any value.
You've specified this for loop
For a = count To 0
But you need to add STEP -1 to go backwards like that.
For a = count To 0 Step -1
2 things. First of all, K.I.S.S. Keep it simple stupid
For i As Integer = ComboBox1.Items.Count - 1 To 0 Step -1
ComboBox2.Items.Add(ComboBox1.Items(i))
Next
second: It didn't work because you forgot the Step -1 on your last loop
~~~~~~~~~~~~~~Edit~~~~~~~~~~~~~~
Sorting the data in a combo box should be done with the sorted property on a combo box
ComboBox3.Sorted = True
Sorting the data in reverse order should be done with arrays as you were trying to do before. The following code should suffice:
Dim List As ArrayList = ArrayList.Adapter(ComboBox3.Items)
List.Sort()
List.Reverse()
ComboBox4.Items.AddRange(List.ToArray)
If you wanted to get creative, you could potentially create your own combo box class and make your own version of the sorted property that allows for "sort alpha", "sort numeric", "sort alpha Desc", and "sort numeric desc" and perhaps some other options. But I'd only do that if you were going to use this in a lot of places.