Skip to content

Instantly share code, notes, and snippets.

@Shimilbi
Created January 13, 2024 05:50
Show Gist options
  • Save Shimilbi/7d056a2ecadf537bcaac5a3d344dc5ee to your computer and use it in GitHub Desktop.
Save Shimilbi/7d056a2ecadf537bcaac5a3d344dc5ee to your computer and use it in GitHub Desktop.
Randomizer with options that picks an entry from an array
export class Randomizer<T> {
Pool :T[]
UsedEntries? :T[]
LastPick? :T
DebugErrorTolerence :number = 5
constructor(...list:T[]) {
this.Pool = list as T[]
// console.log("\n(F.Randomizer: Pool is: " + this.PoolOfUnused().join("|")+" )")
}
// Optional call
#Cheat (edgeTowardThisValue:T) {
if (this.LastPick===undefined)
throw "(Randomizer.#Cheat: Please first get a random pick before cheating on it.)"
const remnents = this.PoolOfUnused()
if (!remnents.includes(this.LastPick))
throw "(Randomizer.#Cheat: Please don't eliminate the initial random pick before cheating on it.)"
let pickedIndex = remnents.includes(this.LastPick)
? remnents.indexOf(this.LastPick)
: this.Pool.indexOf(this.LastPick)
// console.log("Randomizer.#Cheat (DEBUG) of index "+pickedIndex)
let indexToEdgeTowardOf = remnents.indexOf(edgeTowardThisValue)
// console.log("edgeTowardThisValue="+edgeTowardThisValue)
if (indexToEdgeTowardOf > pickedIndex && pickedIndex < remnents.length-1) pickedIndex += 1
else if (indexToEdgeTowardOf < pickedIndex && pickedIndex > 0) pickedIndex -= 1
// console.log("index changed for "+pickedIndex)
this.LastPick = remnents[pickedIndex]
// console.log("favored value: "+this.LastPick)
return this
}
// Optional call
#ThenEliminate () {
if (this.LastPick===undefined)
throw "(Randomizer.#ThenEliminate: Please first get a random pick, then eventually cheat about it, before eliminating it.)"
this.UsedEntries ??= []
this.UsedEntries.push(this.LastPick)
if (this.UsedEntries.length>0)
// If all values were picked once, All are available again
if (this.UsedEntries.every(usedEntry =>
this.PoolOfUnused().includes(usedEntry))
)
this.UsedEntries = []
return this
}
PoolOfUnused() {
if (this.UsedEntries===undefined||this.UsedEntries?.length<1)
return this.Pool
else {
let unused: T[] = this.Pool.filter(entry => !this.UsedEntries!.includes(entry))
return unused.length < 1 ? this.Pool : unused
}
}
getRandom(avoidDuplicates?:boolean, entryToFavor?:T) {
const remnants = this.PoolOfUnused()
// console.log("(Randomizer.GetRandom (DEBUG) Pool: \n- "+remnants.join("\n- "))
this.LastPick = remnants.length==1
? remnants[0]
: remnants[Math.floor( (Math.random() * remnants.length) + 1 )]
// console.log("> "+this.LastPick+" <")
if (this.LastPick===undefined && this.DebugErrorTolerence>0) {
this.DebugErrorTolerence-=1
console.log("(repicking)")
this.getRandom()
}
else if (this.LastPick===undefined && this.DebugErrorTolerence==0) {
this.LastPick = remnants[0]
// throw "A random result could not be picked (and present function might have been looping endlessly by now, so recursivity was limited to 5 consecutive times.)\nWhy are there erros? Maybe because the core function (not my own code) is bugged."
}
const hasFavorite = entryToFavor!==undefined
if (hasFavorite) this.#Cheat(entryToFavor)
if (avoidDuplicates) this.#ThenEliminate()
return this.LastPick
}
}
@Shimilbi
Copy link
Author

Bugged (has to re-attempt more than once at times) but works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment