VB.net Splitting a 1D array down into a 2D array - arrays

I am currently writing a (multiple choice) quiz program using VB.net I have read the answer options in from a .txt file into a single dimension temporary array however I would like to split this down into each question and the answer options for each questions into a 2D array so that (0,0) would be option A for question one and then (0,1) would be Option B for question 1 etc and then (1,0) would be option A for question 2. Below is the method I have tried however I get the error: "Object reference not set to an instance of an object" when adding 1 to a variable when I try and run this section of the code optnum = optnum + 1 Any help would be greatly appreciated, either fixing my code below or suggesting another method.
Dim optnum As Integer
Dim tempq As Integer = 0
Gameload(Phase_3.sounds)
Questionnum = 0
L_start.Hide()
optnum = 0
'splits the temp array down into options for each question
For i = 0 To 39
questions(tempq, optnum) = temparray(i)
optnum = optnum + 1
'there are 4 options for each question
'moves on to the next question when there is 4 options in the question
If optnum = 3 Then
tempq = tempq + 1
optnum = 0
End If
Next
For i = 0 To 3
L_option1.Text = questions(0, i)
Next
question_set()
Edit:
Here is the new full code I am still getting the error: Object reference not set to an instance of an object but now at the next in this section of code.
'''
For optnum = 0 To 3
questions(i, optnum) = temparray(i * 4 + optnum)
Next
'''
Thank you for all the help so far
'''
Public Class Game
Dim submission As Integer
Dim Correct_ans As Integer
Dim temparray() As String
Dim questions(,) As String
Dim Questionnum As Integer
Dim rs As New Resizer
Private Sub Game_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'finds all components on the screen in preperation if the screen resizes
rs.FindAllControls(Me)
L_start.Show()
End Sub
Private Sub Game_Resize(sender As Object, e As EventArgs) Handles Me.Resize
'resizes all components on the screen to same proportions
rs.ResizeAllControls(Me)
End Sub
Sub Gameload(ByVal sounds As String)
Dim pack As String
'reads in the sound pack
pack = My.Resources.ResourceManager.GetString(sounds)
Phase_3.Close()
'splits the pack into an array so that it can be broken down into questions
temparray = pack.Split(","c)
End Sub
Sub L_start_Click(sender As Object, e As EventArgs) Handles L_start.Click
Dim optnum As Integer
Dim tempq As Integer = 0
Gameload(Phase_3.sounds)
Questionnum = 0
L_start.Hide()
optnum = 0
'splits the temp array down into options for each question
For i = 0 To temparray.Count / 4
For optnum = 0 To 3
questions(i, optnum) = temparray(i * 4 + optnum)
Next
Next
For i = 0 To 3
L_option1.Text = questions(0, i)
Next
End Sub
'''

This is just my opinion but I think your aproach would be hard to maintain. I never saw the value of a class until I actually tried one. Maybe this is your chance.
Public Class Quiz
Public Property QuestionNumber As Integer
Public Property Question As String
Public Property AnswerA As String
Public Property AnswerB As String
Public Property AnswerC As String
Public Property AnswerD As String
Public Property CorrectAnswer As String
Public Overrides Function ToString() As String
Return $"Question: {QuestionNumber}.{Question} Answer Choices: {AnswerA}, {AnswerB}, {AnswerC}, {AnswerD} Correct Answer - {CorrectAnswer}"
End Function
End Class
To use your class...
Private QuestionList As New List(Of Quiz)
Private Sub OPCode2()
Dim temparray = File.ReadAllLines("answers.txt")
Dim temparraylocation As Integer
Dim questions = File.ReadAllLines("questions.txt")
Dim correctAnswers = File.ReadAllLines("correct.txt")
For i = 0 To questions.Length - 1
Dim qu As New Quiz
qu.QuestionNumber = i + 1
qu.Question = questions(i)
qu.CorrectAnswer = correctAnswers(i)
qu.AnswerA = temparray(temparraylocation)
temparraylocation += 1
qu.AnswerB = temparray(temparraylocation)
temparraylocation += 1
qu.AnswerC = temparray(temparraylocation)
temparraylocation += 1
qu.AnswerD = temparray(temparraylocation)
temparraylocation += 1
QuestionList.Add(qu)
Next
For Each q In QuestionList
Debug.Print(q.ToString)
Next
End Sub

