REBOL [
    Title: "Dice Roller"
    Date: 14-Oct-2002
    Version: 1.0.0
    File: %roll.r
    Author: "Christopher M. Dicely"
    Purpose: {A general purpose dice roller, supports custom dice and roll-and-keep highest or lowest dice.}
    Email: icdicely@pacbell.net
    Category: [game util 1]
]

dF: [ -1 0 1 ] "Use as the 'sides' argument to roll to use 'fudge dice'"

roll: func [ 
  "returns the result of a specified die roll"
  dice [integer!] "number of dice to roll"
  sides [integer! block!] "type of die: if an integer, the number of sides; if a block, the value of each side"
  /keep keep-dice [integer!] "number of dice to keep"
  /low "used with /keep, keep the lowest rather than highest dice"
  /block "return a block with all the results (otherwise, returns the total)"
  /local results total die entry
] [
  results: copy [ ]
  if block? sides [ block: foreach entry sides [ if not number? entry [ break/return true ] block ] ]
  loop dice [ append results random/only sides ]
  if keep [
    if greater? keep-dice dice [ keep-dice: dice ]
    either low [ sort results] [ sort/reverse results ]
    results: copy/part results keep-dice
  ]
  either block [ return results ] [
    total: 0
    foreach die results [ total: total + die ]
    return total
  ]
]