The middle
function already does what you want
In testing, it looks like the dice are sorted in descending order when selecting the middle. This means that [middle 3 of 6d6]
should be exactly what you want: the 2nd, 3rd, and 4th dice after sorting all 6 dice from highest to lowest, thus dropping the 1st (highest) die as well as the 5th and 6th (two lowest) dice.
To convince yourself that the middle
function works like this, try [middle 1 of 2d6]
. You'll see that the resulting distribution is biased in favor of larger values, which means it is selecting the higher of the two rolls.
Regardless, just in case you want the alternate middle
that rounds dice positions up rather than down, we can easily do this by modifying the standard middle
function, which looks like this:
function: middle NUMBER:n of DICE:d {
if NUMBER = #DICE { result: DICE }
if NUMBER = 1 { result: (1 + (#DICE - 1) / 2) @ DICE }
FROM: 1 + (#DICE - NUMBER) / 2
TO: FROM + NUMBER - 1
result: {FROM..TO}@DICE
}
All we need to do is add an additional 1 to each place where a number is divided by 2, to change rounding down into rounding up:
function: altmiddle NUMBER:n of DICE:d {
if NUMBER = #DICE { result: DICE }
if NUMBER = 1 { result: (1 + (#DICE) / 2) @ DICE }
FROM: 1 + (#DICE - NUMBER + 1) / 2
TO: FROM + NUMBER - 1
result: {FROM..TO}@DICE
}
With these functions defined, we can run the following:
output [middle 3 of 6d6] named "Middle, positions rounding down"
output [altmiddle 3 of 6d6] named "Middle, positions rounding up"
You'll notice that the one using middle
has a higher average, which means it's dropping more low dice than high ones.