Where's your declaration for temparray and questions. Will the quiz always have 4 choices and 10 questions?
It might be easier for you to have a nested loop so that i is temparray.count/4 and optnum is 0-3, then you can populate questions(i, optnum) = temparray(i*4+optnum)
Looking at your new code, you haven't initialised the questions variable. Only declared it.
Personally I would change questions to a list(of question), then use Mary's answer.

Related

Duplicate X Axis for Graph (VB.net)

I am having some issues with my VB.net database, I am trying to present a chart which shows a composition of customers who are members or not from a graph. The graph works, however; there are duplicates (as there are 8 bars instead of 2 bars):
For my database, I've used lists rather than conventional methods such as SQL. However, I'm uncertain if I've made a mistake or I'm missing something, here's the code:
Dim a As Integer
Dim b As Integer
Dim status As String
Dim countList As New List(Of Integer)
Dim statusList As New List(Of String)
Dim yesList As New List(Of String)
Dim count As Integer = 0
For a = 0 To memberList.Count - 1
status = memberList.Item(a).memberStatus
count = 0
For b = 0 To memberList.Count - 1
If status = memberList.Item(b).memberStatus Then
count = count + 1
End If
Next
statusList.Add(memberList.Item(a).memberStatus)
countList.Add(count)
Next
For i = 0 To countList.Count - 1
Debug.Print(memberList(i).memberStatus & countList(i).ToString)
Next
Chart_MemMostPopularTown.ChartAreas("ChartArea1").AxisX.MinorTickMark.Enabled = True
Chart_MemMostPopularTown.ChartAreas("ChartArea1").AxisX.Interval = 1
Chart_MemMostPopularTown.ChartAreas("ChartArea1").AxisX.IsLabelAutoFit = True
Chart_MemMostPopularTown.ChartAreas("ChartArea1").AxisX.LabelAutoFitStyle = DataVisualization.Charting.LabelAutoFitStyles.DecreaseFont
Chart_MemMostPopularTown.Series(0).Points.DataBindXY(statusList, countList)
If there is anything I've missed out, or if I've been too vague; please do let me know. I'm new to this site BTW so apologise for mistakes or lack of clarity.
Kind Regards

Need Help properly displaying an array in a listbox

