Randomness lets the same Item action or Boop produce different results each time. You have already seen that Rand is a namespace and :: accesses one of its functions. This lesson combines that knowledge with the ranges and lists introduced earlier.
Choose a whole number
Rand::pick(1..=100)
1..=100 is a range that includes every whole number from 1 through 100. Rand::pick() chooses one of them.
The range matters. This call chooses any whole number from 1 through 100:
Rand::pick(1..=100)
This different call chooses either the exact value 1 or the exact value 100:
Rand::pick(1, 100)
Use it directly inside a message:
text "@1 and @2 are {}% compatible." with Rand::pick(1..=100);
Choose one option
Rand::pick("Truth", "Dare", "Double Dare")
Rand::pick() also returns one of the individual values you give it. It works well for short prompt lists and alternate wording.
text "@1 {} @2." with Rand::pick("kisses", "teases", "pulls closer");
Every option passed to Rand::pick() is equally likely. Repeating an option can imitate simple weighting, but it quickly becomes difficult to read. Use Rand::weighted() when options need different chances.
Give options different weights
Rand::weighted(
7 => "COMMON",
2 => "UNCOMMON",
1 => "RARE",
)
Each entry uses weight => value. Sugar adds the weights together, then gives each value its share of that total. In this example, "COMMON" has 7 of the 10 total parts, so it is chosen about 70 percent of the time.
Weights are relative. These two choices describe the same probabilities:
Rand::weighted(3 => "DAY", 1 => "NIGHT")
Rand::weighted(75 => "DAY", 25 => "NIGHT")
A weight may be any number expression, so current state can influence a choice without repeating values:
let rareWeight = if luck > 80 then 4 else 1;
let reward = Rand::weighted(
8 => "COINS",
rareWeight => "CROWN",
);
Weights must be non-negative numbers, and at least one weight must be greater than zero. A zero-weight entry cannot be selected.
Give something a percentage chance
Rand::chance(25)
Rand::chance(25) gives true about 25 percent of the time and false the rest of the time.
Use the short if form to choose text:
text "@1 opens the chest and finds {}." with if Rand::chance(10) then "the rare prize" else "the regular prize";
Roll dice
Rand::roll("1d20")
This rolls one 20-sided die, returns the total, and shows JOI’s dice result.
text "@1 rolled {}." with Rand::roll("1d20");
Dice expressions can include more dice and a number to add:
Rand::roll("2d6+3")
This rolls two 6-sided dice and adds 3 to their total.
Pass false as the second argument when you want the number without the visible dice result:
text "@1 takes {} damage." with Rand::roll("2d6+3", false);
Keep one random result for later
Two separate random calls can choose two different results. Save one result in a let variable when a program needs to reuse it:
text {
let roll = Rand::pick(1..=20);
"@1 rolled {roll}. The target was {}." with roll + 5
}
Sugar chooses roll once. Every later use of that variable reads the same number.
The next lesson introduces Date values and the related Date and Duration namespaces.