diff --git a/src/API.ts b/src/API.ts index ce4da5f..8385477 100644 --- a/src/API.ts +++ b/src/API.ts @@ -823,85 +823,105 @@ export class UserAPI { return this.randomGen() > 0.5; }; - public odds = (n: number, sec: number = 15): boolean => { + public odds = (n: number, beats: number = 1): boolean => { /** * Returns true n% of the time. * * @param n - The probability of returning true. 1/4 = 25% = 0.25, 80/127 = 62.9% = 0.6299212598425197, etc... - * @param sec - The time frame in seconds + * @param beats - The time frame in beats * @returns True n% of the time */ - return this.randomGen() < (n * this.ppqn()) / (this.ppqn() * sec); + return this.randomGen() < (n * this.ppqn()) / (this.ppqn() * beats); }; - public almostNever = (sec: number = 15): boolean => { + // @ts-ignore + public never = (beats: number = 1): boolean => { + /** + * Returns false + * @param beats - Doesn't give a * about beats + * @returns False + */ + return false; + }; + + public almostNever = (beats: number = 1): boolean => { /** * Returns true 2.5% of the time in given time frame. * - * @param sec - The time frame in seconds + * @param beats - The time frame in beats * @returns True 2.5% of the time */ - return this.randomGen() < (0.025 * this.ppqn()) / (this.ppqn() * sec); + return this.randomGen() < (0.025 * this.ppqn()) / (this.ppqn() * beats); }; - public rarely = (sec: number = 15): boolean => { + public rarely = (beats: number = 1): boolean => { /** * Returns true 10% of the time. * - * @param sec - The time frame in seconds + * @param beats - The time frame in beats * @returns True 10% of the time. */ - return this.randomGen() < (0.1 * this.ppqn()) / (this.ppqn() * sec); + return this.randomGen() < (0.1 * this.ppqn()) / (this.ppqn() * beats); }; - public scarcely = (sec: number = 15): boolean => { + public scarcely = (beats: number = 1): boolean => { /** * Returns true 25% of the time. * - * @param sec - The time frame in seconds + * @param beats - The time frame in beats * @returns True 25% of the time */ - return this.randomGen() < (0.25 * this.ppqn()) / (this.ppqn() * sec); + return this.randomGen() < (0.25 * this.ppqn()) / (this.ppqn() * beats); }; - public sometimes = (sec: number = 15): boolean => { + public sometimes = (beats: number = 1): boolean => { /** * Returns true 50% of the time. * - * @param sec - The time frame in seconds + * @param beats - The time frame in beats * @returns True 50% of the time */ - return this.randomGen() < (0.5 * this.ppqn()) / (this.ppqn() * sec); + return this.randomGen() < (0.5 * this.ppqn()) / (this.ppqn() * beats); }; - public often = (sec: number = 15): boolean => { + public often = (beats: number = 1): boolean => { /** * Returns true 75% of the time. * - * @param sec - The time frame in seconds + * @param beats - The time frame in beats * @returns True 75% of the time */ - return this.randomGen() < (0.75 * this.ppqn()) / (this.ppqn() * sec); + return this.randomGen() < (0.75 * this.ppqn()) / (this.ppqn() * beats); }; - public frequently = (sec: number = 15): boolean => { + public frequently = (beats: number = 1): boolean => { /** * Returns true 90% of the time. * - * @param sec - The time frame in seconds + * @param beats - The time frame in beats * @returns True 90% of the time */ - return this.randomGen() < (0.9 * this.ppqn()) / (this.ppqn() * sec); + return this.randomGen() < (0.9 * this.ppqn()) / (this.ppqn() * beats); }; - public almostAlways = (sec: number = 15): boolean => { + public almostAlways = (beats: number = 1): boolean => { /** * Returns true 98.5% of the time. * - * @param sec - The time frame in seconds + * @param beats - The time frame in beats * @returns True 98.5% of the time */ - return this.randomGen() < (0.985 * this.ppqn()) / (this.ppqn() * sec); + return this.randomGen() < (0.985 * this.ppqn()) / (this.ppqn() * beats); + }; + + // @ts-ignore + public always = (beats: number = 1): boolean => { + /** + * Returns true 100% of the time. + * @param beats - Doesn't give a * about beats + * @returns true + */ + return true; }; public dice = (sides: number): number => { diff --git a/src/classes/AbstractEvents.ts b/src/classes/AbstractEvents.ts index 58417f9..a5d69d5 100644 --- a/src/classes/AbstractEvents.ts +++ b/src/classes/AbstractEvents.ts @@ -27,6 +27,11 @@ export abstract class Event { return this; }; + // @ts-ignore + never = (func: Function): Event => { + return this; + }; + almostNever = (func: Function): Event => { return this.odds(0.025, func); }; @@ -55,6 +60,10 @@ export abstract class Event { return this.odds(0.985, func); }; + always = (func: Function): Event => { + return this.modify(func); + }; + modify = (func: Function): Event => { return func(this); }; diff --git a/src/documentation/functions.ts b/src/documentation/functions.ts index 6843381..99fafb5 100644 --- a/src/documentation/functions.ts +++ b/src/documentation/functions.ts @@ -225,16 +225,59 @@ prob(80) :: script(toss() ? script(3) : script(4)) ## Chance operators Chance operators returning a boolean value are also available. They are super important because they also exist for another mechanism called **chaining**. Checkout the **Chaining** page to learn how to use them in different contexts! + +By default chance operators will be evaluated 48 times within a beat. You can change this value by providing a number of beats as an argument. Default value is 1. Change operators can also be used to randomly apply other operators. + +- odds(n: number, beats?: number): returns true for every n (odds) (eg. 1/4 = 0.25) in given number of beats +- never(beats?: number): returns false. Can be handy when switching between different probabilities +- almostNever(beats?: number): returns true 0.1% of the time in given number of beats +- rarely(beats?: number): returns true 1% of the time in given number of beats +- scarcely(beats?: number): returns true 10% of the time in given number of beats +- sometimes(beats?: number): returns true 50% of the time in given number of beats +- often(beats?: number): returns true 75% of the time in given number of beats +- frequently(beats?: number): returns true 90% of the time in given number of beats +- almostAlways(beats?: number): returns true 99% of the time in given number of beats +- always(beats?: number): returns true. Can be handy when switching between different probabilities -- odds(n: number, sec?: number): returns true for every n (odds) (eg. 1/4 = 0.25) in given seconds (sec) -- almostNever(sec?: number): returns true 0.1% in given seconds (sec) -- rarely(sec?: number): returns true 1% in given seconds (sec) -- scaresly(sec?: number): returns true 10% in given seconds (sec) -- sometimes(sec?: number): returns true 50% in given seconds (sec) -- often(sec?: number): returns true 75% in given seconds (sec) -- frequently(sec?: number): returns true 90% in given seconds (sec) -- almostAlways(sec?: number): returns true 99% in given seconds (sec) - +Examples: + +${makeExample( + "Using chance operators", + ` + rarely() :: sound('hh').out(); // Rarely 48 times is still a lot + rarely(4) :: sound('bd').out(); // Rarely in 4 beats is bit less + rarely(8) :: sound('east').out(); // Rarely in 8 beats is even less + `, + true +)} + +${makeExample( + "Using chance with other operators", + ` + frequently() :: mod(1) :: sound('kick').out(); + often() :: mod(0.5) :: sound('hh').out(); + sometimes() :: onbeat(1,3) :: sound('snare').out(); + `, + true +)} + +${makeExample( + "Using chance with chaining", + ` + mod(0.5) && sound("bd") + .freq(100) + .sometimes(s=>s.crush(2.5)) + .out() + + mod(0.5) && sound('arp').freq(100) + .sometimes(n=>n.freq(200).delay(0.5)) + .rarely(n=>n.freq(300).delay(2.5)) + .almostNever(n=>n.freq(400)) + .out() + `, + true +)} + ## Math functions - max(...values: number[]): number: returns the maximum value of a list of numbers. diff --git a/src/documentation/inlineHelp.ts b/src/documentation/inlineHelp.ts index 3afcefe..4a1827d 100644 --- a/src/documentation/inlineHelp.ts +++ b/src/documentation/inlineHelp.ts @@ -377,6 +377,66 @@ const completionDatabase: CompletionDatabase = { description: "Pick a value in the given array", example: "[1,4,10].pick()", }, + odds: { + name: "odds", + category: "randomness", + description: "Return true with a probability of n %", + example: "odds(1/2) // 50% probability" + }, + never: { + name: "never", + category: "randomness", + description: "Return false", + example: "never() // false" + }, + almostNever: { + name: "almostNever", + category: "randomness", + description: "Return true with a probability of 2.5%", + example: "almostNever() // 2.5% chance" + }, + rarely: { + name: "rarely", + category: "randomness", + description: "Return true with a probability of 10%", + example: "rarely() // 10% chance" + }, + scarcely: { + name: "scarcely", + category: "randomness", + description: "Return true with a probability of 25%", + example: "scarcely() // 25% chance" + }, + sometimes: { + name: "sometimes", + category: "randomness", + description: "Return true with a probability of 50%", + example: "sometimes() // 50% chance" + }, + often: { + name: "often", + category: "randomness", + description: "Return true with a probability of 75%", + example: "often() // 75% chance" + }, + frequently: { + name: "frequently", + category: "randomness", + description: "Return true with a probability of 90%", + example: "frequently() // chance" + }, + almostAlways: { + name: "almostAlways", + category: "randomness", + description: "Return true with a probability of 98.5%", + example: "almostAlways() // 98.5% chance" + }, + always: { + name: "always", + category: "randomness", + description: "Return true", + example: "always() // true" + }, sound: { name: "sound", category: "audio", @@ -642,7 +702,7 @@ const completionDatabase: CompletionDatabase = { category: "patterns", description: "Divide each element of the given array by a value", example: "[0,1,2,3].division(2)", - }, + } }; export const inlineHoveringTips = hoverTooltip(