I'm writing a game, and all my code works, however I'm looking for more efficient methods of writing my code.
Is there a more efficient way to write this particular piece of code
Select Case (N)
Case 1
If Player1HandGroup(14).QuantityInteger > 0 Or Player1HandGroup(17).QuantityInteger > 0 Or (Player1HandGroup(16).QuantityInteger > 0 And (IDbuster = 8 Or IDbuster = 9 Or _
IDbuster = 10 Or IDbuster = 11)) Then
DodgeBlockDisarmDialog.ShowDialog()
If DodgeBlockDisarmDialog.DialogResult = Windows.Forms.DialogResult.Cancel Or DodgeBlockDisarmDialog.DialogResult = Windows.Forms.DialogResult.OK Then
DodgeBlockDisarmDialog.PlayerTemp = T
End If
End If
Case 2
If Player1HandGroup(14).QuantityInteger2 > 0 Or Player1HandGroup(17).QuantityInteger2 > 0 Or (Player1HandGroup(16).QuantityInteger2 > 0 And (IDbuster = 8 Or IDbuster = 9 Or _
IDbuster = 10 Or IDbuster = 11)) Then
DodgeBlockDisarmDialog.ShowDialog()
If DodgeBlockDisarmDialog.DialogResult = Windows.Forms.DialogResult.Cancel Or DodgeBlockDisarmDialog.DialogResult = Windows.Forms.DialogResult.OK Then
DodgeBlockDisarmDialog.PlayerTemp = T
End If
End If
Case 3
If Player1HandGroup(14).QuantityInteger3 > 0 Or Player1HandGroup(17).QuantityInteger3 > 0 Or (Player1HandGroup(16).QuantityInteger3 > 0 And (IDbuster = 8 Or IDbuster = 9 Or _
IDbuster = 10 Or IDbuster = 11)) Then
DodgeBlockDisarmDialog.ShowDialog()
If DodgeBlockDisarmDialog.DialogResult = Windows.Forms.DialogResult.Cancel Or DodgeBlockDisarmDialog.DialogResult = Windows.Forms.DialogResult.OK Then
DodgeBlockDisarmDialog.PlayerTemp = T
End If
End If
Case 4
If Player1HandGroup(14).QuantityInteger4 > 0 Or Player1HandGroup(17).QuantityInteger4 > 0 Or (Player1HandGroup(16).QuantityInteger4 > 0 And (IDbuster = 8 Or IDbuster = 9 Or _
IDbuster = 10 Or IDbuster = 11)) Then
DodgeBlockDisarmDialog.ShowDialog()
If DodgeBlockDisarmDialog.DialogResult = Windows.Forms.DialogResult.Cancel Or DodgeBlockDisarmDialog.DialogResult = Windows.Forms.DialogResult.OK Then
DodgeBlockDisarmDialog.PlayerTemp = T
End If
End If
Case 5
If Player1HandGroup(14).QuantityInteger5 > 0 Or Player1HandGroup(17).QuantityInteger5 > 0 Or (Player1HandGroup(16).QuantityInteger5 > 0 And (IDbuster = 8 Or IDbuster = 9 Or _
IDbuster = 10 Or IDbuster = 11)) Then
DodgeBlockDisarmDialog.ShowDialog()
If DodgeBlockDisarmDialog.DialogResult = Windows.Forms.DialogResult.Cancel Or DodgeBlockDisarmDialog.DialogResult = Windows.Forms.DialogResult.OK Then
DodgeBlockDisarmDialog.PlayerTemp = T
End If
End If
End Select
The only difference between each case is:
N represents which player is chosen, then with the particular number of N I decide which Quantity integer in my Structure group to look at.
If there were a way to somehow reduce it to just 1 instance and add the "number" on the quantity integer dynamically, I feel it would really free up a lot of my code allthroughout my project.
Not sure what type Player1HandGroup(14) is, but I am mostly positive that it's of the same type as Player1HandGroup(17) and Player1HandGroup(16). So you could have a Sub that takes a parameter of type Function(of YourTypeOfPlayer1HandGroup), and then pass function(x) x.QuantityInteger into it, and so on.
IDbuster = 8 Or IDbuster = 9 Or IDbuster = 10 Or IDbuster = 11
Can be rewritten as:
{8,9,10,11}.Contains(IDbuster)
So your code would turn to something like this:
Select Case N
Case 1: DoProcessingWithProperty(Function(x) x.QuantityInteger)
Case 2: DoProcessingWithProperty(Function(x) x.QuantityInteger2)
Case 3: DoProcessingWithProperty(Function(x) x.QuantityInteger3)
Case 4: DoProcessingWithProperty(Function(x) x.QuantityInteger4)
Case 5: DoProcessingWithProperty(Function(x) x.QuantityInteger5)
End Select
Where
Sub DoProcessingWithProperty(f As Func(Of YourTypeOfPlayer1HandGroup))
If f(Player1HandGroup(14)) > 0 Or f(Player1HandGroup(17)) > 0 Or _
(f(Player1HandGroup(16)) > 0 And {8,9,10,11}.Contains(IDbuster)) Then
DodgeBlockDisarmDialog.ShowDialog()
If DodgeBlockDisarmDialog.DialogResult=Windows.Forms.DialogResult.Cancel Or _
DodgeBlockDisarmDialog.DialogResult=Windows.Forms.DialogResult.OK Then
DodgeBlockDisarmDialog.PlayerTemp = T
End If
End If
End Sub
This is a very generic refactoring (minimum impact), and it may not be the best way to refactor in your current situation, but it certainly makes it more readable.
Your current data structrue doesn't support healthy practices.
If you have N items of the same type in the same class:
Player1HandGroup(14).QuantityInteger
Player1HandGroup(14).QuantityInteger2
Player1HandGroup(14).QuantityInteger3
Player1HandGroup(14).QuantityInteger4
Player1HandGroup(14).QuantityInteger5
You should create a List(Of T) to hold that:
public class HandGroup
Public Property QuantityInteger As List(Of Integer)
...Etc...
End Class
Player1HandGroup(14).QuantityInteger(0)
Player1HandGroup(14).QuantityInteger(1)
Player1HandGroup(14).QuantityInteger(2)
...etc
That way you could do something like:
if Player1HandGroup(14).QuantityInteger(N) ... etc etc etc
Related
I have to know what language is used here. In which language do we define a variable as $value = x
Does this language have loop controls? I need this information, can any one provide?
Public sub Annual_Leave()
$Decimal_Output1 = 0 //variables
$Decimal_Output2 = 0
IF #ServiceMonths# = 1 OR #ServiceMonths# = 2 THEN
$Decimal_Output1 = 0
ELSEIF #ServiceMonths# => 3 AND #ServiceMonths# <= 12 THEN
IF #ServiceMonths# = 3 THEN
$Decimal_Output1 = 1.7
END IF
ELSE
$Decimal_Output1 = 21
$Decimal_Output2 = 0
END IF
End sub
I have a problem with my blackjack game in vb.net. This code I have will add the player's score perfectly, but when it comes to the dealer's score, it will not. It only takes the second card that the dealer has.
It is called with this:
addScore("p") 'add player's score
addScore("d") 'add dealer's score
And this is "addScore()":
Public Function card(player As String, index As Integer) As Label
Try
If player = "p" Then
Return GroupBox1.Controls.OfType(Of Label).Where(Function(l) l.Name = "YouCard" & index.ToString()).Single()
ElseIf player = "d" Then
Return GroupBox1.Controls.OfType(Of Label).Where(Function(l) l.Name = "DealerCard" & index.ToString()).Single()
End If
Catch
Return Nothing
End Try
End Function
Public Sub addScore(ByVal player As String)
Dim currScore As Integer
Dim result As Integer = 0
'Add Score
For value As Integer = 1 To 7
If card(player, value).Text = "A" AndAlso (currScore + 11) <= 21 Then
result = currScore + 11
ElseIf card(player, value).Text = "A" AndAlso (currScore + 1) <= 22 Then
result = currScore + 1
ElseIf IsNumeric(card(player, value).Text) Then
result = currScore + CInt(card(player, value).Text)
ElseIf card(player, value).Text = "" Then
result = result
Else
result = currScore + 10
End If
If player = "p" Then
YouScore.Text = result
Else
DealerScore.Text = result
End If
Next
End Sub
currScore shouldn't be there. Replace it with result
Public Sub addScore(ByVal player As String)
Dim result As Integer = 0
'Add Score
For value As Integer = 1 To 7
If card(player, value).Text = "A" AndAlso (result + 11) <= 21 Then
result = result + 11
ElseIf card(player, value).Text = "A" AndAlso (result + 1) <= 22 Then
result = result + 1
ElseIf IsNumeric(card(player, value).Text) Then
result = result + CInt(card(player, value).Text)
ElseIf card(player, value).Text = "" Then
result = result
Else
result = result + 10
End If
If player = "p" Then
YouScore.Text = result
Else
DealerScore.Text = result
End If
Next
End Sub
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am trying to create a tool using macro so that when few criteria are selected, a certain rating will be shown. There are three criteria that need to be filtered before getting the result.
For example, if the industry (eg. Agriculture) is selected, followed by selection of countries (e.g Indonesia), followed by selection of certain ratio (e.g. 2.5), a rating from 1 to 6 will be given (in this case, 3).
I tried the following code, nothing appears under my rating column but there is no error message. Is there anything missing in my code which causes no result happening?
Private Sub CommandButton1_Click()
If Range("V4").Value = "A.Agriculture,forestry and fishing" Then
If Range("W4").Value = All Or ID Or SG Then
If Range("D4").Value <= 0 Then
Range("X4").Value = 6
ElseIf Range("M4").Value > 4 Then
Range("X4").Value = 5
ElseIf Range("M4").Value <= 4 And Value > 2 Then
Range("X4").Value = 4
ElseIf Range("M4").Value <= 2 And Value > 1 Then
Range("X4").Value = 3
ElseIf Range("M4").Value <= 1 And Value > 0 Then
Range("X4").Value = 2
ElseIf Range("M4").Value <= 0 Then
Range("X4").Value = 1
End If
ElseIf Range("W4").Value = MY Or TH Then
If Range("D4").Value <= 0 Then
Range("X4").Value = 6
ElseIf Range("M4").Value > 4.5 Then
Range("X4").Value = 5
ElseIf Range("M4").Value <= 4.5 And Value > 2 Then
Range("X4").Value = 4
ElseIf Range("M4").Value <= 2 And Value > 1 Then
Range("X4").Value = 3
ElseIf Range("M4").Value <= 1 And Value > 0 Then
Range("X4").Value = 2
ElseIf Range("M4").Value <= 0 Then
Range("X4").Value = 1
End If
End If
End If
End Sub
Your If statements with Or are not properly formed. Additionally, a combination of If and Select Case statements would seem to be best for these multiple, nested conditions. This should also make your code mode readable.
If Range("W4").Value = "All" Or Range("W4").Value = "ID" Or Range("W4").Value = "SG" Then
VBA is case sensitive by default and strings need to be enclosed in quotes; e.g. All <> "All" and "ALL" <> "all". Best to use the LCase and UCase functions to compare "Apples" with "Apples".
Private Sub CommandButton1_Click()
If Range("V4").Value = "A.Agriculture,forestry and fishing" Then
Select Case LCase(Range("W4").Value)
Case "all", "id", "sg"
If Range("D4").Value <= 0 Then
Range("X4").Value = 6
Else
Select Case Range("M4").Value
Case Is > 4
Range("X4").Value = 5
Case 2.01 To 4
Range("X4").Value = 4
Case 1.01 To 2
Range("X4").Value = 3
Case 0.01 To 1
Range("X4").Value = 2
Case Is <= 0
Range("X4").Value = 1
Case Is > 4
Range("X4").Value = 6
End Select
End If
Case "my", "th"
If Range("D4").Value <= 0 Then
Range("X4").Value = 6
Else
Select Case Range("M4").Value
Case Is > 4.5
Range("X4").Value = 5
Case 2.01 To 4.5
Range("X4").Value = 4
Case 1.01 To 2
Range("X4").Value = 3
Case 0.01 To 1
Range("X4").Value = 2
Case Is <= 0
Range("X4").Value = 1
Case Is > 4
Range("X4").Value = 6
End Select
End If
End Select
End If
End Sub
Note that I have added a small decimal value to the between style Case statements in order to achieve the greater than and less than or equal to logic.
Add an Else case at the very end to handle errors. Chances are your If... ElseIf block isn't actually doing anything.
Also, because you are checking so many CASES, this looks like a great opportunity to re-structure your If... Then block to a Select... Case block..
Select [ Case ] testexpression 'stuff here
[ Case expression1 ]
[ statements ] ]
[ Case Else
[ elsestatements ] ]
End Select
more info - https://msdn.microsoft.com/en-us/library/cy37t14y.aspx for info.
So I'm learning visual basic and I'm trying to make a timer that moves an ovalshape, and checks if touches any other ovalshape, where it will invert an integer. So i have this code, which works, but i was wondering if i could shorten it. If you could explain your code aswell since i am pretty new that would be great! Thanks in advance!
Private Sub Timer4_Tick(sender As System.Object, e As System.EventArgs) Handles Timer4.Tick, Timer4.Tick
Dim Pos As Integer
If bb.Bounds.IntersectsWith(OvalShape1.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape2.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape3.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape4.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape5.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape6.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape7.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape8.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape9.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape10.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape11.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape12.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape13.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape14.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape15.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape16.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape17.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape18.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape19.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape20.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape21.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape22.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape23.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape24.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape25.Bounds) Then
Pos = -20
Else
Pos = 20
End If
If bb.Bounds.IntersectsWith(OvalShape26.Bounds) Then
Pos = -20
Else
Pos = 20
End If
bb.Top -= Pos
End Sub
You should refactor the repeated code out into one method, and create constants for your values to better explain what they mean:
Shared Function GetIntersection(Shape first, Shape second)
Const IntersectionValue = -20
Const NonIntersectionValue = 20
If first.Bounds.IntersectsWith(second.Bounds) Then
return IntersectionValue
Else
return NonIntersectionValue
End If
End Function
And then you would call it like this:
Dim Pos As Integer = GetIntersection(bb, OvalShape1)
This is an example of one of the important principles of good software design: Don't Repeat Yourself (D.R.Y).
The problem with your code, though -- regardless of whether you do it your way or the way I've proposed, is that you're never doing anything with the values -- you're overwriting the values with each subsequent operation. For example:
If bb.Bounds.IntersectsWith(OvalShape1.Bounds) Then
Pos = -20
Else
Pos = 20
End If
' you should at least do something with `Pos` assigned in the
' above if-else block before you overwrite it with the following if-else:
If bb.Bounds.IntersectsWith(OvalShape2.Bounds) Then
Pos = -20
Else
Pos = 20
End If
The way it is, though, it's only ever going to take the value for Pos of the very last if-else block
If bb.Bounds.IntersectsWith(OvalShape26.Bounds) Then '...
So then what's the point of the other blocks that come before it? They're just wasted overhead.
Help please, below is my code in Visual Basic.
My for loop does not go to the second if condition. It just checks for the first one. What am I missing here?
Thanks!
If Not dsMarketingOrdIDs Is Nothing Then
For i = 0 To dsMarketingOrdIDs.Tables(0).Rows.Count - 1
If dtMarketingOrdIDs.Rows(i)("marketing_org_id") = 5 Then
If Not objALUtil.CheckPermission("KBAUTHORXTREMESUPPORT") Then
blnKbAuthorXtremeSupport = True
End If
If dtMarketingOrdIDs.Rows(i)("marketing_org_id") = 152 Then
If Not objALUtil.CheckPermission("KBAUTHORXTREMEPORTAL") Then
blnKbAuthorXtremePortal = True
End If
End If
End If
Next
End If
Should be something like that:
If Not dsMarketingOrdIDs Is Nothing Then
For i = 0 To dsMarketingOrdIDs.Tables(0).Rows.Count - 1
If dtMarketingOrdIDs.Rows(i)("marketing_org_id") = 5 Then
If Not objALUtil.CheckPermission("KBAUTHORXTREMESUPPORT") Then
blnKbAuthorXtremeSupport = True
End If
End If
If dtMarketingOrdIDs.Rows(i)("marketing_org_id") = 152 Then
If Not objALUtil.CheckPermission("KBAUTHORXTREMEPORTAL") Then
blnKbAuthorXtremePortal = True
End If
End If
Next
End If
Or even easier:
If Not dsMarketingOrdIDs Is Nothing Then
For i = 0 To dsMarketingOrdIDs.Tables(0).Rows.Count - 1
blnKbAuthorXtremePortal = Not objALUtil.CheckPermission("KBAUTHORXTREMESUPPORT") _
AndAlso (dtMarketingOrdIDs.Rows(i)("marketing_org_id") = 5 OrElse dtMarketingOrdIDs.Rows(i)("marketing_org_id") = 152)
Next
End If
Have you tried an else if?
If Not dsMarketingOrdIDs Is Nothing Then
For i = 0 To dsMarketingOrdIDs.Tables(0).Rows.Count - 1
If dtMarketingOrdIDs.Rows(i)("marketing_org_id") = 5 Then
If Not objALUtil.CheckPermission("KBAUTHORXTREMESUPPORT") Then
blnKbAuthorXtremeSupport = True
Else If dtMarketingOrdIDs.Rows(i)("marketing_org_id") = 152 Then
If Not objALUtil.CheckPermission("KBAUTHORXTREMEPORTAL") Then
blnKbAuthorXtremePortal = True
End If
End If
End If
Next
End If
Also, how can your MARKETING_ORG_ID be 5 and 152 at once??
dtMarketingOrdIDs.Rows(i)("marketing_org_id") = 5
dtMarketingOrdIDs.Rows(i)("marketing_org_id") = 152