How to enable/disable button with a function - vb.net

I have a problem with my university project
It's a little game, 6 buttons for each players and 2 players so 12 buttons
There is number in each buttons, if a player has his 6 buttons at 0, he can't play
I have try some Public Function and i'm actually working with a very simple one but i think this is not the problem
My function is here
And in my form, the problem is here, i've tried many things but i don't know how do to that ... I read my lesson and I'm searching on the internet, i have no idea ..

If possible is True you don't re-enable the button.
You can simplify things.
Public Function PeutJouer(ByVal joueur As Integer) As Boolean
Dim sum As Integer
Dim start As Integer = (joueur - 1) * 7
For i As Integer = start To start + 5
sum += tableau(i)
Next
Return sum <> 0
End Function
Then
Btn1P1.Enabled = PeutJouer(1)
Did you show all the relevant code? You are declaring Dim tableau(12) As Integer but the array is never filled with values. Probably tableau should be declared at the form level and not locally in this function. If you already have both, remove the local declaration, because it hides the one at form level. You also need to return the result from the function. I don't see this in your function.
Note that this
If x <> 0 Then
booleanVariable = True
Else
booleanVariable = True
End If
can be simplified to
booleanVariable = x <> 0
i.e., the condition is an expression yielding the Boolean result True or False already and you can use this value directly. When working with numeric values you don't write If x + y = 1 Then r = 1 Else If x + y = 2 Then r = 2 .... You simply write r = x + y.

Related

my compare statement not working in vb.net

I was doing an exam algorithm earlier (Just started vb 5 days ago so be nice ;) ) and I realised after testing that for whatever reason my statement If 0 < CInt(Num(x)) < 10 was not working which completely baffled me as I would thinkk that of all things THIS would be the easiest but no. No matter what I did, it just would always be true even if I made Num(X) = 90 or 9000000 it wouldn't matter, so if anyone knows what obvious mistake I have made whether its because I made it a string or what let me know :)
Dim Num(2), INPUT As String
Dim Cond As Boolean = False
Dim Valid As Boolean = False
Dim Isnum As Boolean
Dim x, Number, IsTen As Integer
While Cond = False
Do Until IsTen = 3 And Number = 3
IsTen = 0
Number = 0
For x = 0 To 2
MsgBox("Please enter a number")
Num(x) = (Console.ReadLine)
Isnum = IsNumeric(Num(x))
If Isnum = True Then
IsTen = IsTen + 1
End If
If Isnum = True Then
If 0 < CInt(Num(x)) < 10 Then
Number = Number + 1
End If
End If
Next
If Number <> 3 Then
MsgBox("Sorry all three numbers werent between 0 and 10, Please enter again")
End If
If IsTen <> 3 Then
MsgBox("Sorry all three inputs werent numbers, Please enter again")
End If
Loop
MsgBox("All three numbers are valid")
End While
First thing I would advise is setting Option Strict On at the top of your code file. You can also make this the default via Visual Studio options. This will warn you about the implicit type conversion that is causing your problem.
Changing the line
If 0 < CInt(Num(x)) < 10 Then
I'm assuming the intent here is to ensure the number is greater than 1 but less than 10
To something like this:
If Isnum = True Then
Dim val As Integer = Integer.Parse(Num(x))
If (val > 0) AndAlso (val < 10) Then
Number = Number + 1
End If
End If
Notice the use of Integer.Parse() to type cast the string to Int, it's a little more robust but there is also the Integer.TryParse() which is another step up again, might be worth reading up on. Also notice AndAlso usage, this is a short circuit operator so if the First condition is false, doesn't bother evaluating the next.

Poker Hand evaluation through LINQ

