Skip to content

Instantly share code, notes, and snippets.

@janispritzkau
Created December 10, 2022 08:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save janispritzkau/7d0ff8e9d367b39142ddca7c61c3e893 to your computer and use it in GitHub Desktop.
Save janispritzkau/7d0ff8e9d367b39142ddca7c61c3e893 to your computer and use it in GitHub Desktop.
abstract class Property<T = unknown> {
#values: readonly T[];
constructor(public name: string, values: readonly T[]) {
this.#values = Object.freeze(values);
}
get possibleValues(): readonly T[] {
return this.#values;
}
}
class BooleanProperty extends Property<boolean> {
constructor(name: string) {
super(name, [true, false]);
}
}
class IntegerProperty extends Property<number> {
constructor(name: string, public min: number, public max: number) {
const values: number[] = [];
for (let value = min; value <= max; value++) values.push(value);
super(name, values);
}
}
class EnumProperty<T extends string> extends Property<T> {
constructor(name: string, public variants: readonly T[]) {
super(name, variants);
}
}
function getPossibleStates(properties: Property[]) {
properties.sort();
const states: Record<string, unknown>[] = [];
const indices = Array(properties.length).fill(0);
let i: number;
do {
const state = Object.fromEntries(
properties.map((property, i) => [property.name, property.possibleValues[indices[i]]]),
);
states.push(state);
for (i = indices.length - 1; i >= 0; i--) {
indices[i] = (indices[i] + 1) % properties[i].possibleValues.length;
if (indices[i] > 0) break;
}
} while (i >= 0);
return states;
}
const NOTEBLOCK_INSTRUMENT = new EnumProperty("instrument", [
"harp",
"basedrum",
"snare",
"hat",
"bass",
"flute",
"bell",
"guitar",
"chime",
"xylophone",
"iron_xylophone",
"cow_bell",
"didgeridoo",
"bit",
"banjo",
"pling",
]);
const POWERED = new BooleanProperty("powered");
const NOTE = new IntegerProperty("note", 0, 24);
for (const state of getPossibleStates([NOTEBLOCK_INSTRUMENT, POWERED, NOTE])) {
console.log(state);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment