实现Roll and Keep骰子系统:从数组中选取指定数量最大数值
I totally get where you're stuck—when you have duplicate dice values, your current code is probably picking the same value multiple times without accounting for each die being a unique instance. Let's fix that so you can correctly grab the top K dice from your roll array, no double-dipping allowed.
Approach 1: Sort the Array Descending and Grab the Top K Elements
This is the simplest method. By sorting your dice roll array from highest to lowest, you can just take the first K elements—each one is a unique die roll, even if values repeat.
Here's how to implement it:
Function RollAndKeep(totalDice As Integer, keepDice As Integer) As Integer Dim rolls() As Integer ReDim rolls(1 To totalDice) ' Roll the dice (your existing roll logic) Dim i As Integer For i = 1 To totalDice rolls(i) = Int((6 * Rnd) + 1) ' Adjust the 6 if using non-d6 dice Next i ' Sort the array in descending order Dim temp As Integer Dim j As Integer For i = 1 To totalDice - 1 For j = i + 1 To totalDice If rolls(i) < rolls(j) Then temp = rolls(i) rolls(i) = rolls(j) rolls(j) = temp End If Next j Next i ' Sum the top K elements Dim sum As Integer sum = 0 For i = 1 To keepDice sum = sum + rolls(i) Next i RollAndKeep = sum End Function
Approach 2: Iteratively Find and Remove the Max Value (Preserves Original Array)
If you don't want to modify the original roll array, you can create a copy, then repeatedly find the maximum value, add it to your sum, and "remove" it from the copy (by setting it to a value lower than any possible die roll, like 0).
Function RollAndKeepPreserve(totalDice As Integer, keepDice As Integer) As Integer Dim rolls() As Integer ReDim rolls(1 To totalDice) ' Roll the dice (same as your existing logic) Dim i As Integer For i = 1 To totalDice rolls(i) = Int((6 * Rnd) + 1) Next i ' Create a copy of the array to modify Dim rollCopy() As Integer rollCopy = rolls Dim sum As Integer sum = 0 Dim currentMax As Integer Dim maxIndex As Integer For i = 1 To keepDice currentMax = 0 maxIndex = 0 ' Find the highest remaining value For j = 1 To totalDice If rollCopy(j) > currentMax Then currentMax = rollCopy(j) maxIndex = j End If Next j ' Add to sum and mark the die as used sum = sum + currentMax rollCopy(maxIndex) = 0 ' Ensures this die isn't selected again Next i RollAndKeepPreserve = sum End Function
Testing with Your Example
For the roll [4,2,3,3,6]:
- Approach 1 sorts it to
[6,4,3,3,2], sums the first 3 elements: 6+4+3=13 - Approach 2 first picks 6 (sum=6), then 4 (sum=10), then one of the 3s (sum=13)—exactly the result you need.
Quick Notes
- If you're using dice other than d6, just adjust the
Int((6 * Rnd) + 1)part (e.g., d10 would beInt((10 * Rnd) + 1)). - Both methods ensure you never select the same physical die more than once—even if values repeat, each selection is a unique element from your original roll array.
内容的提问来源于stack exchange,提问作者Crystarium Network

