Sorry for the long piece of code. In a game I'm designing, I have this code starting at the checkbox.checked if statement currently repeated 5 times for each checkbox clicked--each checkbox is equal to a card within the players hand in the game.
What I'd like to know is what can I do to make it mostly dynamic. Namely the CardCheckBox1.Checked Object/Method. As stated above the code is repeated 5 times, as I have 5 existing checkboxes. Is there a way to place the checkboxes into an array or collection so when I click a check box and hit the play button it will be the equivalent of hitting CardCheckBox2.checked = true, CardCheckBox2.checked = true, etc. Once I figure how to make that part dynamic I can finally start making the rest of the code dynamic, because I assume procedure for making a dynamic label code would be very similar to the checkboxes, etc.
I've had
Dim CardCheckBoxArray() As CheckBox = {CardCheckBox1, CardCheckBox2, CardCheckBox3, CardCheckBox4, CardCheckBox5}
posted at the Modular Level, in the Form_Load Procedure, and even the Play_Button Procedure, but I always end up with a nullreference exception on the CardCheckBox(n).Checked Portion of the code when I do
If CardCheckBoxArray(0).Checked = True And Player1HandGroup(Number1).QuantityInteger > 0 Then
So I don't know where to go with it. The long piece of code is my entire PlayButton_Click procedure, except for the other CardCheckBox if statements.
Private Sub PlayButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PlayButton.Click
Dim n As Integer
Dim WeaponDiscardInteger As Integer = 1
AtkPlayerDialog.ShowDialog()
'Code for choosing which player to attack
If AtkPlayerDialog.DialogResult = Windows.Forms.DialogResult.Cancel Then
n = 2
ElseIf AtkPlayerDialog.DialogResult = Windows.Forms.DialogResult.OK Then
n = 1
ElseIf AtkPlayerDialog.DialogResult = Windows.Forms.DialogResult.Abort Then
n = 3
ElseIf AtkPlayerDialog.DialogResult = Windows.Forms.DialogResult.Retry Then
n = 4
ElseIf AtkPlayerDialog.DialogResult = Windows.Forms.DialogResult.Ignore Then
n = 5
End If
'playing card 1
If CardCheckBox1.Checked = True And Player1HandGroup(Number1).QuantityInteger > 0 Then
'Subtract Hitpoints when damage is delt
Player1HandGroup(n).HitPoints -= Player1HandGroup(Number1).DamageInteger
HitPoints1.Text = Player1HandGroup(1).HitPoints.ToString
HitPoints2.Text = Player1HandGroup(2).HitPoints.ToString
HitPoints3.Text = Player1HandGroup(3).HitPoints.ToString
HitPoints4.Text = Player1HandGroup(4).HitPoints.ToString
HitPoints5.Text = Player1HandGroup(5).HitPoints.ToString
'When player plays hand, card quantity is removed from hand to discard pile.
Player1HandGroup(Number1).QuantityInteger -= 1
DiscardGroup(Number1).QuantityInteger += 1
'Shuffle Deck from Discard Pile if Deck is out of cards
Call DiscardPile()
'Reset Number Generator, unless weapon isn't discard
Number = (DeckGroup(Rnd.Next(0, DeckGroup.Count)).ID)
If DeckGroup(Number).QuantityInteger > 0 Then
'Grab New Card From Deck
DeckGroup(Number).QuantityInteger -= 1
Player1HandGroup(Number).QuantityInteger += 1
Card1Type = Player1HandGroup(Number).CardType
CardCheckBox1.Text = Player1HandGroup(Number).CardNameString
Number1 = Number
Else
Call PlayElse()
End If
I f you use the checkbox array inside/through most your form code then move it out o the form load event right the way up to the form level scope. when it is inside the forn_load event subroutine, that is not the same as module level scope.
so you would have......
Dim CardCheckBoxArray() As CheckBox = {CardCheckBox1, CardCheckBox2, CardCheckBox3, CardCheckBox4, CardCheckBox5}
Sub Form_Load(blah blah blah)
...
End Sub
Sub Play_Button(blah blah blah)
...
End Sub
etc etc
Related
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
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 :)
So I am building a Memory Game. This is a 2 part question. I have 16 boxes being used and need to have the numbers 1-8 twice. I have set up each box as a structure and have a random number generator randomly picking a number for a box and then randomly placing a number 1 - 8 into it. Problem I am coming across is this. I am getting repeat numbers for my boxes and more than 2 times for a digit that will be placed in that box, sometimes no sequential number being used all together. How can I make sure all 16 boxes are being created with out having to make code for 16 different instances. Also need to make sure each single digit number between 1-8 is being used and only used twice?
Second part of my question is I am having an issue with making a click event when a user chooses a box. Right now I can't figure out how to associate which box the user clicks on. I don't want to write code for 16 different boxes, link an array to each box and then populate each box that array's guess number. Is there a way I can simplify that code down to something short?
I have included all the code so far.
Option Strict On
Option Explicit On
Option Infer Off
Public Class Form1
Structure MemoryBox
Public intBox As Integer
Public intGuess As Integer
Public strGuess As String
End Structure
Private gameScore() As Integer
Private memoryGame(15) As MemoryBox
Dim countLoad As Integer = 0
Dim countScore As Integer = 0
Dim intScore As Integer
Private Sub LoadGame()
'this is where I am using the random numbers to make each box and populate it with a guess
Dim randomGen As New Random
Dim intMemBox As Integer
Dim intMemGuess As Integer
intScore = 0
If countLoad <= 15 Then
intMemBox = randomGen.Next(1, 16)
intMemGuess = randomGen.Next(1, 8)
memoryGame(countLoad).intBox = intMemBox
memoryGame(countLoad).intGuess = intMemGuess
memoryGame(countLoad).strGuess = intMemGuess.ToString
countLoad += 1
End If
End Sub
Private Sub GuessClick()
'trying to use this area for click event for each box click
lblMemory1.BackColor = Color.Green
lblMemory1.Text = memoryGame()
intScore += 1
lblScore.Text = intScore.ToString
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Call LoadGame()
End Sub
Private Sub btnNewGame_Click(sender As Object, e As EventArgs) Handles btnNewGame.Click
gameScore(countScore) = intScore
countScore += 1
Dim outFile As IO.StreamWriter
outFile = IO.File.AppendText("score.txt")
outFile.WriteLine(intScore)
outFile.Close()
Call LoadGame()
End Sub
Private Sub btnHighScore_Click(sender As Object, e As EventArgs) Handles btnHighScore.Click
Array.Sort(gameScore)
lblHighScore.Text = gameScore(0).ToString
End Sub
Private Sub btnAllScores_Click(sender As Object, e As EventArgs) Handles btnAllScores.Click
Dim inFile As IO.StreamReader
Dim strInfo As String
If IO.File.Exists("score.txt") Then
inFile = IO.File.OpenText("score.txt")
Do Until inFile.Peek = -1
strInfo = inFile.ReadLine
Loop
inFile.Close()
Else
MessageBox.Show("Can't find the score.txt file", "High Score", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
MessageBox.Show(strInfo, "All Scores", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
End Class
One option is to populate an array with the numbers you want, then randomly shuffle it. Use a loop that runs at least one times the length of the array and use the iterator value as one index and swap it with a randomly chosen index.
Something like this:
Dim memoryGame(15) As MemoryBox
Dim randomarray() As Integer = {1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8}
Dim rnd As New Random(Now.Millisecond)
For I = 0 To 15
Dim randindex As Integer = rnd.Next(0, 16)
Dim temp As Integer = randomarray(I)
randomarray(I) = randomarray(randindex)
randomarray(randindex) = temp
Next
For I = 0 To 15
memoryGame(I).intBox = randomarray(I)
Next
From here simply iterate through the array and assign the values to your boxes
To handle the click events:
Use the same handler for each box. One way is to add a Handles clause for each box. With 16 boxes this could get a little clunky. I would suggest in the load event handler iterate through the boxes and use the AddHandler statement to add the handler to each box. At this point sender will always point to the box that was clicked. It is simply a matter of casting sender as whatever type the box is, to access all the properties of the box.
If the boxes are buttons(Box1, Box2, etc.) it would look something like this:
For Each b As Button In Me.Controls.OfType(Of Button).Where(Function(x) x.Name.StartsWith("Box"))
AddHandler b.Click, AddressOf Button_Click
Next
Private Sub Button_Click(sender As Object, e As EventArgs)
Dim clickedbutton As Button = DirectCast(sender, Button)
'access the properties here
End Sub
I have been getting into some object-oriented features of VB6. I've done lots of OOP with Java, and I'm trying to get this to work:
I have a array of Card objects, I want to check if an object in the index in the array has been created.
Dim cardsPlayer1(1 To 10) As Card
I created objects like this:
Set cardsPlayer1(index) = New Card
If tried using this to test if I have assigned an object to an index yet:
For counter = 1 To 10
If (cardsPlayer1(counter) Is Nothing) Then
Set cardsPlayer1(counter) = New Card
End If
Next counter
But it gave me a true value everytime and creating a new object to the whole array.
Here's the relevant code:
'Jordan Mathewson
'May 31, 2013
Dim cardsPlayer1(1 To 10) As Card
Dim cardsPlayer2(1 To 10) As Card
Private Sub cmdStartGame_Click()
Call addCard(1)
End Sub
'Called to add a card to one of the player's stacks
Private Sub addCard(player As Integer)
Dim counter As Integer
'To add a card to player1..
If (player = 1) Then
For counter = 1 To 10
If (cardsPlayer1(counter) Is Nothing) Then
Print "Object created." '<- Printed 10 times.
Set cardsPlayer1(counter) = New Card
End If
Next counter
'To add a card to player2..
Else
For counter = 1 To 10
If (cardsPlayer2(counter) Is Nothing) Then
Set cardsPlayer2(counter) = New Card
End If
Next counter
End If
Call refreshForm
End Sub
If I understand you correctly, the addCard sub should add one card but it adds all of them, when only called once. This isn't because it can't tell which array element is empty. It's just because it doesn't stop after successfully adding one.
For counter = 1 To 10
If (cardsPlayer1(counter) Is Nothing) Then
Set cardsPlayer1(counter) = New Card
Exit For ' <-- Add this
End If
Next counter
Without the Exit For, it will keep looping through the array and initialize the rest of it.
I suspect you might have a scoping issue. This gives me the expected results:
Sub Test()
Dim objectsArray(1 To 5) As TestObject
If objectsArray(1) Is Nothing Then
MsgBox "objectsArray(1) Is Nothing" ' <----- displayed
End If
Set objectsArray(1) = New TestObject
If objectsArray(1) Is Nothing Then
MsgBox "objectsArray(1) Is Nothing"
Else
MsgBox "Not objectsArray(1) Is Nothing" ' <----- displayed
End If
End Sub
Where do you declare objectsArray; where do you create the object; where is the loop? (Are these code snippets in different modules/class modules/functions?)
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