I am creating a poker game - Texas Holdem (5 cards on the table and 2 cards for myself).
I've already created flush, straight and straight flush functions and I got stuck on evaluating if the hand has a:
1. Four of a kind
2. Three of a kind
3. Full house
4. Two pairs
5. One pair
I believe I can write one function for all of the above, that will return a corresponding string.
I have created a list that holds list of Cards (7 cards)
Class Card has a property cardNumber of Integer type (Ace = 1, Two = 2, Three = 3 etc)
Here is my function:
Public Shared Function ofAKind(hand As List(Of Card)) As String
Dim result As String = ""
Dim counter As Integer
Dim IntegerList As New List(Of Integer)
'creating a list of integers that are representing faces of cards
Do
IntegerList.Add(hand.Item(counter).cardNumber)
counter += 1
Loop Until counter = hand.Count
Dim groupedIntegers = From Int In IntegerList
Group By Int
Into grouping = Group, Count()
'and here is my problem: how can I make such a grouping? below is just pseudocode.
'When using a debugger, I see that it groups them well. It is just that I do not know
'how to use LINQ to extract that grouping into the below if statement and get a corresponding string.
'if grouping = 4 Then
'result = "Four of a kind"
'if grouping = 3 andAlso grouping = 2 Then
'result = "Full House"
'if grouping = 2 andAlso grouping = 2 Then
'result = "Two Pairs"
'if grouping = 2 Then
'result = "Pair"
Return result
End Function
For the lack of being able to comment.
Possibly String.Concat all of the card Values together (with whitespace in-between each) and use a Regex.Matches(...) with match code "\d" to match the Numbers
Then Array.ForEach(...) for the Groups() with an in-line If[...] to count the occurrences in each group and test if it has particular combinations of matches.
It may be a little tedious, and a long in-line Linq, but just a thought :p
I figured it out. I am sure it can be done in a cleaner way, but it worked for me. At this phase of my programming discovery - this is a next milestone achieved. Thanks to Plutonix. Appreciate it.
Public Function ofAKind(IntegerList As List(Of Integer)) As String
Dim result As String = "YES"
Dim groupedIntegerList As New List(Of Integer)
Dim groupedIntegers = From Int In IntegerList
Group By Int
Into LOL = Group, Count()
'creating another list (I am sure there is a cleaner way, but I don't know it yet)
For Each e In groupedIntegers
groupedIntegerList.Add(e.Count)
Next
If groupedIntegerList.Contains(3) And groupedIntegerList.Contains(2) Then
result = "Fullhouse!"
ElseIf groupedIntegerList.Contains(4) Then
result = "Four of a kind!"
ElseIf groupedIntegerList.Contains(3) Then
result = "Three of a kind"
ElseIf groupedIntegerList.Contains(2) Then
result = "Pair!"
End If
'ugly way to search for two pairs (but it works)
If result = "Pair!" Then
Dim searchingForTwoPairs = From int In groupedIntegerList
Where int > 1
Group By int
Into LOL2 = Group, Count()
Dim twoPairsList As New List(Of Integer)
For Each e In searchingForTwoPairs
twoPairsList.Add(e.Count)
Next
If twoPairsList.Contains(2) Or twoPairsList.Contains(3) Then
result = "Two pairs!"
End If
End If
Return result
End Function

Looping through only columns containing values for specific row in dataTable

