puzzle/common/Util.js

229 lines
4 KiB
JavaScript
Raw Normal View History

2020-12-21 18:34:57 +01:00
import { Rng } from './Rng.js'
const pad = (x, pad) => {
const str = `${x}`
if (str.length >= pad.length) {
return str
}
return pad.substr(0, pad.length - str.length) + str
}
export const logger = (...pre) => {
const log = (m) => (...args) => {
const d = new Date()
const hh = pad(d.getHours(), '00')
const mm = pad(d.getMinutes(), '00')
const ss = pad(d.getSeconds(), '00')
console[m](`${hh}:${mm}:${ss}`, ...pre, ...args)
}
return {
log: log('log'),
error: log('error'),
info: log('info'),
}
}
2020-11-08 14:49:34 +01:00
// get a unique id
export const uniqId = () => Date.now().toString(36) + Math.random().toString(36).substring(2)
2020-11-07 11:35:29 +01:00
// get a random int between min and max (inclusive)
2020-12-21 18:34:57 +01:00
export const randomInt = (
/** @type Rng */ rng,
min,
max
) => rng.random(min, max)
2020-11-07 11:35:29 +01:00
// get one random item from the given array
2020-12-21 18:34:57 +01:00
export const choice = (
/** @type Rng */ rng,
array
) => array[randomInt(rng, 0, array.length - 1)]
2020-11-07 11:35:29 +01:00
export const throttle = (fn, delay) => {
let canCall = true
return (...args) => {
if (canCall) {
fn.apply(null, args)
canCall = false
setTimeout(() => {
canCall = true
}, delay)
}
}
}
2020-11-07 11:35:29 +01:00
// return a shuffled (shallow) copy of the given array
2020-12-21 18:34:57 +01:00
export const shuffle = (
/** @type Rng */ rng,
array
) => {
2020-11-07 11:35:29 +01:00
let arr = array.slice()
for (let i = 0; i <= arr.length - 2; i++)
{
2020-12-21 18:34:57 +01:00
const j = randomInt(rng, i, arr.length -1);
2020-11-07 11:35:29 +01:00
const tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
return arr
}
2020-12-05 19:45:34 +01:00
function encodeShape(data) {
if (typeof data === 'number') {
return data
}
/* encoded in 1 byte:
00000000
^^ top
^^ right
^^ bottom
^^ left
*/
return ((data.top + 1) << 0)
| ((data.right + 1) << 2)
| ((data.bottom + 1) << 4)
| ((data.left + 1) << 6)
}
function decodeShape(data) {
if (typeof data !== 'number') {
return data
}
return {
top: (data >> 0 & 0b11) - 1,
right: (data >> 2 & 0b11) - 1,
bottom: (data >> 4 & 0b11) - 1,
left: (data >> 6 & 0b11) - 1,
}
}
function encodeTile(data) {
if (Array.isArray(data)) {
return data
}
return [data.idx, data.pos.x, data.pos.y, data.z, data.owner, data.group]
}
function decodeTile(data) {
if (!Array.isArray(data)) {
return data
}
return {
idx: data[0],
pos: {
x: data[1],
y: data[2],
},
z: data[3],
owner: data[4],
group: data[5],
}
}
function encodePlayer(data) {
if (Array.isArray(data)) {
return data
}
return [
data.id,
data.x,
data.y,
data.d,
data.name,
data.color,
data.bgcolor,
data.points,
data.ts,
]
}
function decodePlayer(data) {
if (!Array.isArray(data)) {
return data
}
return {
id: data[0],
x: data[1],
y: data[2],
d: data[3], // mouse down
name: data[4],
color: data[5],
bgcolor: data[6],
points: data[7],
ts: data[8],
}
}
2020-12-24 15:29:32 +01:00
function encodeGame(data) {
if (Array.isArray(data)) {
return data
}
return [
data.id,
data.rng.type,
Rng.serialize(data.rng.obj),
data.puzzle,
data.players,
data.evtInfos,
]
}
function decodeGame(data) {
if (!Array.isArray(data)) {
return data
}
return {
id: data[0],
rng: {
type: data[1],
obj: Rng.unserialize(data[2]),
},
puzzle: data[3],
players: data[4],
evtInfos: data[5],
}
}
2020-12-05 19:45:34 +01:00
function coordByTileIdx(info, tileIdx) {
const wTiles = info.width / info.tileSize
return {
x: tileIdx % wTiles,
y: Math.floor(tileIdx / wTiles),
}
}
2020-12-22 22:35:09 +01:00
const hash = (str) => {
let hash = 0
for (let i = 0; i < str.length; i++) {
let chr = str.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
2020-11-07 11:35:29 +01:00
export default {
2020-12-22 22:35:09 +01:00
hash,
2020-11-08 14:49:34 +01:00
uniqId,
randomInt,
choice,
throttle,
2020-11-08 14:49:34 +01:00
shuffle,
2020-12-05 19:45:34 +01:00
encodeShape,
decodeShape,
encodeTile,
decodeTile,
encodePlayer,
decodePlayer,
2020-12-24 15:29:32 +01:00
encodeGame,
decodeGame,
2020-12-05 19:45:34 +01:00
coordByTileIdx,
2020-11-08 12:56:54 +01:00
}