Object variable or With block variable not set (Arrays) - arrays

For several projects now I've had this error flash up and completely ground my projects. In most cases, I've simply had to leave them and start a new, different one. Basically, I just want to be able to refer to every object on the form that matches certain criteria. In this case it's an arcade style game with four different game modes. There is a timer that creates the objects to be shot at and it works fine, either a PictureBox or a label depending on which mode. on creation it changes the tag of each object to "Obj" & whatever shape/maths number it is with a space in-between. But for some reason it won't create an array of sorts on a different timer tick event to move them.
I just need it to be able to constantly add and delete objects to shoot at, the adding and moving and deleting was working fine, but as in all my other cases with arrays this error just worms its way in and me and my seriously qualified IPT teacher can't figure it out. Why does it suddenly start doing it and how can I fix it? Attached is some of the code for the object move event.
Dim NumofObjsLeft As Integer = 0
For Each obj As Object In Me.Controls
If obj.Tag.Contains("Obj") Then
NumofObjsLeft += 1
If NumofObjsLeft <= 0 Then
Wav += 1
WaveStart = True
End If
Select Case GameMode
Case "Protector"
Select Case Curry
Case "Shapes"
If TypeOf obj Is PictureBox AndAlso obj.Tag.Contains("Obj") Then
obj.Left += 15
End If
Case "Maths"
If TypeOf obj Is Label AndAlso obj.tag.Contains("Obj") Then
obj.Left += 15
End If
End Select
EDIT: Just thought I'd add all the code for Shape Spawn and Move. I haven't finished the other half of the code for Shape Move cause I couldn't get the first part to work.
Private Sub tmrShapeSpawn_Tick(sender As System.Object, e As System.EventArgs) Handles tmrShapeSpawn.Tick
If WaveStart = True Then
Select Case Wav
Case 1
NumofObjs = Wave1
Case 2
NumofObjs = Wave2
Case 3
NumofObjs = Wave3
Case 4
NumofObjs = Wave4
Case 5
NumofObjs = Wave5
Case 6
NumofObjs = Wave6
End Select
If F < NumofObjs Then
Dim newPic As PictureBox = New PictureBox
Dim newLab As Label = New Label
Dim CorrectLabel As Label = New Label
Dim CorrectPictureBox As PictureBox = New PictureBox
CorrectPictureBox.Height = 75
CorrectPictureBox.Width = 100
CorrectLabel.AutoSize = True
CorrectLabel.BackColor = Color.Transparent
CorrectPictureBox.BackColor = Color.Transparent
CorrectPictureBox.SizeMode = PictureBoxSizeMode.Zoom
CorrectLabel.ForeColor = Color.Blue
CorrectLabel.Font = New Font("Goudy Stout", 60, FontStyle.Regular)
Select Case GameMode
Case "Protector"
Randomize()
If CorrectMade = False Then
CorrectLabel.Left = CorrectLabel.Width
CorrectPictureBox.Left = CorrectPictureBox.Width
CorrectLabel.Top = Int(Rnd() * (Me.Height - CorrectLabel.Height))
CorrectPictureBox.Top = Int(Rnd() * (Me.Height - CorrectPictureBox.Height))
End If
newLab.Left = newLab.Width
newPic.Left = newPic.Width
newLab.Top = Int(Rnd() * (Me.Height - newLab.Height))
newPic.Top = Int(Rnd() * (Me.Height - newPic.Height))
Case "Catcher"
Randomize()
If CorrectMade = False Then
CorrectLabel.Top = CorrectLabel.Height
CorrectPictureBox.Top = CorrectPictureBox.Height
CorrectLabel.Left = Int(Rnd() * (Me.Width - CorrectLabel.Width))
CorrectPictureBox.Left = Int(Rnd() * (Me.Width - CorrectPictureBox.Width))
End If
newLab.Top = newLab.Height
newPic.Top = newPic.Height
newLab.Left = Int(Rnd() * (Me.Width - newLab.Width))
newPic.Left = Int(Rnd() * (Me.Width - newPic.Width))
End Select
Select Case Curry
Case "Maths"
lblCriteria.Text = lstNum1.Items.Item(Wav - 1) & " " & lstOp.Items.Item(Wav - 1) & " " & lstNum2.Items.Item(Wav - 1) & " ="
If CorrectMade = False Then
CorrectLabel.Text = lstAns.Items.Item(Wav - 1)
CorrectLabel.Tag = "Obj " & lstAns.Items.Item(Wav - 1)
Me.Controls.Add(CorrectLabel)
CorrectLabel.BringToFront()
End If
Randomize()
newLab.Text = Int(Rnd() * 100)
newLab.Tag = "Obj " & newLab.Text
Me.Controls.Add(CorrectLabel)
CorrectLabel.BringToFront()
Case "Shapes"
Dim epahs As Integer
Dim sap As String
lblCriteria.Text = lstShape.Items.Item(Wav - 1)
If CorrectMade = False Then
CorrectPictureBox.ImageLocation = "Shapes\" & lstShape.Items.Item(Wav - 1) & ".png"
CorrectPictureBox.Tag = "Obj " & lstShape.Items.Item(Wav - 1)
Me.Controls.Add(CorrectPictureBox)
CorrectPictureBox.BringToFront()
End If
Randomize()
epahs = Int(Rnd() * 9)
Select Case epahs
Case 0
sap = "Square"
Case 1
sap = "Circle"
Case 2
sap = "Triangle"
Case 3
sap = "Rectangle"
Case 4
sap = "Oval"
Case 5
sap = "Hexagon"
Case 6
sap = "Star"
Case 7
sap = "Diamond"
Case 8
sap = "Trapezium"
Case 9
sap = "Rhombus"
End Select
newPic.ImageLocation = "Shapes\" & sap & ".png"
newPic.Tag = "Obj " & sap
newPic.SizeMode = PictureBoxSizeMode.Zoom
Me.Controls.Add(newPic)
newPic.BringToFront()
End Select
CorrectMade = True
F += 1
Else
WaveStart = False
End If
End If
End Sub
Private Sub tmrShapeMove_Tick(sender As System.Object, e As System.EventArgs) Handles tmrShapeMove.Tick
Dim CBA As Integer
Dim NumofObjsLeft As Integer = 0
For Each obj As Object In Me.Controls
If obj.Tag.Contains("Obj") Then
NumofObjsLeft += 1
If NumofObjsLeft <= 0 Then
Wav += 1
WaveStart = True
End If
Select Case GameMode
Case "Protector"
Select Case Curry
Case "Shapes"
If TypeOf obj Is PictureBox AndAlso obj.Tag.Contains("Obj") Then
obj.Left += 15
End If
Case "Maths"
If TypeOf obj Is Label AndAlso obj.tag.Contains("Obj") Then
obj.Left += 15
End If
End Select
For CBA = 0 To ABC Step 1
If Collision(obj, Missile(CBA)) Then
Missile(CBA).Visible = False
Missile(CBA).Enabled = False
If picExplosion1.Visible = True And picExplosion2.Visible = False And picExplosion3.Visible = False Then
picExplosion2.Visible = True
tmrExplosion2.Start()
CentreOn(obj, picExplosion2)
ElseIf picExplosion1.Visible = True And picExplosion2.Visible = True And picExplosion3.Visible = False Then
picExplosion3.Visible = True
tmrExplosion3.Start()
CentreOn(obj, picExplosion3)
ElseIf picExplosion1.Visible = False Then
picExplosion1.Visible = True
tmrExplosion1.Start()
CentreOn(obj, picExplosion1)
Else
End If
If obj.Tag.Contains(lblCriteria.Text) Then
lblScore.Text += 1
Else
lblLives.Text -= 1
End If
Me.Controls.Remove(obj)
End If
Next CBA
Case "Catcher"
Select Case Curry
Case "Shapes"
If TypeOf obj Is PictureBox AndAlso obj.Tag.Contains("Obj") Then
obj.Top += 15
End If
Case "Maths"
If TypeOf obj Is Label AndAlso obj.Tag.Contains("Obj") Then
obj.Top += 15
End If
End Select
If Collision(obj, picChar) Then
If obj.Tag.Contains(lblCriteria.Text) Then
Score += 1
Else
Lives -= 1
End If
Me.Controls.Remove(obj)
End If
End Select
End If
Next obj
End Sub