I am developing an application using Visual Basic 2010 for hydraulic calculations of a pipe network.
This application uses a lot of iterations and loops, depending on the user input and size of network. Most of the results have to be saved temporarily to be used for the next step of calculations.
Firstly, I used a DataGridView to save the results but as the number of iterations increased, the application became very slow.
Now I am trying to create a DataTable, then populate it with some initial results (this part was successful). The obtained DataTable has some columns that are not populated like so:
22 24 10
3 16 22 9 15
16 12 24 13
14 21 10 23 12 1
24 18 23 2 1
Other calculations are performed and a certain value (X) is obtained.
Now I am trying to loop through the columns of a specific row to check if the calculated value (X) equals to one of the values in those columns.
My question is: How can I loop through only the columns that have values (avoiding the columns containing NULL values) for a specific row?
I am a beginner in VB.net. I hope my question is clear as I didn't provide any code.
Thanks in advance for you help.
This is the initial code I used:
Results.DGVInitial.Rows.Clear()
Results.DGVFinal.Rows.Clear()
For m As Integer = 0 To NetworkLayout.DGVNetworkLayout.Rows.Count - 1
Results.DGVInitial.Rows.Add()
Next
Dim I As Integer = NetworkLayout.DGVNetworkLayout.Rows.Count - 1
Dim Sec(I), Ini(I) As Integer
Dim Hyd(I), Dia(I), Len(I) As Single
Dim Qsec(I), Qini(I), Vsec(I) As Single
Dim U(I), Y(I) As Single
Do
I = I - 1
Sec(I) = NetworkLayout.DGVNetworkLayout.Rows(I).Cells(0).Value
Ini(I) = NetworkLayout.DGVNetworkLayout.Rows(I).Cells(1).Value
Hyd(I) = NetworkLayout.DGVNetworkLayout.Rows(I).Cells(6).Value
Dia(I) = NetworkLayout.DGVNetworkLayout.Rows(I).Cells(4).Value
Len(I) = NetworkLayout.DGVNetworkLayout.Rows(I).Cells(3).Value
Dim V As Integer
V = Results.DGVRandomGen.Rows(TotalNum_Runs - 1).Cells(I).Value
Qsec(I) = 0
Dim q As Single = 0
For n As Integer = 0 To Results.DGVInitial.Rows.Count - 1
If Results.DGVInitial.Rows(n).Cells(1).Value = Sec(I) Then
q = Results.DGVInitial.Rows(n).Cells(0).Value
Qsec(I) = Qsec(I) + q
Else
Qsec(I) = Qsec(I)
End If
Next
If V = 1 Then ' if the hydrant is open
Qini(I) = Hyd(I) + Qsec(I)
Else ' if the hydrant is close
Qini(I) = Qsec(I)
End If
Results.DGVInitial.Rows(I).Cells(0).Value = Qini(I)
Results.DGVInitial.Rows(I).Cells(1).Value = Ini(I)
Results.DGVSectionDischarges.Rows(TotalNum_Runs - 1).Cells(I).Value = ini(I).ToString("F2")
Now instead of using
V = Results.DGVRandomGen.Rows(TotalNum_Runs - 1).Cells(I).Value
I would like to replace the "DGVRandomGen" with a DataTable called "DT_Random"
Like I said I am a beginner so I am not sure how to code it but it will be something like this:
For DT_Random.Rows (TotalNum_Runs - 1)
For Each col As DataColumn In DT_Random.Columns
If DT_Random.Rows(TotalNum_Runs - 1).Item(col) = I Then
Qini(I) = Hyd(I) + Qsec(I)
Else
Qini(I) = Qsec(I)
End If
Next
But I want to avoid Null values as not all columns are populated
Thanks
Maybe this will help you:
Dim myXvalue = 24
Dim myDataTable As New DataTable
myDataTable.Columns.Add("Col1")
myDataTable.Columns.Add("Col2")
myDataTable.Columns.Add("Col3")
myDataTable.Columns.Add("Col4")
myDataTable.Rows.Add(22, 24, 10, DBNull.Value)
myDataTable.Rows.Add(3, 16, 22, DBNull.Value)
myDataTable.Rows.Add(24, 18, DBNull.Value, 24)
For Each column As DataColumn In myDataTable.Columns
If IsDBNull(myDataTable.Rows(0).Item(column)) Then
MsgBox("DB Null Found At: " & column.ColumnName)
Continue For
End If
If myDataTable.Rows(0).Item(column) = myXvalue Then
MsgBox("Match: " & myDataTable.Rows(0).Item(column) & " found at " & column.ColumnName)
End If
Next column
Just a quick example, you may need to restructure it a bit, but at least it shows you how to access the values in your datatable by columns. I would do a function that passes a row index as a parameter and returns a boolean. Create two booleans inside the sub, one for dbnull existing in the row, and one for finding a matching value. If dbnull bool is false, and match value is true, then return true. Just make sure you loop all the columns and dont exit early.
If you need me to elaborate let me know.

How to not generate a stack overflow when a sub procedure calls itself?

