Need help on figuring out dice game scoring logic - vb.net

So, we are creating a game in VB.net based off the game, Farkle. Basically, you roll an amount of dice and depending on what you keep is your score. We have eight dice. Here's an example, say you roll 3 "3"s and you want to score them, a three of a kind. We want to check all the dice together to see if we do have three 3's. We have figured out the two of a kind, but the three of a kind we cannot.
For l = 0 To 5
For o = 1 To 6
For q = 2 To 7
If (DieScore(l) = DieScore(o) And DieScore(l) = DieScore(q)) Then
PlayerScore = 200 + PlayerScore
End If
Next
Next
Next
This is our checking for three of a kind on the dice. If it is true we add 200 to the score. The DieScore(x) refer to the dice. Where are we going wrong?

You really just need to loop and count how many times that number of pips (spots) appears in the array.
Dim count As Integer = 0
For pips As Integer = 1 To 6
count = 0 ' reset count for each Pip iteration
For n As Integer = 0 To DieScore.Length - 1
' If operator version:
count += If(DieScore(n) = pips, 1, 0)
' If Statement version:
'If DieScore(n) = pips Then
' count += 1
'End If
Next
' scoring
Select Case count
Case 2 ' pair
playerscore += 50
Case 3 ' trips
playerscore += 200
If pips = 6 Then
playerscore += 25 ' extra bonus for 666 (example)
End If
Case 4 ' quads
playerscore += 350
' etc
End Select
Next
Not for nothing, but these kinds of logic issues are easy to find using the Debugger. Plus, you will learn a lot about how code executes.

For starters, please learn to use different, more descriptive variable names than l and o, that are easily confused with 1 and 0. Some famous bugs have been caused by doing things like that.
One thing you can do is simply count how many dots or pips there are in a roll of the dice and store that in an array.
' index 0 = 1 spot, 5 = 6 spots.
Dim pipsCount(6) as Integer
' This counts the number of dice for each possible "pips"
For dieIndex as Integer = 0 To DieScore.Length - 1
' Increment (the -1 is because index starts at 0)
pipsCount(DieScore(dieIndex)-1) += 1
Next
Now that you have the number of dice that landed headsup with a given number of pips, you can do a number of different things with that.
' You can easily find out now how many sixes were thrown:
Dim numberOfSixes As Integer = pipsCount(6-1)
' Or score pairs, trips, quads, ...
For pipsIndex As Integer = 0 To 5
Select Case pipsCount(pipsIndex)
Case 2
PlayerScore += 50
Case 3
PlayerScore += 200
' ... etc
End Select
Next
' Or count the length of a straight
Dim straightLength As Integer = If(pipsCount(0) > 0, 1, 0)
Dim longestStraight As Integer = straightLength
For pipsIndex As Integer = 1 To 5
If pipsCount(pipsIndex) > 0 Then
straightLength += 1
Else ' straight ended
If straightLength > longestStraight Then
longestStraight = straightLength
End If
straightLength = 0
End If
Next

Related

How Do I Count When Numbers Do Not Show Up

I have numbers from 1 to 25, four numbers will show up daily. I need to put a +1 on each of the four numbers and need to put a -1 on each of the 21 numbers didn't show up.
The four numbers that come up daily will be inputted in four different text boxes. The count being positive or negative needs to go on 25 separate text boxes labeled 1 thru 25.
I have tried "if textbox <> number, then count -= 1" but I get a count of -4 because it doesn't see the number in any of the four text boxes.
I only need a daily count not a textbox count. Sorry I don't have any code started and would greatly appreciate if someone can point me in the right direction. I'm doing this on Visual Studio 2012.
Thank you all for responding. Here is some code I've started but the count is not correct. My four input text boxes are in GroupBox2. Four numbers from 1 to 25 will draw daily like a lottery. The four numbers drawn will have a value of +1 each all others -1. I need to find the age of each number 1 thru 25. If a number has a +3 then that means that number has drawn 3 consecutive days. If a number has a -15 then that means that number has not drawn for the past 15 days.
Dim tb As New TextBox
Dim ctrl As Control
Dim Counter As Integer
For Each ctrl In GroupBox2.Controls
tb = ctrl
If tb.Text = 1 Then
Counter += 1
ElseIf tb.Text <> 1 Then
Counter -= 1
TextBox464.Text = Counter
End If
If tb.Text = 2 Then
Counter += 1
ElseIf tb.Text <> 2 Then
Counter -= 1
TextBox463.Text = Counter
End If
If tb.Text = 3 Then
Counter += 1
ElseIf tb.Text <> 3 Then
Counter -= 1
TextBox462.Text = Counter
End If
If tb.Text = 4 Then
Counter += 1
ElseIf tb.Text <> 4 Then
Counter -= 1
TextBox461.Text = Counter
End If
Next
We will need more information about how your going to approach it to be able to help you further, but as for your problem with this If Textbox <> number Then count -= 1 you can use something like this since your only going to be having numbers on the textboxes If Cint(Textbox.Text) <> number then count -= 1 since your using just Textbox its attempting to evaluate it as a control and not the property that your looking for, you need to read from its .Text Property, However since its evaluated as a String and not an Integer it will throw an error exception, thats why the Cint() is included (This may also be used to convert it to integer Ctype(number, Integer) Not sure if there is an execution speed difference or not, however Cint() is a faster way of writing it.) it will try and convert the String into an Integer and when its converted into an integer it can be evaluated like one using <>. No one is going to write a whole solution out for you, but while you attempt to create it yourself and more information can be added we are more than happy to help you with problems along the way.