Public Class Form1
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim Teams() As String = IO.File.ReadAllLines("SBWinners.txt")
Dim Team As String
Dim SteelersWins As Integer = 0
Dim RaidersWins As Integer = 0
Dim PackersWins As Integer = 0
Dim CowboysWins As Integer = 0
Dim GiantsWins As Integer = 0
Dim RamsWins As Integer = 0
Dim RavensWins As Integer = 0
Dim SaintsWins As Integer = 0
Dim FortyNinersWins As Integer = 0
Dim RedskinsWins As Integer = 0
Dim BroncosWins As Integer = 0
Dim PatriotsWins As Integer = 0
Dim ColtsWins As Integer = 0
Dim DolphinsWins As Integer = 0
Dim BearsWins As Integer = 0
Dim JetsWins As Integer = 0
Dim ChiefsWins As Integer = 0
Dim BuccWins As Integer = 0
For Each team In Teams
If team = "Steelers" Then
SteelersWins += 1
End If
If team = "Raiders" Then
RaidersWins += 1
End If
If team = "Packers" Then
PackersWins += 1
End If
If team = "Cowboys" Then
CowboysWins += 1
End If
If Team = "Giants" Then
GiantsWins += 1
End If
If team = "Rams" Then
RamsWins += 1
End If
If team = "Ravens" Then
RavensWins += 1
End If
If team = "Saints" Then
SaintsWins += 1
End If
If team = "Forty-Niners" Then
FortyNinersWins += 1
End If
If team = "Redskins" Then
RedskinsWins += 1
End If
If team = "Broncos" Then
BroncosWins += 1
End If
If team = "Patriots" Then
PatriotsWins += 1
End If
If team = "Colts" Then
ColtsWins += 1
End If
If team = "Dolphins" Then
DolphinsWins += 1
End If
If team = "Bears" Then
BearsWins += 1
End If
If team = "Jets" Then
JetsWins += 1
End If
If Team = "Chiefs" Then
ChiefsWins += 1
End If
If team = "Buccaneers" Then
BuccWins += 1
End If
Next
Dim Wins() As Integer = {SteelersWins, RaidersWins, PackersWins, CowboysWins, GiantsWins, RamsWins, RavensWins, SaintsWins, FortyNinersWins, RedskinsWins,
BroncosWins, PatriotsWins, ColtsWins, DolphinsWins, BearsWins, JetsWins, ChiefsWins, BuccWins}
For Each win In Wins
Array.Sort(Wins)
Array.Reverse(Wins)
lstOutput.Items.Add(win)
Next
End Sub
End Class
What I have right now is code that reads a text file with the names of Superbowl winners, and counts the number of wins by the number of times the team name appears. These wins are then put into an array and sorted in descending order and displayed in a listbox. This all works fine.
My problem is that I need to display the corresponding team name with their number of wins on the same line in the listbox. So, instead of being:
6
5
5
4
4
It needs to be:
6 Steelers
5 49ers
5 Cowboys
4 Giants
4 Packers
And so on.
There are a couple of issues with your code, not the least of which is you are using hard coded names and variables to collect your team information. This is severely limiting if new names are added or names change.
As Plutonix mentioned in the comments you need to use a class to properly identify and collate your information. I also strongly suggest you use a List(of T) collection to contain your data.
The following code does what you desire.
Private Class cls_Team_wins
Public Team_Name As String
Public Wins As Integer
Public Sub New(Name As String)
Team_Name = Name
Wins = 1
End Sub
Public Overrides Function ToString() As String
Return Strings.Right(" " & Wins, 2) & " - " & Team_Name
End Function
End Class
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim Games = New List(Of cls_Team_wins)
Dim Teams() As String = IO.File.ReadAllLines("SBWinners.txt")
For Each Team As String In Teams
If Team <> "" Then
Dim Team_Win As cls_Team_wins = Games.Find(Function(x) x.Team_Name = Team)
If Team_Win Is Nothing Then
Games.Add(New cls_Team_wins(Team))
Else
Team_Win.Wins += 1
End If
End If
Next
Games.Sort(Function(x, y) -x.Wins.CompareTo(y.Wins))
ListBox1.DataSource = Games
End Sub
The class included the team name and win counter. It over-rides the ToString method so the list box knows what to show as text. The New function requires you pass the team name and presets the win counter to one.
The For Loop checks for and ignores blank team names, this can be an issue reading text files, esp on the last line. Otherwise it will either add a new team to the list if it does not already exist, or it will increment the win counter if it does.
Once the list is built it is reverse sorted (Note the minus sign in the "Function" compare statement, that's a little trick that reverses the sort), and finally given to the listbox as a datasource.
Good luck to you :)

How to monitor array's and reset when limit is reached. VB.net

