Commands/Dice/New-Dice.ps1
function New-Dice { <# .SYNOPSIS Creates a new dice. .DESCRIPTION Creates a new dice, or returns an existing dice. .NOTES A dice is a simple table that represents a die. The table has a column for the roll number, the roll result, and the number of sides on the die. By describing a dice in a table, we can easily roll the dice, and keep track of the results. #> param( # The number of sides on the die. [Parameter(ValueFromPipelineByPropertyName)] [ValidateRange(2, [int]::MaxValue/2)] [Alias('Side','SideCount')] [int] $Sides = 2, # The name of the die. [Parameter(ValueFromPipelineByPropertyName)] [Alias('DiceName','DieName')] [string] $Name, # The faces of the die. Each face is a string that will can be displayed when the die is rolled. [Parameter(ValueFromPipelineByPropertyName)] [Alias('Faces')] [string[]] $Face ) process { # If the name is not provided, we will usually default to the number of sides. if (-not $name) { $name = switch ($sides) { # Special cases for coins and six-sided dice. 2 { 'coin' } 6 { 'Six-Sided-Dice' } default { "d$Sides" } } } # Check if the dice already exists by querying the dice table. $diceExists = $dice.DB.Tables['Dice'].Select("Sides = $sides") # If the dice does not exist, create a new dice. if (-not $diceExists) { $diceRoll = $dice.DB.Tables.Add($Name) $diceRoll.Columns.AddRange(@( # The roll number is an auto-incrementing number. $rollNumber = [Data.DataColumn]::new('N', [double], '', 'Attribute') $rollNumber.AutoIncrementSeed = 1 $rollNumber.AutoIncrement = $true $rollNumber.ReadOnly = $true $rollNumber # The roll result is a double. [Data.DataColumn]::new('Roll', [double], '', 'Attribute') # The number of sides is an int, and it is hidden from serialization. [Data.DataColumn]::new('Sides', [int], '', 'Hidden') )) # The roll number is the primary key. $diceRoll.PrimaryKey = @($diceRoll.Columns['N']) # Create a relationship between the dice and the dice roll. $diceRelationship = $dice.DB.Relations.Add( "DiceRoll$Name", $dice.DB.Tables['Dice'].Columns['Sides'], $diceRoll.Columns['Sides'] ) # nest the relationship, so that any generated content nests as well. $diceRelationship.Nested = $true # Set the default value for the sides column to the number of sides $diceRoll.Columns['Sides'].DefaultValue = $diceRow.Sides $diceRoll.Columns['Sides'].ReadOnly = $true # 'decorate' the dice with type typename 'Dice' $diceRoll.pstypenames.insert(0,'Dice') # If faces are provided, add them to the dice table. if ($Face) { # as the extended properties. $diceRoll.ExtendedProperties.Add('Faces', $Face) } # Add the new dice to the dice table. $newDice = $dice.DB.Tables['Dice'].Rows.Add($Name, $Sides) # 'decorate' the dice with type typename 'Dice' $newDice.pstypenames.insert(0,'Dice') # Return the new dice. $newDice } else { # If the dice already exists, return the existing dice. # Since it has already been decorated, it will have the 'Dice' type typename. $diceExists } } } |