Colouring datagrid rows

I was wondering how to colour the first 8 rows of a datagridview. I have managed to sort the values in descending order and I wish to have the first 8 rows coloured to highlight the top 8 to the user, and I'm not sure how to go about doing this.
Dim count As Integer
For count = 0 To datagridsort.RowCount - 1
Do
datagridsort.Rows(0).Cells(0).Style.BackColor = Color.Coral
datagridsort.Rows(0).Cells(1).Style.BackColor = Color.Coral
Loop Until count = 8
Next
In the code you posted in your comment, you were never using the count variable. You were only updated the first row every time. Try it like this:
For i As Integer = 0 To Math.Min(datagridsort.RowCount - 1, 7)
For j As Integer = 0 To datagridsort.ColumnCount - 1
datagridsort.Rows(i).Cells(j).Style.BackColor = Color.Coral
Next
Next

How to check if numbers match for if statement vb.net

Will you please give me a gide line on how to solve my current problem. I'm not sure how to put this in practice.
I have a counter which increase by one in a for statement
I want to add a if statment that needs to do the following:
Dim count as decimal = 1
For i As Integer = 1 To 400 - 1
If count = 3 or count = 6 or count = 9 or count = 12 ..and on and on
'All the numbers that mathes the count
Else
'All the numbers that does not match
End if
count += 1
Next
I want a simpaler method on how to write the If count = 3 or count = 6 and so on
If the count should be dividable by 3 without a rest (as it seems to be the case), you can use the Mod operator: Documentation
The Mod operator will divide 2 numbers and will return the remaining, so e.g 14 Mod 3 will be 2. So the only check, you need to do, is if count Mod 3 = 0 like:
Dim count as decimal = 1
For i As Integer = 1 To 400 - 1
If count Mod 3 = 0 then
'All the numbers that mathes the count
Else
'All the numbers that does not match
End if
count += 1
Next
1) Why do you have i and count which appear to always be the same value?
2) Two possible solutions: either the Mod operator as others have noted, assuming you actually want every third number, or:
For i As Integer = 1 To 400 - 1
Select Case i
Case 3,6,9,12,15....
'Do stuff here for matching
Case Else
'All the numbers that does not match
End Select
Next
Modulus is your friend.
number1 Mod number2
if count MOD 3 = 0
http://msdn.microsoft.com/en-us/library/se0w9esz(v=vs.90).aspx
I'm not sure about syntax, but you need to use Mod operator:
Dim count as decimal = 1
For i As Integer = 1 To 400 - 1
If (count Mod 3) = 0
'All the numbers that mathes the count
Else
'All the numbers that does not match
End if
count += 1
Next

Error code using Linq to add to a variable