I have a VB.Net program that loops through array's to try to figure out where bottles are on a "conveyor". The point of this program is to visually show staff, how the conveyor works using VB.net and Labels. It's extremely difficult to explain, so I’ll do my best.
Bottle_Number(10) Bottle_Position(128)
There are 10 bottles that I want to track at all 128 stops on the conveyor.
We have a conveyor that can only fit 10 bottles. I need to track the position of each of the 10 bottles. Once bottle 11 comes on - That means bottle 1 is completed and off the conveyor. So, bottle 11 becomes bottle 1, so I need to reset the position of bottle1 to 0, and continue tracking bottles 2-9 while also tracking bottle 11(Not bottle 1). Once bottle 12 comes on it becomes bottle 2, and I need to reset the position of bottle 2 to '0' and continue tracking all bottles.
Any help would be appreciated.
Here is my code:
Public Class frmMain
Dim Product_Position(10) As Integer
Dim Inches_Per_Pulse As Integer
Dim PulseNumber As Integer
Dim Product_Counter As Integer
Dim Product_Location(10) As Integer
Dim Function1 As Integer
Dim Function2 As Integer
Dim Function3 As Integer
Dim Function4 As Integer
Dim Function5 As Integer
Dim Function6 As Integer
Dim Function7 As Integer
Dim Function8 As Integer
Dim Function9 As Integer
Dim Function10 As Integer
Dim Product_in_Tunel As Integer
Dim test As Integer
Dim Roll_OVer As Boolean
Dim Product_Counter_Test As Integer
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
lblStatus.BackColor = Color.Green
lblStatus.Text = "Conveyor Status: Running"
End Sub
Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click
lblStatus.BackColor = Color.Red
lblStatus.Text = "Conveyor Status: Off"
End Sub
Private replace_next As Integer
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
If Product_Counter = 10 Then
replace_next += 1
If replace_next > 10 Then
replace_next = 1 ' replace them in turn 1..10, then loop back to 1
Product_Position(replace_next) = 0 ' put initial position here
End If
End If
Product_Counter = Product_Counter + 1
If Product_Counter > 10 Then
Product_Counter = 1
Roll_over = True
End If
'MsgBox(Product_Counter)
'MsgBox(replace_next)
End Sub
Private Sub btnPulse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPulse.Click
Get_Location()
End Sub
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
PulseNumber = "0"
Inches_Per_Pulse = "1"
Roll_OVer = False
'MsgBox("Test")
End Sub
Public Sub Get_Location()
'MsgBox(Product_Counter)
If Roll_OVer = True Then
Product_Counter_Test = 10
'MsgBox("i'm stuck here")
End If
If Roll_OVer = False Then
Product_Counter_Test = Product_Counter
End If
'MsgBox(Product_Counter_Test)
'MsgBox("am I here - Yes")
For test = 1 To Product_Counter_Test
'MsgBox("This works")
Product_Position(test) = Product_Position(test) + Inches_Per_Pulse
Next
PulseNumber = PulseNumber + 1
ClearLabels()
lblProduct1Position.Text = Product_Position(1)
lblProduct2Position.Text = Product_Position(2)
lblProduct3Position.Text = Product_Position(3)
lblProduct4Position.Text = Product_Position(4)
lblProduct5Position.Text = Product_Position(5)
lblProduct6Position.Text = Product_Position(6)
lblProduct7Position.Text = Product_Position(7)
lblProduct8Position.Text = Product_Position(8)
lblProduct9Position.Text = Product_Position(9)
lblProduct10Position.Text = Product_Position(10)
End Sub
Public Sub ClearLabels()
lblProduct1Position.Text = ""
lblProduct2Position.Text = ""
lblProduct3Position.Text = ""
lblProduct4Position.Text = ""
lblProduct5Position.Text = ""
lblProduct6Position.Text = ""
lblProduct7Position.Text = ""
lblProduct8Position.Text = ""
lblProduct9Position.Text = ""
lblProduct10Position.Text = ""
End Sub
The Pulse button is what is actually driving the conveyor, each pulse (click of the button) means the conveyor is moving forward.
Right now once the program gets to bottle 11, it resets and only moves forward the "new" bottle (bottle1). It should continue incrementing the remaining bottles until they reach the end and do the same for them - Reset the position to 0 and begin counting again.
As far as I understand it, once you have 11 bottles, you don't want to reset to only one bottle, but instead still have 10 bottles, and replace one of them. You'll need a second variable to keep track of which is to be replaced.
So instead of :
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
Product_Counter = Product_Counter + 1
If Product_Counter > 10 Then Product_Counter = 1
End Sub
It would be something like:
Private Replace_Next as Integer = 0
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
If Product_Counter = 10 Then
Replace_Next += 1
If Replace_Next > 10 Then Replace_Next = 1 ' replace them in turn 1..10, then loop back to 1
Product_Position(Replace_Next) = .... ' put initial position here
Else
Product_Counter = Product_Counter + 1
End If
End Sub
Your conveyor is FIFO (first-in, first-out), so rather than constantly shifting, reindexing and/or rebuilding (=reset?) an array to make it seem like it is FIFO, Net includes the Queue(Of T) collection which is FIFO.
A LinkedList(Of T) could also be used. A plain List(Of T) would also work, but if the add/remove frequency is high, that will result in the same inefficient shifting taking place under the hood that you have with an array.
The only issue is enforcement of the size limit, which is easily handled with a small class wrapper. I assume there is something interesting or identifiable about the bottles other than their position. The test code uses a sequence ID and the contents.
Friend Class Bottle
Public Property Contents As String
Public Property SequenceID As Int32
' etc
Public Overrides Function ToString() As String
Return String.Format("{0}: ({1})", SequenceID.ToString("00"), Contents)
End Function
End Class
You likely have more relevant information to show. The, the collection class:
Friend Class BottleQueue
Private mcol As Queue(Of Bottle)
Private lbls As Label()
Private MaxSize As Int32 = 10 ' default
Public Sub New(size As Int32)
MaxSize = size
mcol = New Queue(Of Bottle)
End Sub
Public Sub New(size As Int32, l As Label())
Me.New(size)
lbls = l
End Sub
Public Sub Add(b As Bottle)
mcol.Enqueue(b)
Do Until mcol.Count <= MaxSize
mcol.Dequeue()
Loop
UpdateDisplay()
End Sub
Public Function Peek() As Bottle
Return mcol.ElementAtOrDefault(0)
End Function
Public ReadOnly Property Count() As Int32
Get
Return mcol.Count
End Get
End Property
Public Function Remove() As Bottle
Dim b As Bottle = Nothing
If mcol.Count > 0 Then
b = mcol.Dequeue
UpdateDisplay()
End If
Return b
End Function
Private Sub UpdateDisplay()
Dim n As Int32
If lbls Is Nothing OrElse lbls.Count = 0 Then
Return
End If
For n = 0 To mcol.Count - 1
lbls(n).Text = mcol.ElementAtOrDefault(n).ToString
Next
For n = n To lbls.Count - 1
lbls(n).Text = "(empty)"
Next
End Sub
Public ReadOnly Property GetQueue As Bottle()
Get
Return mcol.ToArray()
End Get
End Property
End Class
The class has 2 display means built in. One updates a set of labels. Since it is a collection, it also provides a way to get the current collection in order for a collection type control such as a Listbox. An even better way would be if the collection itself was "observable", so it could be used as a datasource.
It also provides a way to Removethe next bottle manually. Removing from a specific index (e.g. Remove(3)) is antithetical to a Queue, so it isnt implemented.
test code:
' form level vars:
Private BottleQ As BottleQueue
Private BottleID As Int32 = 7
' form load, passing the labels to use
' using a queue size of FIVE for test
BottleQ = New BottleQueue(5, New Label() {Label1, Label2, Label3, Label4, Label5})
Adding an item:
Dim material = {"Napalm", "Beer", "Perfume", "Pepsi", "Cyanide", "Wine"}
' add new bottle with something in it
BottleQ.Add(New Bottle With {.Contents = material(RNG.Next(0, material.Count)),
.SequenceID = BottleID})
BottleID += 1
' clear and show the contents in a listbox:
lbQueView.Items.Clear()
lbQueView.Items.AddRange(BottleQ.GetQueue)
The BottleId arbitrarily starts at 7, the contents are random. BTW, material shows just about the only way I ever use an array: when the contents are fixed and known ahead of time. In almost all other cases, a NET collection of one sort or another, is probably a better choice.
Because it is not an observable collection (and that is a little at odds with the FIFO nature), the listbox needs to be cleared each time. That could be internal to the class like the label display is. Results:
On the right, the first 5 are shown in order; 3 clicks later, the result is on the left: everything moved up 3 and 3 new items have been added.
Note: If the code using this needs to know when/which Bottle is removed from the conveyor, the class could include a ItemRemoved event which provides the item/Bottle just removed when adding forces one out. That is probably the case, but the question doesnt mention it.

