You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现Roll and Keep骰子系统:从数组中选取指定数量最大数值

Fixing the Duplicate Selection Issue in Your Roll and Keep VBA System

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 be Int((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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:05:40