I'll start with the problem, and then describe how the procedure works.
I'm getting a an error saying:
Value of type 'System.Collections.Generic.IEnumerable(Of LunchMoneyGame.LunchMoneyMainForm.Group)' cannot be converted to 'LunchMoneyGame.LunchMoneyMainForm.Group'.
The blue underline pinpointing the problem is on Dim obj As LunchMoneyGame.LunchMoneyMainForm.Group = From r In temp Where r.ID = Number Select r on the right side of the operator.
I know it is something to do with explicitness
--
This is for a table top card game i am converting to a text game.
The goal of this sub procedure is to subtract a card from a players hand and add it to the discard pile. Once added to the discard pile I then call the discard pile to move the cards from the discard pile to the card deck.
The problem starts with the number generator.
What I'm doing is randomly picking a card from the deck. by generating a the card id of a card in the deck. Once the ID is generated using linq the number generated then takes a card, then adds the card to the players inventory (quantity integer), and subtracts from the deck.
T represents whose turn it is. Currently for testing purposes I have coded it for only 2 players in terms of the T variable.
Private Sub GrabFromDeckAndDiscard()
Dim CardCheckBoxInteger As Integer
'ReDeclare CheckBox Array for Private sub
Dim CardCheckBoxArray() As CheckBox = {CardCheckBox1, CardCheckBox2, CardCheckBox3, CardCheckBox4, CardCheckBox5}
'Discard
Select Case T
Case 0
Player1HandGroup(NumberArray(Checks)).QuantityInteger -= 1
Case 1
Player1HandGroup(NumberArray(Checks)).QuantityInteger2 -= 1
Case 2
Player1HandGroup(NumberArray(Checks)).QuantityInteger3 -= 1
Case 3
Player1HandGroup(NumberArray(Checks)).QuantityInteger4 -= 1
Case 4
Player1HandGroup(NumberArray(Checks)).QuantityInteger5 -= 1
End Select
'Add Card to Discard Pile
DiscardGroup(NumberArray(Checks)).QuantityInteger += 1
'Shuffle Deck from Discard Pile if Deck is out of cards
Call DiscardPile()
'Reset Number Generator, unless weapon isn't discard
Dim temp As IEnumerable(Of LunchMoneyGame.LunchMoneyMainForm.Group) = From r In DeckGroup Where r.QuantityInteger > 0 Select r
If temp IsNot Nothing AndAlso temp.count > 0 Then
Number = (temp(Rnd.Next(0, temp.Count)).ID)
' ** Edit **: This will give you the actual object to be manipulated
Dim obj As LunchMoneyGame.LunchMoneyMainForm.Group = (From r In temp Where r.ID = Number Select r).Single
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
'Switch to next player
Select Case T
Case 0
For CardCheckBoxInteger = 0 To 4
CardCheckBoxArray(CardCheckBoxInteger).Text = Player1HandGroup(NumberArray(CardCheckBoxInteger + 5)).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
'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
From r In temp
Where r.ID = Number
Select r
Returns a collection of everything which matches the Where clause (see this for the MSDN documentation). .NET represents this as an IEnumerable, which means a collection of things which can be iterated over (e.g. using a For loop or something like that).
There is no automatic concept that you'll only get one record returned even though your condition is an = (there may also be conditions, broadly, where no elements are returned such as when nothing matches the equality condition or where multiple things match the equality condition).
In order to indicate that you only want one element you can use the First, Single, FirstOrDefault or SingleOrDefault methods.
For example:
Dim obj As LunchMoneyGame.LunchMoneyMainForm.Group = (From r In temp Where r.ID = Number Select r).Single()
Which will give you an object of type LunchMoneyGame.LunchMoneyMainForm.Group, which I think you're looking for in this case.
As an aside, it's not bad to know the difference between the methods I've outlined above. In my lay perspective (as I'm no expert):
First returns the first item in the collection or throws an Exception if the collection is empty
FirstOrDefault returns the first item in the collection or null if empty
Single returns the only item in the collection or throws an Exception if the collection does not have exactly one item
SingleOrDefault returns the first item in the collection, null if the collection is empty and throws an exception if the collection has more than 1 element
So in your case, since you should only match on a single item with the = condition I would suggest using Single or SingleOrDefault
PS. Sorry, when I say null above, that'll be Nothing in VB.NET speak

Calculating the sum of number difference within a for loop in vb.net

I have a dataset which includes some numbers, I want to calculate the sum of the difference in the numbers how do I do this?
For example my dataset looks like this:
Name Score
Luke 100
Adam 90
James 80
Peter 70
Mike 60
How do I calculate the sum of the difference within a “for loop” in vb.net such that it does something like this below:
(100 - 90) + (90 – 80) + (80 – 70) + (70 – 60) = 40
I tried to do this below, but i am not sure of how to add the difference:
Dim i as integer
For i = 0 to ds.tables(0).rows.count
ds.tables(0).Row(i).Item(1)
Dim diff = ds.tables(0).Row(i).Item(1) - ds.tables(0).Row(i+1).Item(1)
sum = ....
Next
Any help will be appreciated
You can try this,
Dim totalValue As Integer = 0
For index = 1 To ds.Tables(0).Rows.Count
totalValue += (CInt(ds.Tables(0).Rows(index - 1).Item(1)) - CInt(ds.Tables(0).Rows(index).Item(1)))
Next
You can use totalValue as your answer
First, you need to stop the loop before you reach the count, otherwise you will receive an exception.
Second, you need to add a special case for the first item:
' The sum of the differences
Dim wSumOfDifferences As Integer
' Start with a non-sensical value for the last value that we processed
Dim wLastValue As Integer = -1
For Each oRow As DataRow in ds.Tables(0).Rows
Dim wCurrValue As Integer
' Get the current value
wCurrValue = CInt(oRow.Item(1))
' If we are not working on the first item, calculate the difference between
' the current value and the last value
If wLastValue <> -1 Then
wSumOfDifferences += (wLastValue - wCurrValue)
End If
' Record the current value as the last value
wLastValue = wCurrValue
Next
Console.WriteLine("Sum = " & CStr(wSumOfDifferences))