1) Use background worker instead of timer. Its built to interact correctly with the main form thread and handle control interactions a bit more cleanly. Timers are notoriously problematic for both main UI thread sync issues and exiting unexpectedly.
2) You have to handle the obj.Tag or obj being nothing. The easiest way is to add
If obj is Nothing OrElse String.IsNullOrWhitespace(obj.Tag) Then
Continue For
End If
...as the first statement after the For loop.

Righto, thanks to everyone who commented, replied. It seems to be working now with just that extra condition. Adding an if statement to check to see if the tag is empty before comparing the text.
Dim NumofObjsLeft As Integer = 0
For Each obj As Object In Me.Controls
If obj.Tag > "" Then
If obj.Tag.Contains("Obj") Then
NumofObjsLeft += 1
If NumofObjsLeft <= 0 Then
Wav += 1
WaveStart = True
End If
Select Case GameMode
Case "Protector"
Select Case Curry
ETC...................................................

Related

how to populate array of controls (labels) using database vb.net

I am doing my homework but stuck on a part. Problem is, How can i populate seat number in array of controls(labels) using database. I already created labels and a class to retrieve all rows from database but how can i apply it in main form and populate labels.
--------------------------Class---------------------------------------
Public Shared Function getOneRow(PK As Integer) As datMovieTimes
Dim returnRow As New datMovieTimes(0)
Dim connDB As New SqlConnection
connDB.ConnectionString = Conn.getConnectionString
Dim command As New SqlCommand
command.Connection = connDB
command.CommandType = CommandType.Text
command.CommandText = SQLStatements.SELECT_1_BY_ID
command.Parameters.AddWithValue("#Key", PK)
Try
connDB.Open()
Dim dR As IDataReader = command.ExecuteReader
If dR.Read() Then
returnRow.showingID = PK
If Not IsDBNull(dR(Fields.movieID)) Then returnRow.movieID = dR(Fields.movieID)
If Not IsDBNull(dR(Fields.dateTime)) Then returnRow.dateTime = dR(Fields.dateTime)
If Not IsDBNull(dR(Fields.isActive)) Then returnRow.isActive = dR(Fields.isActive)
End If
Catch ex As Exception
Console.WriteLine(Err.Description)
End Try
Return returnRow
End Function
Public Shared Function getAllRows() As Generic.List(Of datMovieTimes)
Dim returnRows As New Generic.List(Of datMovieTimes)
Dim connDB As New SqlConnection
connDB.ConnectionString = Conn.getConnectionString
Dim command As New SqlCommand
command.Connection = connDB
command.CommandType = CommandType.Text
command.CommandText = SQLStatements.SELECT_ALL
Try
connDB.Open()
Dim dR As IDataReader = command.ExecuteReader
Do While dR.Read()
Dim Row As New datMovieTimes(0)
If Not IsDBNull(dR(Fields.showingID)) Then Row.showingID = dR(Fields.showingID)
If Not IsDBNull(dR(Fields.movieID)) Then Row.movieID = dR(Fields.movieID)
If Not IsDBNull(dR(Fields.dateTime)) Then Row.dateTime = dR(Fields.dateTime)
If Not IsDBNull(dR(Fields.isActive)) Then Row.isActive = dR(Fields.isActive)
returnRows.Add(Row)
Loop
Catch ex As Exception
Console.WriteLine(Err.Description)
End Try
Return returnRows
End Function
-----------------------------main form-----------------------------------------
Public Sub createSeat()
Dim S1 As Label
For X As Integer = 1 To _MAX_X
For Y As Integer = 1 To _MAX_Y
S1 = New Label
S1.Height = 25
S1.Width = 25
S1.BackColor = Color.LightGreen
S1.Top = 100 + (X - 1) * (S1.Height + 5)
S1.Left = 200 + (Y - 1) * (S1.Width + 5)
S1.TextAlign = ContentAlignment.MiddleCenter
S1.Text = Y.ToString
AddHandler S1.Click, AddressOf GenericLabel_Click
Me.Controls.Add(S1)
_SeatArray(X, Y) = S1
Next
Next
For X As Integer = 0 To 9
_AlphaLabel(X) = New Label
_AlphaLabel(X).Height = 25
_AlphaLabel(X).Width = 25
_AlphaLabel(X).BackColor = Color.Transparent
_AlphaLabel(X).Top = 130 + (X - 1) * (_AlphaLabel(X).Height + 6)
_AlphaLabel(X).Left = 170
_AlphaLabel(X).Text = _AlphaName(X)
Me.Controls.Add(_AlphaLabel(X))
Next
End Sub
Private Sub GenericLabel_Click(sender As Object, e As EventArgs)
Dim L As New Label
L = DirectCast(sender, Label)
If L.BackColor = Color.LightGreen Then
L.BackColor = Color.Orange
clickLess -= 1
ElseIf L.BackColor = Color.Orange Then
L.BackColor = Color.LightGreen
clickLess += 1
End If
clickCount += 1
Me.lblRemainingCount.Text = clickLess.ToString
Me.nudTicketsCount.Value = clickCount
If clickLess <= 0 Then
MsgBox("No more seats left.", MsgBoxStyle.OkOnly, "House Full")
End If
End Sub
Database pic
When creating labels, insert one more line:
S1.Name = "MyLabel" & X & Y
When accessing the label:
Dim MyCurrentLabel as Label
MyCurrentLabel = CType("MyLabel" & X & Y, Label)
Then you can do things with the current label:
MyCurrentLabel.Text = "Hello World"
current image
Now it is something like this, so it want to change the colour to red if it is paid according to database.
Thanks
I found the answer, sorry i forgot to mention it because i was busy in completing the project
----------------------Seat creation----------------------------------------
Public Sub createSeat()
Dim S1 As Label
Dim numValue As Integer = 1
For X As Integer = 1 To _MAX_X
For Y As Integer = 1 To _MAX_Y
S1 = New Label
S1.Height = 25
S1.Width = 25
S1.BackColor = Color.LightGreen
S1.Top = 180 + (X - 1) * (S1.Height + 5)
S1.Left = 200 + (Y - 1) * (S1.Width + 5)
S1.TextAlign = ContentAlignment.MiddleCenter
S1.Text = Y.ToString
' S1.Text = numValue
S1.Name = "Label" & numValue
AddHandler S1.Click, AddressOf GenericLabel_Click
Me.Controls.Add(S1)
_SeatArray(X, Y) = S1
numValue += 1
Next
Next
For X As Integer = 0 To 9
_AlphaLabel(X) = New Label
_AlphaLabel(X).Height = 25
_AlphaLabel(X).Width = 25
_AlphaLabel(X).BackColor = Color.Transparent
_AlphaLabel(X).Top = 210 + (X - 1) * (_AlphaLabel(X).Height + 6)
_AlphaLabel(X).Left = 170
_AlphaLabel(X).Text = _AlphaName(X)
Me.Controls.Add(_AlphaLabel(X))
Next
End Sub
-------------------------------populate seat number----------------------------------
Public Sub populateSeatNumber()
Dim connectionString As String = DBL.Conn.getConnectionString
Dim connection As New SqlConnection(connectionString)
connection.Open()
Dim selectStatement As String = "SELECT * FROM datTicketsSold"
Dim selectCommand As New SqlCommand(selectStatement, connection)
Dim daSoldTickets As New SqlDataAdapter(selectCommand)
Dim dsSoldTickets As DataSet = New DataSet
daSoldTickets.Fill(dsSoldTickets, "datTicketsSold")
connection.Close()
Dim dtTickets As DataTable = dsSoldTickets.Tables("datTicketsSold")
Dim row As DataRow
For Each row In dtTickets.Rows
If row(3) = True Then
CType(Controls("Label" & row(2)), Label).BackColor = Color.Red
redCounter += 1
Else
CType(Controls("Label" & row(2)), Label).BackColor = Color.Yellow
yellowCounter += 1
End If
Next
Me.lblReservedCount.Text = yellowCounter.ToString
Me.lblSoldCount.Text = redCounter.ToString
End Sub
Thanks everyone

