triangleInt method

int triangleInt(
  1. int center,
  2. int range
)

Gets a random number centered around center with range (inclusive) using a triangular distribution. For example triangleInt(8, 4) will return values between 4 and 12 (inclusive) with greater distribution towards 8.

This means output values will range from (center - range) to (center + range) inclusive, with most values near the center, but not with a normal distribution. Think of it as a poor man's bell curve.

The algorithm works essentially by choosing a random point inside the triangle, and then calculating the x coordinate of that point. It works like this:

Consider Center 4, Range 3:

        *
      * | *
    * | | | *
  * | | | | | *
--+-----+-----+--
0 1 2 3 4 5 6 7 8
 -r     c     r

Now flip the left half of the triangle (from 1 to 3) vertically and move it over to the right so that we have a square.

    .-------.
    |       V
    |
    |   R L L L
    | . R R L L
    . . R R R L
  . . . R R R R
--+-----+-----+--
0 1 2 3 4 5 6 7 8

Choose a point in that square. Figure out which half of the triangle the point is in, and then remap the point back out to the original triangle. The result is the x coordinate of the point in the original triangle.

Implementation

int triangleInt(int center, int range) {
  if (range < 0) {
    throw ArgumentError("The argument \"range\" must be zero or greater.");
  }

  // Pick a point in the square.
  int x = inclusive(range);
  int y = inclusive(range);

  // Figure out which triangle we are in.
  if (x <= y) {
    // Larger triangle.
    return center + x;
  } else {
    // Smaller triangle.
    return center - range - 1 + x;
  }
}