2020-12-21 18:34:57 +01:00
|
|
|
import { Rng } from './Rng.js'
|
|
|
|
|
|
2021-04-13 20:18:41 +02:00
|
|
|
|
|
|
|
|
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
|
|
|
|
2020-12-04 00:04:47 +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,
|
2020-12-04 00:04:47 +01:00
|
|
|
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
|
|
|
}
|