VB.net Passing value of Array 1, to Array 2

so i have this code, and i need to pass the value of array1 to array2,
but the value of array2 should be array1 + (key Mod 255) where key is put by the user
Private Sub mod_Btn_enc_Click(sender As Object, e As EventArgs) Handles mod_Btn_enc.Click
Dim counter As Integer = 0
If mod_TB_key.Text = "" Then
MessageBox.Show("Pls Input Modulo Key Value", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
modKey = mod_TB_key.Text
End If
modModulo = modKey Mod 255 'formula
mod_TB_mod.Text = modModulo 'i used this to show that it is working
'modbyte = array 1
'modconverted = array2
For Each i As Integer In modByte
counter += 1
modConverted(counter - 1) = modByte(i - 1) + (modModulo) 'formula used
Next i
mod_Tb_enc.Text = String.Join(" ", modConverted) 'show the array in textbox
here is my interface
i've managed to do it this way.
For i = 0 To modByte.GetUpperBound(0)
counter += 1
ReDim Preserve modConverted(counter - 1)
modConverted(counter - 1) = modByte(i) + (modModulo)
Next
thanks for explaining #phoog

Background Worker and ODBC Query

I want to run the fetching of a Database into a background worker but it seems to be crashing without Visual Studio returning me an error in my code.
Here's the code in the DoWork:
Private Sub ITSM_Fetch_BW_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles ITSM_Fetch_BW.DoWork
Dim sql As String = "xxxx"
Dim ConnString As String = "DRIVER={AR System ODBC Driver};ARServer=xxxx;ARServerPort=xxxx;ARPrivateRpcSocket=xxxx;UID=xxxx;PWD=xxxx;ARAuthentication=;ARUseUnderscores=1;SERVER=NotTheServer"
Dim connection As New Odbc.OdbcConnection(ConnString)
connection.Open()
Dim ODBC_Command As New Odbc.OdbcCommand(sql, connection)
Dim ODBC_reader As Odbc.OdbcDataReader
'Load the Data into the local Memory
ODBC_reader = ODBC_Command.ExecuteReader
e.Result = ODBC_reader
ODBC_reader.Close()
End Sub
Private Sub ITSM_Fetch_BW_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles ITSM_Fetch_BW.RunWorkerCompleted
Data = New DataTable
Data.Load(e.Result)
Dim Count_ToDo(5) As String
Count_ToDo(0) = "Product_Name"
Count_ToDo(1) = "Status"
Count_ToDo(2) = "Language"
Count_ToDo(3) = "Assigned_Group"
Count_ToDo(4) = "Priority"
Count_ToDo(5) = "Company"
For Each Item As String In Count_ToDo
Dim i As Integer = 0
Dim ITEM_Count(0, 1) As String
For Each Ticket As DataRow In Data.Rows
'PART FOR THE CI
If IsDBNull(Ticket.Item(Item)) = False Then
Dim IsInIndex As Integer = -1
If i = 0 Then
ITEM_Count(0, 0) = Ticket.Item(Item)
ITEM_Count(0, 1) = 1
Else
For x As Integer = 0 To ITEM_Count.GetLength(0) - 1
If ITEM_Count(x, 0) = Ticket.Item(Item) Then
IsInIndex = x
End If
Next
If IsInIndex = -1 Then
Dim ITEM_Count_Temp(ITEM_Count.GetLength(0), ITEM_Count.GetLength(0)) As String
ITEM_Count_Temp = ITEM_Count
ReDim ITEM_Count(ITEM_Count.GetLength(0), 1)
For x As Integer = 0 To ITEM_Count_Temp.GetLength(0) - 1
For y As Integer = 0 To ITEM_Count_Temp.GetLength(1) - 1
ITEM_Count(x, y) = ITEM_Count_Temp(x, y)
Next
Next
ITEM_Count(ITEM_Count.GetLength(0) - 1, 0) = Ticket.Item(Item)
ITEM_Count(ITEM_Count.GetLength(0) - 1, 1) = 1
Else
ITEM_Count(IsInIndex, 1) = ITEM_Count(IsInIndex, 1) + 1
End If
End If
Else
'IF NULL
End If
i = i + 1
Next
'CI_COUNT FILLING
'ORDERING BY COUNT
Dim ITEM_obj = New List(Of obj)
Dim ITEM_ToObj As String = ""
Dim ITEMCount_ToObj As String = ""
For x As Integer = 0 To ITEM_Count.GetLength(0) - 1
ITEM_ToObj = ITEM_Count(x, 0)
ITEMCount_ToObj = ITEM_Count(x, 1)
ITEM_obj.Add(New obj(ITEM_ToObj, ITEMCount_ToObj))
Next
ITEM_obj = OrderItem(ITEM_obj)
Dim Item_Count_listview As ListViewItem
For Each Itemobj As obj In ITEM_obj
Dim Transfer_Array(2) As String
Transfer_Array(0) = Itemobj.Item
Transfer_Array(1) = Itemobj.Item_Count
Item_Count_listview = New ListViewItem(Transfer_Array)
Select Case Item
Case "Product_Name"
CI_Count_Table.Items.Add(Item_Count_listview)
Case "Status"
Status_Count_Table.Items.Add(Item_Count_listview)
Case "Language"
Language_Count_Table.Items.Add(Item_Count_listview)
Case "Assigned_Group"
AssignedGroup_Count_Table.Items.Add(Item_Count_listview)
Case "Priority"
Priority_Count_Table.Items.Add(Item_Count_listview)
Case "Company"
LOB_Count_Table.Items.Add(Item_Count_listview)
Case Else
MsgBox("No Category Of this type exist. Programming Issue. Item is: " & Item)
End Select
Next
Next
End Sub
What is not possible to run into a background worker like this?
regards,

Need to create an edit control that acts like a terminal window

I need to create an edit control that takes each line, as entered, and goes off and does an action according to what was entered. I don't want the user to be able to delete what they typed into the box via their mouse and the delete key. It would look something like this:
Power On (user entered this)
Power: On Level:50 (what the power on command returned)
Laser On (user entered this )
Laser: On Power:60 ( what the command returned)
So I don't want them to go back and delete the lines already entered, they can just keep appending items and sending off these commands. Any ideas on how to accomplish this? Thanks.
I think your best bet would be creating a hybrid UserControl consisting of 2 Textbox's one which is readonly the other being writable. Enter your data in the one, append it to the other when the enter key is pressed, then append the response. Since you haven't stated a programming language here is an example in vb.net.
Public Class UserControl1
Private Sub TextBox2_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox2.KeyDown
If e.KeyCode = Keys.Enter Then
ScrollToEnd(TextBox1)
TextBox1.Text += TextBox2.Text + vbCrLf
TextBox1.Text += GetResponse(TextBox2.Text) + vbCrLf
TextBox2.Text = ""
ScrollToEnd(TextBox1)
e.SuppressKeyPress = True
End If
End Sub
Private Sub ScrollToEnd(tb As TextBox)
tb.SelectionStart = tb.TextLength
tb.ScrollToCaret()
End Sub
Private Function GetResponse(command As String) As String
Select Case command
Case "Power On"
Return "On Level: 50"
Case "Laser On"
Return "Laser: On Power:60"
Case Else
Return "I do not understand"
End Select
End Function
End Class
UserControl1.Designer.VB's InitializeComponent Method (I am only putting this in so you can see the properties of my Controls)
Private Sub InitializeComponent()
Me.TextBox1 = New System.Windows.Forms.TextBox()
Me.TextBox2 = New System.Windows.Forms.TextBox()
Me.TableLayoutPanel1 = New System.Windows.Forms.TableLayoutPanel()
Me.TableLayoutPanel1.SuspendLayout()
Me.SuspendLayout()
'
'TextBox1
'
Me.TextBox1.BackColor = System.Drawing.Color.Black
Me.TextBox1.BorderStyle = System.Windows.Forms.BorderStyle.None
Me.TextBox1.Dock = System.Windows.Forms.DockStyle.Fill
Me.TextBox1.ForeColor = System.Drawing.Color.Lime
Me.TextBox1.Location = New System.Drawing.Point(3, 3)
Me.TextBox1.Multiline = True
Me.TextBox1.Name = "TextBox1"
Me.TextBox1.ReadOnly = True
Me.TextBox1.Size = New System.Drawing.Size(253, 181)
Me.TextBox1.TabIndex = 0
Me.TextBox1.TabStop = False
'
'TextBox2
'
Me.TextBox2.BackColor = System.Drawing.Color.Black
Me.TextBox2.BorderStyle = System.Windows.Forms.BorderStyle.None
Me.TextBox2.Dock = System.Windows.Forms.DockStyle.Fill
Me.TextBox2.ForeColor = System.Drawing.Color.Lime
Me.TextBox2.Location = New System.Drawing.Point(3, 190)
Me.TextBox2.Name = "TextBox2"
Me.TextBox2.Size = New System.Drawing.Size(253, 17)
Me.TextBox2.TabIndex = 1
'
'TableLayoutPanel1
'
Me.TableLayoutPanel1.BackColor = System.Drawing.Color.Black
Me.TableLayoutPanel1.ColumnCount = 1
Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
Me.TableLayoutPanel1.Controls.Add(Me.TextBox1, 0, 0)
Me.TableLayoutPanel1.Controls.Add(Me.TextBox2, 0, 1)
Me.TableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill
Me.TableLayoutPanel1.Location = New System.Drawing.Point(0, 0)
Me.TableLayoutPanel1.Name = "TableLayoutPanel1"
Me.TableLayoutPanel1.RowCount = 2
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 89.09953!))
Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10.90047!))
Me.TableLayoutPanel1.Size = New System.Drawing.Size(259, 211)
Me.TableLayoutPanel1.TabIndex = 2
'
'UserControl1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 16.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.Controls.Add(Me.TableLayoutPanel1)
Me.Name = "UserControl1"
Me.Size = New System.Drawing.Size(259, 211)
Me.TableLayoutPanel1.ResumeLayout(False)
Me.TableLayoutPanel1.PerformLayout()
Me.ResumeLayout(False)
End Sub

