2021-05-17 02:32:33 +02:00
|
|
|
import { EncodedPiece, EncodedPieceShape, EncodedPlayer, Piece, PieceShape, Player } from './GameCommon'
|
|
|
|
|
import { Point } from './Geometry'
|
2021-05-17 00:27:47 +02:00
|
|
|
import { Rng } from './Rng'
|
2020-12-21 18:34:57 +01:00
|
|
|
|
2021-04-13 20:18:41 +02:00
|
|
|
|
2021-05-17 00:27:47 +02:00
|
|
|
const pad = (x: any, pad: string) => {
|
2021-04-13 20:18:41 +02:00
|
|
|
const str = `${x}`
|
|
|
|
|
if (str.length >= pad.length) {
|
|
|
|
|
return str
|
|
|
|
|
}
|
|
|
|
|
return pad.substr(0, pad.length - str.length) + str
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-17 00:27:47 +02:00
|
|
|
export const logger = (...pre: Array<any>) => {
|
|
|
|
|
const log = (m: 'log'|'info'|'error') => (...args: Array<any>) => {
|
2021-04-13 20:18:41 +02:00
|
|
|
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)
|
|
|
|
|
|
2021-05-17 02:32:33 +02:00
|
|
|
function encodeShape(data: PieceShape): EncodedPieceShape {
|
2020-12-05 19:45:34 +01:00
|
|
|
/* 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)
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-17 02:32:33 +02:00
|
|
|
function decodeShape(data: EncodedPieceShape): PieceShape {
|
2020-12-05 19:45:34 +01:00
|
|
|
return {
|
|
|
|
|
top: (data >> 0 & 0b11) - 1,
|
|
|
|
|
right: (data >> 2 & 0b11) - 1,
|
|
|
|
|
bottom: (data >> 4 & 0b11) - 1,
|
|
|
|
|
left: (data >> 6 & 0b11) - 1,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-17 02:32:33 +02:00
|
|
|
function encodeTile(data: Piece): EncodedPiece {
|
2020-12-05 19:45:34 +01:00
|
|
|
return [data.idx, data.pos.x, data.pos.y, data.z, data.owner, data.group]
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-17 02:32:33 +02:00
|
|
|
function decodeTile(data: EncodedPiece): Piece {
|
2020-12-05 19:45:34 +01:00
|
|
|
return {
|
|
|
|
|
idx: data[0],
|
|
|
|
|
pos: {
|
|
|
|
|
x: data[1],
|
|
|
|
|
y: data[2],
|
|
|
|
|
},
|
|
|
|
|
z: data[3],
|
|
|
|
|
owner: data[4],
|
|
|
|
|
group: data[5],
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-17 02:32:33 +02:00
|
|
|
function encodePlayer(data: Player): EncodedPlayer {
|
2020-12-05 19:45:34 +01:00
|
|
|
return [
|
|
|
|
|
data.id,
|
|
|
|
|
data.x,
|
|
|
|
|
data.y,
|
|
|
|
|
data.d,
|
|
|
|
|
data.name,
|
|
|
|
|
data.color,
|
|
|
|
|
data.bgcolor,
|
|
|
|
|
data.points,
|
|
|
|
|
data.ts,
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-17 02:32:33 +02:00
|
|
|
function decodePlayer(data: EncodedPlayer): Player {
|
2020-12-05 19:45:34 +01:00
|
|
|
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],
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-17 00:27:47 +02:00
|
|
|
function encodeGame(data: any): Array<any> {
|
2020-12-24 15:29:32 +01:00
|
|
|
if (Array.isArray(data)) {
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
return [
|
|
|
|
|
data.id,
|
|
|
|
|
data.rng.type,
|
|
|
|
|
Rng.serialize(data.rng.obj),
|
|
|
|
|
data.puzzle,
|
|
|
|
|
data.players,
|
|
|
|
|
data.evtInfos,
|
2021-04-27 21:43:53 +02:00
|
|
|
data.scoreMode,
|
2020-12-24 15:29:32 +01:00
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-17 00:27:47 +02:00
|
|
|
function decodeGame(data: any) {
|
2020-12-24 15:29:32 +01:00
|
|
|
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],
|
2021-04-27 21:43:53 +02:00
|
|
|
scoreMode: data[6],
|
2020-12-24 15:29:32 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-17 02:32:33 +02:00
|
|
|
function coordByTileIdx(info: any, tileIdx: number): Point {
|
2020-12-05 19:45:34 +01:00
|
|
|
const wTiles = info.width / info.tileSize
|
|
|
|
|
return {
|
|
|
|
|
x: tileIdx % wTiles,
|
|
|
|
|
y: Math.floor(tileIdx / wTiles),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-17 00:27:47 +02:00
|
|
|
const hash = (str: string): number => {
|
2020-12-22 22:35:09 +01:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-21 00:43:02 +02:00
|
|
|
function asQueryArgs(data: any) {
|
|
|
|
|
const q = []
|
|
|
|
|
for (let k in data) {
|
|
|
|
|
const pair = [k, data[k]].map(encodeURIComponent)
|
|
|
|
|
q.push(pair.join('='))
|
|
|
|
|
}
|
|
|
|
|
if (q.length === 0) {
|
|
|
|
|
return ''
|
|
|
|
|
}
|
|
|
|
|
return `?${q.join('&')}`
|
|
|
|
|
}
|
|
|
|
|
|
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,
|
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,
|
2021-05-21 00:43:02 +02:00
|
|
|
|
|
|
|
|
asQueryArgs,
|
2020-11-08 12:56:54 +01:00
|
|
|
}
|