This code generates a stack overflow. I'm aware it is caused by the procedure calling itself.
What can I do to avoid the stack overflow? Recalling the sub procedure and generating a new random number is the easiest thing to do, however it generates the overflow. The randomly generated number picks a random inventory item, then the if statement matches that number (random inventory item) with the quantity of that item from the deck inventory to make sure it isn't less than 1. If the inventory of that item is 0, the else plays and restarts the procedure, generating a new random number and doing the process all over again. In another procedure I have a function that if the deck's inventory becomes completely empty, then the discard pile replenishes the deck, making the discard pile empty, so there should never be a case where all randomly generated numbers can be associated item with a inventory of 0.
I wonder if I could somehow force the random number generator
Number = (DeckGroup(Rnd.Next(0, DeckGroup.Count)).ID)
not to generate numbers to inventory items DeckGroup(Number).QuantityInteger that are zero. By doing so I wouldn't even need to recall the function.
The random number is generated by a different branch in the same structure group.
Private Sub PlayElse()
Dim CardCheckBoxArray() As CheckBox = {CardCheckBox1, CardCheckBox2, CardCheckBox3, CardCheckBox4, CardCheckBox5}
'Reset Number Generator
Number = (DeckGroup(Rnd.Next(0, DeckGroup.Count)).ID)
Dim PlayerQuantitySubtractionInteger As Integer
For PlayerQuantitySubtractionInteger = ChecksDynamicA To ChecksDynamicB
If CardCheckBoxArray(TextBoxInteger).Checked = True And DeckGroup(Number).QuantityInteger > 0 Then
DeckGroup(Number).QuantityInteger -= 1
'Select the Player depending value of T
Select Case T
Case 0
Player1HandGroup(Number).QuantityInteger += 1
Case 1
Player1HandGroup(Number).QuantityInteger2 += 1
Case 2
Player1HandGroup(Number).QuantityInteger3 += 1
Case 3
Player1HandGroup(Number).QuantityInteger4 += 1
Case 4
Player1HandGroup(Number).QuantityInteger5 += 1
End Select
CardTypeArray(PlayerQuantitySubtractionInteger) = Player1HandGroup(Number).CardType
CardCheckBoxArray(TextBoxInteger).Text = Player1HandGroup(Number).CardNameString
NumberArray(PlayerQuantitySubtractionInteger) = Number
Else
If CardCheckBoxArray(TextBoxInteger).Checked = True And DeckGroup(Number).QuantityInteger < 0 Then
Call PlayElse()
End If
End If
Next PlayerQuantitySubtractionInteger
End Sub
You could use LINQ to weed out all the objects you never want to get first and then use the collection returned by the linq instead of your original collection.
Something like:
Private Sub PlayElse()
Dim CardCheckBoxArray() As CheckBox = {CardCheckBox1, CardCheckBox2, CardCheckBox3, CardCheckBox4, CardCheckBox5}
'Reset Number Generator
Dim temp As IEnumerable(Of LunchMoneyGame.LunchMoneyMainForm.Group) = From r In DeckGroup Where r.QuantityInteger > 0 Select r
If temp IsNot Nothing AndAlso temp.Any Then
Number = (temp(Rnd.Next(0, temp.Count)).ID)
' ** Edit **: This will ensure that you only got 1 object back from the LINQ which can tell you whether or not you have bad data. You *can* exclude this check but its good practice to include it.
Dim obj As LunchMoneyGame.LunchMoneyMainForm.Group = Nothing
Dim t = From r In temp Where r.ID = Number Select r
If t IsNot Nothing AndAlso t.Count = 1 Then
obj = t(0)
End If
If obj IsNot Nothing Then
Dim PlayerQuantitySubtractionInteger As Integer
For PlayerQuantitySubtractionInteger = ChecksDynamicA To ChecksDynamicB
' ** Edit **
obj.QuantityInteger -= 1
'Select the Player depending value of T
Select Case T
Case 0
Player1HandGroup(Number).QuantityInteger += 1
Case 1
Player1HandGroup(Number).QuantityInteger2 += 1
Case 2
Player1HandGroup(Number).QuantityInteger3 += 1
Case 3
Player1HandGroup(Number).QuantityInteger4 += 1
Case 4
Player1HandGroup(Number).QuantityInteger5 += 1
End Select
CardTypeArray(PlayerQuantitySubtractionInteger) = Player1HandGroup(Number).CardType
CardCheckBoxArray(TextBoxInteger).Text = Player1HandGroup(Number).CardNameString
NumberArray(PlayerQuantitySubtractionInteger) = Number
Next PlayerQuantitySubtractionInteger
End If
End If
End Sub
Pass through the list and determine only those that are valid. Then randomly pull from that set. Here is a simple version of it. You could use LINQ as well, but this should be clear enough:
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
Then use this:
Dim deckGroupNdx As Integer = Rnd.Next(0, validDeckGroupsIndexes.Count)
Number = DeckGroup(deckGroupNdx).ID