My Program breaks randomly [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
My program randomly decides to quit working. No Error messages, just pressing the play buttom with nothing happens, and I check my card summary to find that The QuantityInteger to a corresponding player subtracted a card and added to discard pile, but didn't add a new card to their hand. However that is completely random as it works or doesn't work in randomly intervals.
T is sort of the heart of my code. Currently I only implemented it for two player mode. If T = 0 then it executes the code for player 1, if T = 1 it executes code for player 2.
The ChecksDynamic represents what the range will be on the For Loop, as those numbers represent the numbers valid to that players spot in the array.
The Atk Dialog represents which player you decide to attack.( can only atk one person in 2 player mode since you can't attack yourself).
T also places the different players quantity integers into a use case. The output variable of the usecase = player Assign to that specfic value of T.
Then I convert all players cards using a use case to make my code dynamic for the checkboxes checked for a specific player.
The If statement then sees if the checkbox is checked, and the quantity integer to the right player (SelectPlayer from the select case) is selected.
Then the hitpoints are subtracted based on card damage value.
If a card is a weapon the player has the option to keep the card or discard it.
If not discard nothing changes besides hitpoints.
In the GrabFromDeckandDiscard procedure I use T with a Select Case again to subract from the correct players item inventory
Then it adds the corresponding card to the discard pile
Then I run a function to randomly pick a card that is available in the deckgroup's quantity integer.
I run the Select case again to then add the need card from the randomly generated number to the corresponding players inventory.
Then the last major part involves switching T to the next value. For testing purposes I put a random label on my form, and use it to see the value of T. T doesn't seem to be failing from what I can tell.
Private Sub PlayButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PlayButton.Click
Dim CardCheckBoxArray() As CheckBox = {CardCheckBox1, CardCheckBox2, CardCheckBox3, CardCheckBox4, CardCheckBox5}
Dim HitPoints() As Label = {Nothing, HitPoints1, HitPoints2, HitPoints3, HitPoints4, HitPoints5}
Dim n, SelectPlayer As Integer
Label1.Text = T.ToString
'Player 1
If T = 0 And (CardCheckBoxArray(0).Checked = True Or CardCheckBoxArray(1).Checked = True Or CardCheckBoxArray(2).Checked = True Or CardCheckBoxArray(3).Checked = True Or CardCheckBoxArray(4).Checked = True) Then
AtkPlayerDialog.Player1.Enabled = False
AtkPlayerDialog.Player2.Enabled = True
AtkPlayerDialog.Player3.Enabled = True
AtkPlayerDialog.Player4.Enabled = True
AtkPlayerDialog.Player5.Enabled = True
ChecksDynamicA = 0
ChecksDynamicB = 4
'Player 2
ElseIf T = 1 And (CardCheckBoxArray(0).Checked = True Or CardCheckBoxArray(1).Checked = True Or CardCheckBoxArray(2).Checked = True Or CardCheckBoxArray(3).Checked = True Or CardCheckBoxArray(4).Checked = True) Then
AtkPlayerDialog.Player1.Enabled = True
AtkPlayerDialog.Player2.Enabled = False
AtkPlayerDialog.Player3.Enabled = True
AtkPlayerDialog.Player4.Enabled = True
AtkPlayerDialog.Player5.Enabled = True
ChecksDynamicA = 5
ChecksDynamicB = 9
'Player 3
ElseIf T = 2 And (CardCheckBoxArray(0).Checked = True Or CardCheckBoxArray(1).Checked = True Or CardCheckBoxArray(2).Checked = True Or CardCheckBoxArray(3).Checked = True Or CardCheckBoxArray(4).Checked = True) Then
AtkPlayerDialog.Player1.Enabled = True
AtkPlayerDialog.Player2.Enabled = True
AtkPlayerDialog.Player3.Enabled = False
AtkPlayerDialog.Player4.Enabled = True
AtkPlayerDialog.Player5.Enabled = True
ChecksDynamicA = 10
ChecksDynamicB = 14
'Player 4
ElseIf T = 3 And (CardCheckBoxArray(0).Checked = True Or CardCheckBoxArray(1).Checked = True Or CardCheckBoxArray(2).Checked = True Or CardCheckBoxArray(3).Checked = True Or CardCheckBoxArray(4).Checked = True) Then
AtkPlayerDialog.Player1.Enabled = True
AtkPlayerDialog.Player2.Enabled = True
AtkPlayerDialog.Player3.Enabled = True
AtkPlayerDialog.Player4.Enabled = False
AtkPlayerDialog.Player5.Enabled = True
ChecksDynamicA = 15
ChecksDynamicB = 19
'Player 5
ElseIf T = 4 And (CardCheckBoxArray(0).Checked = True Or CardCheckBoxArray(1).Checked = True Or CardCheckBoxArray(2).Checked = True Or CardCheckBoxArray(3).Checked = True Or CardCheckBoxArray(4).Checked = True) Then
AtkPlayerDialog.Player1.Enabled = True
AtkPlayerDialog.Player2.Enabled = True
AtkPlayerDialog.Player3.Enabled = True
AtkPlayerDialog.Player4.Enabled = True
AtkPlayerDialog.Player5.Enabled = False
ChecksDynamicA = 20
ChecksDynamicB = 24
End If
'Code for choosing which player to attack
AtkPlayerDialog.ShowDialog()
If AtkPlayerDialog.DialogResult = 1 Then
n = 1
ElseIf AtkPlayerDialog.DialogResult = 2 Then
n = 2
ElseIf AtkPlayerDialog.DialogResult = 3 Then
n = 3
ElseIf AtkPlayerDialog.DialogResult = 4 Then
n = 4
ElseIf AtkPlayerDialog.DialogResult = 5 Then
n = 5
End If
'CheckedLoop
For Me.Checks = ChecksDynamicA To ChecksDynamicB
'Supplement Numbers(1-5) variable in loop
NumberChecks = NumberArray(Checks)
'Select the Player
Select Case T
Case 0
SelectPlayer = Player1HandGroup(NumberChecks).QuantityInteger
Case 1
SelectPlayer = Player1HandGroup(NumberChecks).QuantityInteger2
Case 2
SelectPlayer = Player1HandGroup(NumberChecks).QuantityInteger3
Case 3
SelectPlayer = Player1HandGroup(NumberChecks).QuantityInteger4
Case 4
SelectPlayer = Player1HandGroup(NumberChecks).QuantityInteger5
End Select
'Convert arrays to correct textboxes
Select Case Checks
Case 0, 5, 10, 15, 20
TextBoxInteger = 0
Case 1, 6, 11, 16, 21
TextBoxInteger = 1
Case 2, 7, 12, 17, 22
TextBoxInteger = 2
Case 3, 8, 13, 18, 23
TextBoxInteger = 3
Case 4, 9, 14, 19, 24
TextBoxInteger = 4
End Select
'Play Card(s)
If CardCheckBoxArray(TextBoxInteger).Checked = True AndAlso SelectPlayer > 0 Then
'Subtract Hitpoints when damage is delt
Player1HandGroup(n).HitPoints -= Player1HandGroup(NumberChecks).DamageInteger
HitPoints(n).Text = Player1HandGroup(n).HitPoints.ToString
'When player plays hand, card quantity is removed from hand to the discard pile.
If Player1HandGroup(NumberChecks).CardType = "Weapon" Then
DiscardDialog.ShowDialog()
'Choose if to Discard Weapon after usage
If DiscardDialog.DialogResult = Windows.Forms.DialogResult.OK Then
Call GrabFromDeckAndDiscard()
End If
Else
Call GrabFromDeckAndDiscard()
End If
End If
ChecksLabel.Text = Checks.ToString
Next
Dim CardCheckBoxInteger As Integer
'Clear Check Boxes when turn is finished
For CardCheckBoxInteger = 0 To 4
CardCheckBoxArray(CardCheckBoxInteger).Checked = False
Next
'Turn off play button
PlayButton.Enabled = False
End Sub
Private Sub GrabFromDeckAndDiscard()
'ReDeclare CheckBox Array for Private sub
Dim n As Integer
Dim CardCheckBoxArray() As CheckBox = {CardCheckBox1, CardCheckBox2, CardCheckBox3, CardCheckBox4, CardCheckBox5}
'Discard
Select Case T
Case 0
Player1HandGroup(NumberChecks).QuantityInteger -= 1
Case 1
Player1HandGroup(NumberChecks).QuantityInteger2 -= 1
Case 2
Player1HandGroup(NumberChecks).QuantityInteger3 -= 1
Case 3
Player1HandGroup(NumberChecks).QuantityInteger4 -= 1
Case 4
Player1HandGroup(NumberChecks).QuantityInteger5 -= 1
End Select
'Add Card to Discard Pile
DiscardGroup(NumberChecks).QuantityInteger += 1
'Shuffle Deck from Discard Pile if Deck is out of cards
Call DiscardPile()
'Reset Number Generator, unless weapon isn't discard
Dim validDeckGroupsIndexes As New List(Of Integer)
For ndx As Integer = 0 To (DeckGroup.Count - 1)
If DeckGroup(ndx).QuantityInteger > 0 Then
validDeckGroupsIndexes.Add(ndx)
End If
Next ndx
Dim deckGroupNdx As Integer = Rnd.Next(0, validDeckGroupsIndexes.Count)
Number = DeckGroup(deckGroupNdx).ID
If DeckGroup(Number).QuantityInteger > 0 Then
'Grab New Card From Deck
DeckGroup(Number).QuantityInteger -= 1
Select Case T
Case 0
Player1HandGroup(NumberChecks).QuantityInteger += 1
Case 1
Player1HandGroup(NumberChecks).QuantityInteger2 += 1
Case 2
Player1HandGroup(NumberChecks).QuantityInteger3 += 1
Case 3
Player1HandGroup(NumberChecks).QuantityInteger4 += 1
Case 4
Player1HandGroup(NumberChecks).QuantityInteger5 += 1
End Select
' assign card type to chosen card and assign "number" to corresponding cards number as well
CardTypeArray(Checks) = Player1HandGroup(Number).CardType
NumberArray(Checks) = Number
End If
'Switch to next player
Select Case T
Case 0
For CardCheckBoxInteger = 0 To 4
Select Case CardCheckBoxInteger
Case 0
n = 5
Case 1
n = 6
Case 2
n = 7
Case 3
n = 8
Case 4
n = 9
End Select
CardCheckBoxArray(CardCheckBoxInteger).Text = Player1HandGroup(NumberArray(n)).CardNameString
Next
T += 1
Case 1
If GameSize = 2 Then
For CardCheckBoxInteger = 0 To 4
CardCheckBoxArray(CardCheckBoxInteger).Text = Player1HandGroup(NumberArray(CardCheckBoxInteger)).CardNameString
Next CardCheckBoxInteger
T -= 1
End If
If GameSize > 2 Then
T += 1
End If
Case 2
Case 3
Case 4
End Select
Label1.Text = T.ToString
End Sub
I think the solution will be easier to find if you clean up your code. For example, here are at least 20 lines removed by just a cursory glance.
Private Sub PlayButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PlayButton.Click
Dim CardCheckBoxArray() As CheckBox = {CardCheckBox1, CardCheckBox2, CardCheckBox3, CardCheckBox4, CardCheckBox5}
Dim HitPoints() As Label = {Nothing, HitPoints1, HitPoints2, HitPoints3, HitPoints4, HitPoints5}
Dim n, SelectPlayer As Integer
Label1.Text = T.ToString
'Player 1
If CardCheckBoxArray(0).Checked Or CardCheckBoxArray(1).Checked Or CardCheckBoxArray(2).Checked Or CardCheckBoxArray(3).Checked Or CardCheckBoxArray(4).Checked Then
AtkPlayerDialog.Player1.Enabled = Not (0=T)
AtkPlayerDialog.Player2.Enabled = Not (1=T)
AtkPlayerDialog.Player3.Enabled = Not (2=T)
AtkPlayerDialog.Player4.Enabled = Not (3=T)
AtkPlayerDialog.Player5.Enabled = Not (4=T)
ChecksDynamicA = 5 * T
ChecksDynamicB = 5 * T + 4
End If
'Code for choosing which player to attack
AtkPlayerDialog.ShowDialog()
n = AtkPlayerDialog.DialogResult
'CheckedLoop
For Me.Checks = ChecksDynamicA To ChecksDynamicB
'Supplement Numbers(1-5) variable in loop
NumberChecks = NumberArray(Checks)
'Select the Player
Select Case T
Case 0
SelectPlayer = Player1HandGroup(NumberChecks).QuantityInteger
Case 1
SelectPlayer = Player1HandGroup(NumberChecks).QuantityInteger2
Case 2
SelectPlayer = Player1HandGroup(NumberChecks).QuantityInteger3
Case 3
SelectPlayer = Player1HandGroup(NumberChecks).QuantityInteger4
Case 4
SelectPlayer = Player1HandGroup(NumberChecks).QuantityInteger5
End Select
'Convert arrays to correct textboxes
TextBoxInteger = Checks Mod 5
'Play Card(s)
If CardCheckBoxArray(TextBoxInteger).Checked AndAlso SelectPlayer > 0 Then
'Subtract Hitpoints when damage is delt
Player1HandGroup(n).HitPoints -= Player1HandGroup(NumberChecks).DamageInteger
HitPoints(n).Text = Player1HandGroup(n).HitPoints.ToString
'When player plays hand, card quantity is removed from hand to the discard pile.
If Player1HandGroup(NumberChecks).CardType.Equals("Weapon") Then
DiscardDialog.ShowDialog()
'Choose if to Discard Weapon after usage
If DiscardDialog.DialogResult = Windows.Forms.DialogResult.OK Then
Call GrabFromDeckAndDiscard()
End If
Else
Call GrabFromDeckAndDiscard()
End If
End If
ChecksLabel.Text = Checks.ToString
Next
Dim CardCheckBoxInteger As Integer
'Clear Check Boxes when turn is finished
For CardCheckBoxInteger = 0 To 4
CardCheckBoxArray(CardCheckBoxInteger).Checked = False
Next
'Turn off play button
PlayButton.Enabled = False
End Sub
And this one!
For CardCheckBoxInteger = 0 To 4
Select Case CardCheckBoxInteger
Case 0
n = 5
Case 1
n = 6
Case 2
n = 7
Case 3
n = 8
Case 4
n = 9
End Select
CardCheckBoxArray(CardCheckBoxInteger).Text = Player1HandGroup(NumberArray(n)).CardNameString
Next
Turn into:
For CardCheckBoxInteger = 0 To 4
CardCheckBoxArray(CardCheckBoxInteger).Text = Player1HandGroup(NumberArray(CardCheckBoxInteger+5)).CardNameString
Next

Resources