@joncuster/randomly
v2.0.0
Published
Optionally deterministic dice and card utilities for games or other practical randomization needs
Readme
Randomly
Updated to use random for most RNG needs -- this library does everything I intended for RNG and more.
This lib still provides some useful abstractions for games or procedural generation needs.
Die
Simulates an n-sided die.
const d8 = new Die({ sides: 8, initialValue: 4 });
d8.value; // 4
d8.roll() // returns rolled value
d8.value; // stores the last-rolled valueDicePool
Simulates a pool of x n-sided dice.
const pool4d12 = new DicePool({ sides: 12, number: 4 });
pool4d12.roll(); // returns the total value of all rolled dice
pool4d12.dice[0].value; // to get the value of an individual die
pool4d12.dice[3].roll(); // (re)roll a single die in the poolDeck
Simulates a deck of cards (which can be anything, e.g. objects).
Basic usage
const deck = new Deck([ 'dog', 'cat', 'mouse', 'lizard' ]);
// shuffle the items
deck.shuffle();
// draw the top item, which is removed from the deck
deck.draw(); // 'lizard'
deck.items; // is just an array with all normal methods availableConfig options
Deck takes a config object as its second argument, which can have the following options:
shuffle whether to shuffle the deck on instantiation
rng provide your own rng, which should be an instance of random
seed provide a custom seed for the rng for deterministic randomness (defaults to no seed, which uses Math.random())
weightKey allows for weighted draws; items must be objects, and the property specified by weightKey should be either a number or a callback function that returns a number.
Shuffling and cutting the deck
deck.shuffle() // shuffle the whole deckdeck.cut() // [ top, bottom ]cut takes three options:
positionin the deck to cut at. If a fraction like 0.6, it will cut the deck 60/40. If a number like 10 it will cut centered on that exact card position.variancecan also be a fraction or an integer. If a fraction, the cut position will be cut at a random position +/- that fraction, e.g. with position 0.5 and variance 0.1 it will cut somewhere between 40% and 60% of the deck. If a number, the cut position will be varied randomly by +/- that many cards.noSwapnormally when the deck is cut the two stacks are swapped. If you just want to return the two stacks without mutating the deck, set this totrue.
Drawing items
deck.draw(5) // draw the 5th item from the topdeck.peek(2) // peek at the second item from the top without removing it from the deckdeck.drawHand(5) // draw the top 5 items from the deck
deck.drawHand(5,1) // draw 5 items from the deck skipping the top itemdeck.drawRandom() // draw a random item from anywhere in the deck
deck.drawRandom(5) // draw a random item from the top 5 itemsConditional draw
Pass a callback that takes an item and returns true/false to randomly draw only items that meet certain conditions:
const deck = new Deck([
{ name: "cat", species: "mammal" },
{ name: "dog", species: "mammal" },
{ name: "carp", species: "fish" },
])
deck.drawRandomConditional(item => item.species === 'mammal') // will only return cat or dog
deck.drawRandomConditional(item => item.species === 'mammal', 1) // optional max depth, in this case can only return dogWeighted random draw
By setting weight on each item or providing a custom weightKey you can perform weighted draws.
const deck = new Deck([
{ name: "cat", weight: 10 },
{ name: "dog", weight: 1 },
{ name: "fish", weight: 0 },
])
deck.drawWeighted() // most likely will get cat, fish will never be selectedWith a custom weightKey:
const deck = new Deck([{ name: 'Gold', rarity: 1 },{ name: 'Iron ore', rarity: 10 }], { weightKey: 'rarity' })
deck.drawWeighted() // most likely to get iron oreweight can also be a function:
function weightByRarity(rarity) {
return 100 - rarity;
}
const deck = new Deck([{ name: 'Gold', rarity: 99, getWeight: weightByRarity },{ name: 'Iron ore', rarity: 1, getWeight: weightByRarity }], { weightKey: 'getWeight' })
deck.drawWeighted() // most likely to get iron ore