Array of pictureboxes and resource images

Hey all i have the following code:
Dim radarStrengthImages() As PictureBox = ({imgRadar_Strength1, imgRadar_Strength2, imgRadar_Strength3, imgRadar_Strength4, imgRadar_Strength5, imgRadar_Strength6, imgRadar_Strength7, imgRadar_Strength8})
Dim radarStrengthResourcesON() As Bitmap = ({My.Resources.radarON_16, My.Resources.radarON_17, My.Resources.radarON_18, My.Resources.radarON_19, My.Resources.radarON_20, My.Resources.radarON_21, My.Resources.radarON_22, My.Resources.radarON_23})
Dim radarStrengthResourcesOFF() As Bitmap = ({My.Resources.radar_16, My.Resources.radar_17, My.Resources.radar_18, My.Resources.radar_19, My.Resources.radar_20, My.Resources.radar_21, My.Resources.radar_22, My.Resources.radar_23})
The imgRadar_StrengthX is the name of the pictureboxes on the form itself and My.Resources.radar_XX is the image for the pictureboxes.
However when i use this code:
Dim intX As Integer = 0
Do Until intX = 8
radarStrengthImages(intX).Image = radarStrengthResourcesON(intX)
intX += 1
Loop
I get an error of:
Object reference not set to an instance of an object
and that happens on this like:
radarStrengthImages(intX).Image = radarStrengthResourcesON(intX)
This kind of code can't work, initialization order is always an important detail. The variables you use don't get a value until after the InitializeComponent() method runs. But the arrays are initialized before that happens. So you just initialize them with Nothing, nada, zippo. "Object reference not set" is the zippo exception you'll get.
You'll have to do it later, that requires moving the initializer for the array into the constructor. Generic syntax for a sample form with textboxes:
Public Class Form1
Dim boxes As TextBox()
Public Sub New()
InitializeComponent()
boxes = New TextBox() {TextBox1, TextBox2, TextBox3}
End Sub
End Class
issue is this array start at index 0 and you have 8 items
change the loop to
Do Until intX = 7
and it should now work
or if the array will change in time, use a variable to handle the max
Module Module1
Sub Main()
Dim intX As Integer = 0
Dim test(7) As Integer '8 item
Dim max = test.Length - 1
Do Until intX = max
intX += 1
Loop
Console.WriteLine("intX: " & intX)
Console.ReadKey()
End Sub
End Module