How to Find out if an items is not in an array

Ok i just want to know if value x is not in my array
Heres what i have been trying
Im using VB.net
and just need to know when x isnt in the array so i can take an action. thankx
Dim L, Path(0) As Integer
Open = cleara(Open)
sealed = cleara(sealed)
Open(0) = Agent
sealed(0) = Agent
Finds adjacent nodes
L = Agent
Do Until sealed(sealed.GetLength(0) - 1) = Targ Or Open.GetLength(0) = 0
'Agents(0) = L
H = Find_H(L, Targ, Open)
'T = Find_T(L, Targ, Open)
ReDim F(T.GetLength(0) - 1)
For lp As Integer = 0 To F.GetLength(0) - 1
F(lp) = H(lp) '+ H(lp)
Next
L = Find_lowest(F, Open)
Open = Remove_from(Open, L)
sealed = Add_to(sealed, L)
Ad = Find_adjacent(L, Targ)
For lp As Integer = 0 To Ad.GetLength(0) - 1
Ok here is where my problems is
What i need to do is
find out if ad is in seal if yes ignore it
If ad isnt in sealed the if it is in open compare T values
if ad isn in sealed or open then add it to open and set L as parent of ad
The below was a way to test and see if the values were loading into the arrays right
If Walk(Ad(lp)) <> -1 Then
Parents(Ad(lp)) = L
Open = Add_to(Open, Ad(lp))
For lp2 As Integer = 0 To sealed.GetLength(0) - 1
For lp3 As Integer = 0 To Open.GetLength(0) - 1
If lp3 < Open.GetLength(0) - 1 Then
If Open(lp3) = sealed(lp2) Then
Open = Remove_from(Open, sealed(lp2))
End If
End If
Next
Next
End If
Next
G.Graphics.DrawRectangle(Pens.White, Grid(Targ))
TempDrawing()
Loop
This is suppost to be an a* program but i have been having trouble main with my heuistics if you can tell me what im doing wrong it would also be a great help
Here is how this work so far
Add my location to open
Create H,G,F for items in open list
Find lowest F
Find adjacent nodes
Loop through nodes
If node is not walkable then ignore
If in sealed ignore (this is where im stuck at)
If not in sealed and is walkable then if in open compare G scores else add to open
try this
If Array.IndexOf(yourArray, x) == -1 Then
'Do something
End If
This need to be for -
For lp as integer = 0 to array.getlength(0) - 1
^ error. Needs to array.GetLength()
Also, if a number is found, you can print it and break from the loop. There is no need to iterate further in the loop.
You need to be careful, the variable that is used as a flag( i.e., g) is different from the variable actually setting a value to it. ( i.e., G )
You forgot to assign initial value to g outside of the for loop.
Try this.
Dim g as int
g = 0
For lp as integer = 0 to array.Length() - 1
If X = array(LP) Then
g = 1
Exit For
End If
next
If g = 0 Then
X is not in array
End If
Use the Enumerable.Except method to get all points in one enumerable collection that are also present in a second collection.
Here is an example taken from the MSDN documentation of the method:
' Create two arrays of doubles.
Dim numbers1() As Double = {2.0, 2.1, 2.2, 2.3, 2.4, 2.5}
Dim numbers2() As Double = {2.2}
' Select the elements from the first array that are not
' in the second array.
Dim onlyInFirstSet As IEnumerable(Of Double) = numbers1.Except(numbers2)
Dim output As New System.Text.StringBuilder
For Each number As Double In onlyInFirstSet
output.AppendLine(number)
Next
' Display the output.
MsgBox(output.ToString())
' This code produces the following output:
'
' 2
' 2.1
' 2.3
' 2.4
' 2.5