Powershell D&;D骰子模拟器
我想出了一个滚动策略,你滚动4d6,然后再滚动任何重复的。这导致数字介于10和18之间。这导致14是最常见的,10和18是最不常见的。若要指定,请保留其中一个副本,然后重新滚动其他副本。我在任何掷骰子应用程序/在线上都找不到这种方法。我正在PowerShell中尝试运行:Powershell D&;D骰子模拟器,powershell,random,Powershell,Random,我想出了一个滚动策略,你滚动4d6,然后再滚动任何重复的。这导致数字介于10和18之间。这导致14是最常见的,10和18是最不常见的。若要指定,请保留其中一个副本,然后重新滚动其他副本。我在任何掷骰子应用程序/在线上都找不到这种方法。我正在PowerShell中尝试运行: $A = Get-Random -Maximum 6 -Minimum 1 $B = Get-Random -Maximum 6 -Minimum 1 $C = Get-Random -Maximum 6 -Minimum 1
$A = Get-Random -Maximum 6 -Minimum 1
$B = Get-Random -Maximum 6 -Minimum 1
$C = Get-Random -Maximum 6 -Minimum 1
$D = Get-Random -Maximum 6 -Minimum 1
While ($A = $B) {
$B = Get-Random -Maximum 6 -Minimum 1
}
...
...
$Stat = $A+$B+$C+$D
但是$A和$B总是一样的,$C和$D总是一样的。谁能解释一下Get Random是如何工作的,并提出一个解决方案来解释为什么我的循环是无限的?这里有一个解决方案,用于任意数量的骰子,重新滚动直到唯一并返回一个数组
function RollDice {
param (
[ValidateRange(1,[int]::MaxValue)][parameter(Position = 0, Mandatory = $true)][int]$Amount,
[ValidateRange(1,[int]::MaxValue)][Alias('d')][int]$Sides
)
if ($Amount -gt $Sides) {
throw "Invalid parameter - The number of sides ($Sides) must be greater than the number of dice thrown ($Amount)"
}
[System.Collections.Generic.List[int]]$Results = @()
for ($DiceNum = 1; $DiceNum -le $Amount; $DiceNum++) {
while (!([int]$Roll) -or $Roll -in $Results) {
$Roll = Get-Random -Minimum 1 -Maximum ($Sides + 1) #Maximum pulls a number less than, not equal. See https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-random
}
$Results += $Roll
}
Return $Results
}
RollDice 4 -d 6
如果您将其视为一系列单独的骰子滚动,重复直到您看到4个不同的值(这正是它的含义),您可以将其建模为:
function Roll-4d6 {
# Use hashtable to keep track of face values
$uniqueRolls = @{}
# Keep rolling until we've seen 4 distinct faces
while($uniqueRolls.Count -lt 4){
# Roll the dice, make note of unique face value
$roll = 1..6 |Get-Random
$uniqueRolls[$roll] = $roll
}
# Calculate and return sum
return $uniqueRolls.Values |Measure-Object -Sum |Select-Object -ExpandProperty Sum
}
执行10K次将揭示在副本上重新滚动4d6的真实分布(与您预期的不完全相同):
一个简单的解释是,只有一种轧辊组合可以生产10(1,2,3,4
),11(1,2,3,5
),17(2,4,5,6
)和18(3,4,5,6
)
要通过单个采样模拟相同的分布,您可以执行以下操作:
$roll = 10, 11, 12, 12, 13, 13, 14, 14, 14, 15, 15, 16, 16, 17, 18 |Get-Random
关于
-最大值的注释
请注意,Get Random
的-Maximum
参数是一个排除项,因此对于6面骰子,您需要Get Random-最小1-最大7
以下是另一种使用列表且不需要重新滚动重复项的方法:
Function Roll {
# Die face values
$roll = [System.Collections.Generic.List[int]]@(1..6)
# Perform the required number of rolls
$values = 1..4 | Foreach-Object {
# Random roll
$r = Get-Random -InputObject $roll
# Remove rolled value from list to prevent duplicates
[void]$roll.Remove($r)
# return roll
$r
}
# Sum rolls
($values | Measure-Object -Sum).Sum
}
# Execute the rolls
Roll
# Output
16
=
用于赋值-eq
用于相等比较。因此,10、11、11、12、12、12、13、13、13、13、14、14、14、14、14、15、15、15、16、16、16、17、17、18 | Get Random
对于我想做的事情更为准确,如果不是出于它的精神……不,那是不准确的,我在答案中添加了一个示例,说明如何在一个语句中实现这一点
Function Roll {
# Die face values
$roll = [System.Collections.Generic.List[int]]@(1..6)
# Perform the required number of rolls
$values = 1..4 | Foreach-Object {
# Random roll
$r = Get-Random -InputObject $roll
# Remove rolled value from list to prevent duplicates
[void]$roll.Remove($r)
# return roll
$r
}
# Sum rolls
($values | Measure-Object -Sum).Sum
}
# Execute the rolls
Roll
# Output
16