Randomizing an array

I wish to implement the Dr.D.E.Knuth's Subtractive RANDOM number generation algorithm. I wish to implement an ATM panel on which when very time user log-in the buttons will be scrambled. every button will change its position.
Here is my code:
Public Sub addbutton()
Dim n As Integer = 0
For i As Integer = 0 To 10
' Initialize one variable
btnArray(i) = New System.Windows.Forms.Button
Next i
While (n < 10)
With (btnArray(n))
.Tag = n + 1 ' Tag of button
.Width = 40 ' Width of button
.Height = 40
FlowLayoutPanel1.Controls.Add(btnArray(n))
.Text = Chr(n + 48)
AddHandler .Click, AddressOf Me.ClickButton
n += 1
End With
End While
End Sub
Then, for sending information to button Text, I used:
Dim btn As Button = sender
TextBox1.Text += btn.Text
Now the major task is to shuffle the btnArray() with Random() function.. But I've failed to do this. I managed to get some code for shuffling the array like follows:
Imports System.Security.Cryptography
Public Class ArrayUtilities
Private Random As RNGCryptoServiceProvider = New RNGCryptoServiceProvider
Private Bytes(4) As Byte
Public Function ShuffleArray(ByVal argArr As Array) As Array
Dim FirstArray As New ArrayList(argArr)
Dim SecoundArray As Array = Array.CreateInstance(GetType(Object), FirstArray.Count)
Dim intIndex As Integer
For i As Integer = 0 To FirstArray.Count - 1
intIndex = RandomNumber(FirstArray.Count)
SecoundArray(i) = FirstArray(intIndex)
FirstArray.RemoveAt(intIndex)
Next
FirstArray = Nothing
Return SecoundArray
End Function
Private Function RandomNumber(ByVal argMax As Integer) As Integer
If argMax <= 0 Then Throw New Exception
Random.GetBytes(Bytes)
Dim intValue As Integer = (BitConverter.ToInt32(Bytes, 0)) Mod argMax
If intValue < 0 Then intValue = -intValue
Return intValue
End Function
End Class
Module Module1
Sub Main()
Dim AU As ArrayUtilities
AU = New ArrayUtilities
Dim GivenArray As Integer() = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Dim NewArray As Array = AU.ShuffleArray(GivenArray)
Dim i As Integer
Dim stb As New System.Text.StringBuilder
stb.Append("GivenArray = {0,1,2,3,4,5,6,7,8,9}")
stb.Append(vbCrLf)
stb.Append("NewArray = {")
For i = 0 To NewArray.Length - 2
stb.Append(NewArray(i).ToString)
stb.Append(", ")
Next
stb.Append(NewArray(NewArray.Length - 1).ToString)
stb.Append("}")
Console.Write(stb.ToString)
Console.Read()
End Sub
End Module
Yet, when we debug this code we get RANDOMNESS for the array. In the same way, I want randomness for my buttons on form.
Thank you sir. sir i tried the code that u suggested.
I was missing the incremental character "n".
Tthe debug-able code is
flowlayoutpannel.controls.add(out(n)).
but it is not working as i wanted and ABOVE code is just to show the way i want 2 shuffle the BUTTONS.
Is there any simpler way to jst create an button array and randomize them with RANDOM() and adding to form.
My buddies says you are so stupid that u are working on this topic from last 20-25DAYS
There are quite some "shuffle" algorithms (search Fisher-Yates for example) and they are usually not difficult to implement. The EASIEST (imho) way, ist to use LINQ:
Dim r As New Random
Dim out = (From b In btnArray Order By r.Next Select b).ToArray
Maybe the question is not clear: Do you want to shuffle the POSITIONS of the buttons or do you want to shuffle the CONTENT (buttons) of the Array?
To set the position of the buttons randomly in the panel, instead of using n from 0 to 9 in the loop, you can use a random value from 0 to 9. Be sure you don't use the same value twice.
You don't need to use a cryptographically secure random number generator for that, nor do you need a separate class.
Private Shared rng As New Random()
Private Shared Function ShuffleArray(Of T)(arr() As T) As T()
Dim left = Enumerable.Range(0, arr.Length).ToList()
Dim result(arr.Length - 1) As T
For i = 0 To arr.Length - 1
Dim nextIndex = rng.Next(left.Count)
result(i) = arr(left(nextIndex))
left.RemoveAt(nextIndex)
Next
Return result
End Function

Resources