n0mbers/src/utils.ts

112 lines
2.5 KiB
TypeScript
Raw Normal View History

2022-02-18 19:28:52 +01:00
import { utcToZonedTime } from 'date-fns-tz'
import { BXL_TZ, GAME_STARTING_DATE } from '@/globals'
export function getCurrentDate(): Date {
return utcToZonedTime(new Date(), BXL_TZ)
}
2022-02-22 22:52:50 +01:00
export function getCurrentSessionKey(): string {
2022-02-22 22:54:01 +01:00
const now = getCurrentDate()
// https://stackoverflow.com/a/28149561
const tzoffset = now.getTimezoneOffset() * 60000
const localISOTime = new Date(now.getTime() - tzoffset).toISOString()
return localISOTime.slice(0, 10)
2022-02-22 22:52:50 +01:00
}
2022-02-23 22:39:53 +01:00
/**
*
* @param a
* @param b
* @returns Percentage rounded to 2 decimals
*/
export function percentageDiff(a: number, b: number): number {
return Math.round(((a - b) / ((a + b) / 2)) * 100) / 100
}
2022-02-18 19:28:52 +01:00
// #region RNG
export let random = Math.random
2022-02-07 22:14:31 +01:00
/**
*
* @param min inclusive
* @param max exclusive
* @returns
*/
2022-02-18 19:28:52 +01:00
export function randRange(min: number, max: number, rnd = random): number {
2022-02-09 22:10:58 +01:00
return Math.floor(rnd() * (max - min) + min)
}
2022-02-18 19:28:52 +01:00
export function randItem<T>(items: T[], rnd = random): T {
2022-02-09 22:10:58 +01:00
return items[Math.floor(rnd() * items.length)]
2022-02-07 22:14:31 +01:00
}
2022-02-18 19:28:52 +01:00
export function setMathPRNG(): void {
random = Math.random
}
export function setDailyPRNG(): void {
random = initDailyPRNG()
}
/**
* Shuffles an array in place and returns it
* @param array
* @returns
*/
export function shuffle<T>(array: T[]): T[] {
let currentIndex = array.length
2022-02-18 19:28:52 +01:00
let randomIndex: number
// While there remain elements to shuffle...
while (currentIndex !== 0) {
// Pick a remaining element...
2022-02-18 19:28:52 +01:00
randomIndex = Math.floor(random() * currentIndex)
currentIndex--
// And swap it with the current element.
;[array[currentIndex], array[randomIndex]] = [
array[randomIndex],
array[currentIndex],
]
}
return array
}
2022-02-18 19:28:52 +01:00
function initDailyPRNG(): () => number {
// Prefix the seed when in dev to avoid spoiling myself while working on it
const prefix = import.meta.env.DEV ? 'dev-' : ''
2022-02-22 22:52:50 +01:00
const hashed = hashStr(prefix + getCurrentSessionKey())
2022-02-18 19:28:52 +01:00
return mulberry32(hashed)
}
function mulberry32(a: number) {
return function () {
let t = (a += 0x6d2b79f5)
t = Math.imul(t ^ (t >>> 15), t | 1)
t ^= t + Math.imul(t ^ (t >>> 7), t | 61)
return ((t ^ (t >>> 14)) >>> 0) / 4294967296
}
}
/**
* https://stackoverflow.com/a/7616484
* @param val
* @returns
*/
function hashStr(val: string): number {
let hash = 0
if (val.length === 0) {
return 0
}
for (let i = 0; i < val.length; ++i) {
hash = (hash << 5) - hash + val[i].charCodeAt(0)
hash |= 0
}
return hash
}
// #endregion RNG