# VB Magic

## 2011/04/19

### Rolling the Dice

Filed under: .NET, VB.NET — Tags: , , , , — vbmagic @ 9:46 pm

Doing a game that is an RPG, one thing that I will always need to do is roll a dice. There may be better ways of introducing randomisation but rolling the dice is my preferred method. It was the best part of playing games like Dungeons and Dragons and Middle Earth Role Playing as a kid. We always used a certain way of writing down the dice formula to complete a certain action, for example:

2d6+1

Would mean that you would roll two six sided dice and then add one to the result. This formula has also stuck with me when I end up trying to write an RPG game. I once used a PICK operating system in one of my very early jobs to write a character generator in PICK Basic (Or Data Basic as it was also known) This piece of code seems to have followed me to multiple different operating systems and languages. I thought I would post the latest incarnation. A quick note, the FIELD function used was available in the PICK Basic Language it was used for manipulating strings, I did a .net version to make things easier for me 🙂

```
Module support

Public Function RollDice(value As String) As Integer
' setup working variables to make things easier
Dim tmp As String = ""
Dim modType As String = ""
Dim numberOfDice As Integer = 0
Dim numberOfSidesPerDice As Integer = 0
Dim modifier As Integer = 0
' First we check to see if there is a "d" in the string
If value.Contains("d") = True Then
' There is so first we need to get the value infront of the d
tmp = Field(value, "d"c, 1).Trim
' and convert it to an integer if it's a number, errors are silently
' ignored for now.
If Integer.TryParse(tmp, numberOfDice) = False Then
numberOfDice = 0
End If
' Now look at the value after the d
tmp = Field(value, "d"c, 2).Trim
' does it contain a + or a -?
If tmp.Contains("+") = True Then
modType = "+"
End If
If tmp.Contains("-") = True Then
modType = "-"
End If
' if does not contain a + or a -, then there is no modifer
If modType = "" Then
' and we take the right side of the d as the number of sides
' of the dice
If Integer.TryParse(tmp, numberOfSidesPerDice) = False Then
numberOfSidesPerDice = 0
End If
Else
' there is a + or a - so we need to extract the number on the left
' side of the +/-
Dim bit As String = Field(tmp, CChar(modType), 1).Trim
If Integer.TryParse(bit, numberOfSidesPerDice) = False Then
numberOfSidesPerDice = 0
End If
' now we take the right side of the +/- and set that to the modifier
bit = Field(tmp, CChar(modType), 2).Trim
If Integer.TryParse(bit, modifier) = False Then
modifier = 0
End If
End If
Else
' Ah so there is no d so we assume it's not a forumlar, just a number
numberOfDice = 0
numberOfSidesPerDice = 0
If Integer.TryParse(value, 0) = True Then
modifier = 0
Else
modifier = 0
End If
End If

' Now comes time to roll the dice
Dim lp As Integer
Dim total As Integer = 0
' Set up a random object randomised by the syystem date and time
Dim objRandom As New System.Random(CType(System.DateTime.Now.Ticks Mod System.Int32.MaxValue, Integer))
' loop through the number of dice
For lp = 1 To numberOfDice
' add each roll to the total
total = total + CInt(objRandom.Next(numberOfSidesPerDice) + 1)
Next
' now modify the total if needed
If modType = "+" Then
total += modifier
ElseIf modType = "-" Then
total -= modifier
End If
' we have the results of the dice roll
End Function

' Using the delimiter to split the string into chunks, return the pos chunk
' e.g. Field("1d6+1","d",2) would return "6+1"
Public Function Field(ByVal sourceString As String, ByVal delimiter As Char, ByVal pos As Integer) As String
Dim parts() As String = sourceString.Split(delimiter)
If pos > parts.Length Then
Return ""
Else
Return parts(pos - 1)
End If
End Function

End Module
```