some more type hinting etc
This commit is contained in:
parent
432e1b6668
commit
ee7804a594
18 changed files with 161 additions and 150 deletions
|
|
@ -1,16 +1,12 @@
|
|||
import Geometry from './Geometry'
|
||||
import Geometry, { Point, Rect } from './Geometry'
|
||||
import Protocol from './Protocol'
|
||||
import { Rng } from './Rng'
|
||||
import Time from './Time'
|
||||
import Util from './Util'
|
||||
|
||||
interface EncodedPlayer extends Array<any> {}
|
||||
interface EncodedPiece extends Array<any> {}
|
||||
|
||||
interface Point {
|
||||
x: number
|
||||
y: number
|
||||
}
|
||||
export type EncodedPlayer = Array<any>
|
||||
export type EncodedPiece = Array<any>
|
||||
export type EncodedPieceShape = number
|
||||
|
||||
interface GameRng {
|
||||
obj: Rng
|
||||
|
|
@ -22,7 +18,7 @@ interface Game {
|
|||
players: Array<EncodedPlayer>
|
||||
puzzle: Puzzle
|
||||
evtInfos: Record<string, EvtInfo>
|
||||
scoreMode?: number
|
||||
scoreMode?: ScoreMode
|
||||
rng: GameRng
|
||||
}
|
||||
|
||||
|
|
@ -44,15 +40,24 @@ interface PuzzleTable {
|
|||
height: number
|
||||
}
|
||||
|
||||
enum PieceEdge {
|
||||
Flat = 0,
|
||||
Out = 1,
|
||||
In = -1,
|
||||
}
|
||||
export interface PieceShape {
|
||||
top: 0|1|-1
|
||||
bottom: 0|1|-1
|
||||
left: 0|1|-1
|
||||
right: 0|1|-1
|
||||
top: PieceEdge
|
||||
bottom: PieceEdge
|
||||
left: PieceEdge
|
||||
right: PieceEdge
|
||||
}
|
||||
|
||||
export interface Piece {
|
||||
owner: string|number
|
||||
idx: number
|
||||
pos: Point
|
||||
z: number
|
||||
group: number
|
||||
}
|
||||
|
||||
export interface PuzzleInfo {
|
||||
|
|
@ -72,8 +77,7 @@ export interface PuzzleInfo {
|
|||
tilesX: number
|
||||
tilesY: number
|
||||
|
||||
// TODO: ts type Array<PieceShape>
|
||||
shapes: Array<any>
|
||||
shapes: Array<EncodedPieceShape>
|
||||
}
|
||||
|
||||
export interface Player {
|
||||
|
|
@ -93,8 +97,10 @@ interface EvtInfo {
|
|||
_last_mouse_down: Point|null
|
||||
}
|
||||
|
||||
const SCORE_MODE_FINAL = 0
|
||||
const SCORE_MODE_ANY = 1
|
||||
export enum ScoreMode {
|
||||
FINAL = 0,
|
||||
ANY = 1,
|
||||
}
|
||||
|
||||
const IDLE_TIMEOUT_SEC = 30
|
||||
|
||||
|
|
@ -134,20 +140,20 @@ function getPlayerIndexById(gameId: string, playerId: string): number {
|
|||
return -1
|
||||
}
|
||||
|
||||
function getPlayerIdByIndex(gameId: string, playerIndex: number) {
|
||||
function getPlayerIdByIndex(gameId: string, playerIndex: number): string|null {
|
||||
if (GAMES[gameId].players.length > playerIndex) {
|
||||
return Util.decodePlayer(GAMES[gameId].players[playerIndex]).id
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function getPlayer(gameId: string, playerId: string) {
|
||||
let idx = getPlayerIndexById(gameId, playerId)
|
||||
function getPlayer(gameId: string, playerId: string): Player {
|
||||
const idx = getPlayerIndexById(gameId, playerId)
|
||||
return Util.decodePlayer(GAMES[gameId].players[idx])
|
||||
}
|
||||
|
||||
function setPlayer(gameId: string, playerId: string, player: Player) {
|
||||
let idx = getPlayerIndexById(gameId, playerId)
|
||||
const idx = getPlayerIndexById(gameId, playerId)
|
||||
if (idx === -1) {
|
||||
GAMES[gameId].players.push(Util.encodePlayer(player))
|
||||
} else {
|
||||
|
|
@ -168,17 +174,17 @@ function playerExists(gameId: string, playerId: string) {
|
|||
return idx !== -1
|
||||
}
|
||||
|
||||
function getActivePlayers(gameId: string, ts: number) {
|
||||
function getActivePlayers(gameId: string, ts: number): Array<Player> {
|
||||
const minTs = ts - IDLE_TIMEOUT_SEC * Time.SEC
|
||||
return getAllPlayers(gameId).filter((p: Player) => p.ts >= minTs)
|
||||
}
|
||||
|
||||
function getIdlePlayers(gameId: string, ts: number) {
|
||||
function getIdlePlayers(gameId: string, ts: number): Array<Player> {
|
||||
const minTs = ts - IDLE_TIMEOUT_SEC * Time.SEC
|
||||
return getAllPlayers(gameId).filter((p: Player) => p.ts < minTs && p.points > 0)
|
||||
}
|
||||
|
||||
function addPlayer(gameId: string, playerId: string, ts: number) {
|
||||
function addPlayer(gameId: string, playerId: string, ts: number): void {
|
||||
if (!playerExists(gameId, playerId)) {
|
||||
setPlayer(gameId, playerId, __createPlayerObject(playerId, ts))
|
||||
} else {
|
||||
|
|
@ -186,7 +192,7 @@ function addPlayer(gameId: string, playerId: string, ts: number) {
|
|||
}
|
||||
}
|
||||
|
||||
function getEvtInfo(gameId: string, playerId: string) {
|
||||
function getEvtInfo(gameId: string, playerId: string): EvtInfo {
|
||||
if (playerId in GAMES[gameId].evtInfos) {
|
||||
return GAMES[gameId].evtInfos[playerId]
|
||||
}
|
||||
|
|
@ -211,7 +217,7 @@ function getAllGames(): Array<Game> {
|
|||
})
|
||||
}
|
||||
|
||||
function getAllPlayers(gameId: string) {
|
||||
function getAllPlayers(gameId: string): Array<Player> {
|
||||
return GAMES[gameId]
|
||||
? GAMES[gameId].players.map(Util.decodePlayer)
|
||||
: []
|
||||
|
|
@ -221,11 +227,11 @@ function get(gameId: string) {
|
|||
return GAMES[gameId]
|
||||
}
|
||||
|
||||
function getTileCount(gameId: string) {
|
||||
function getTileCount(gameId: string): number {
|
||||
return GAMES[gameId].puzzle.tiles.length
|
||||
}
|
||||
|
||||
function getImageUrl(gameId: string) {
|
||||
function getImageUrl(gameId: string): string {
|
||||
return GAMES[gameId].puzzle.info.imageUrl
|
||||
}
|
||||
|
||||
|
|
@ -233,8 +239,8 @@ function setImageUrl(gameId: string, imageUrl: string) {
|
|||
GAMES[gameId].puzzle.info.imageUrl = imageUrl
|
||||
}
|
||||
|
||||
function getScoreMode(gameId: string) {
|
||||
return GAMES[gameId].scoreMode || SCORE_MODE_FINAL
|
||||
function getScoreMode(gameId: string): ScoreMode {
|
||||
return GAMES[gameId].scoreMode || ScoreMode.FINAL
|
||||
}
|
||||
|
||||
function isFinished(gameId: string) {
|
||||
|
|
@ -259,6 +265,7 @@ function getTilesSortedByZIndex(gameId: string) {
|
|||
function changePlayer(gameId: string, playerId: string, change: any) {
|
||||
const player = getPlayer(gameId, playerId)
|
||||
for (let k of Object.keys(change)) {
|
||||
// @ts-ignore
|
||||
player[k] = change[k]
|
||||
}
|
||||
setPlayer(gameId, playerId, player)
|
||||
|
|
@ -274,12 +281,13 @@ function changeData(gameId: string, change: any) {
|
|||
function changeTile(gameId: string, tileIdx: number, change: any) {
|
||||
for (let k of Object.keys(change)) {
|
||||
const tile = Util.decodeTile(GAMES[gameId].puzzle.tiles[tileIdx])
|
||||
// @ts-ignore
|
||||
tile[k] = change[k]
|
||||
GAMES[gameId].puzzle.tiles[tileIdx] = Util.encodeTile(tile)
|
||||
}
|
||||
}
|
||||
|
||||
const getTile = (gameId: string, tileIdx: number) => {
|
||||
const getTile = (gameId: string, tileIdx: number): Piece => {
|
||||
return Util.decodeTile(GAMES[gameId].puzzle.tiles[tileIdx])
|
||||
}
|
||||
|
||||
|
|
@ -500,7 +508,7 @@ const freeTileIdxByPos = (gameId: string, pos: Point) => {
|
|||
continue
|
||||
}
|
||||
|
||||
const collisionRect = {
|
||||
const collisionRect: Rect = {
|
||||
x: tile.pos.x,
|
||||
y: tile.pos.y,
|
||||
w: info.tileSize,
|
||||
|
|
@ -531,9 +539,9 @@ const getPlayerName = (gameId: string, playerId: string) => {
|
|||
return p ? p.name : null
|
||||
}
|
||||
|
||||
const getPlayerPoints = (gameId: string, playerId: string) => {
|
||||
const getPlayerPoints = (gameId: string, playerId: string): number => {
|
||||
const p = getPlayer(gameId, playerId)
|
||||
return p ? p.points : null
|
||||
return p ? p.points : 0
|
||||
}
|
||||
|
||||
// determine if two tiles are grouped together
|
||||
|
|
@ -746,13 +754,13 @@ function handleInput(gameId: string, playerId: string, input: any, ts: number) {
|
|||
_tileChanges(tileIdxs)
|
||||
|
||||
let points = getPlayerPoints(gameId, playerId)
|
||||
if (getScoreMode(gameId) === SCORE_MODE_FINAL) {
|
||||
if (getScoreMode(gameId) === ScoreMode.FINAL) {
|
||||
points += tileIdxs.length
|
||||
} else if (getScoreMode(gameId) === SCORE_MODE_ANY) {
|
||||
} else if (getScoreMode(gameId) === ScoreMode.ANY) {
|
||||
points += 1
|
||||
} else {
|
||||
// no score mode... should never occur, because there is a
|
||||
// fallback to SCORE_MODE_FINAL in getScoreMode function
|
||||
// fallback to ScoreMode.FINAL in getScoreMode function
|
||||
}
|
||||
changePlayer(gameId, playerId, { d, ts, points })
|
||||
_playerChange()
|
||||
|
|
@ -809,7 +817,7 @@ function handleInput(gameId: string, playerId: string, input: any, ts: number) {
|
|||
break
|
||||
}
|
||||
}
|
||||
if (snapped && getScoreMode(gameId) === SCORE_MODE_ANY) {
|
||||
if (snapped && getScoreMode(gameId) === ScoreMode.ANY) {
|
||||
const points = getPlayerPoints(gameId, playerId) + 1
|
||||
changePlayer(gameId, playerId, { d, ts, points })
|
||||
_playerChange()
|
||||
|
|
@ -881,6 +889,4 @@ export default {
|
|||
getStartTs,
|
||||
getFinishTs,
|
||||
handleInput,
|
||||
SCORE_MODE_FINAL,
|
||||
SCORE_MODE_ANY,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,18 @@
|
|||
interface Point {
|
||||
export interface Point {
|
||||
x: number
|
||||
y: number
|
||||
}
|
||||
|
||||
interface Rect {
|
||||
export interface Rect {
|
||||
x: number
|
||||
y: number
|
||||
w: number
|
||||
h: number
|
||||
}
|
||||
export interface Dim {
|
||||
w: number
|
||||
h: number
|
||||
}
|
||||
|
||||
function pointSub(a: Point, b: Point): Point {
|
||||
return { x: a.x - b.x, y: a.y - b.y }
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ const MIN = SEC * 60
|
|||
const HOUR = MIN * 60
|
||||
const DAY = HOUR * 24
|
||||
|
||||
export const timestamp = () => {
|
||||
export const timestamp = (): number => {
|
||||
const d = new Date();
|
||||
return Date.UTC(
|
||||
d.getUTCFullYear(),
|
||||
|
|
@ -17,7 +17,7 @@ export const timestamp = () => {
|
|||
)
|
||||
}
|
||||
|
||||
export const durationStr = (duration: number) => {
|
||||
export const durationStr = (duration: number): string => {
|
||||
const d = Math.floor(duration / DAY)
|
||||
duration = duration % DAY
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { EncodedPiece, EncodedPieceShape, EncodedPlayer, Piece, PieceShape, Player } from './GameCommon'
|
||||
import { Point } from './Geometry'
|
||||
import { Rng } from './Rng'
|
||||
|
||||
|
||||
|
|
@ -27,10 +29,7 @@ export const logger = (...pre: Array<any>) => {
|
|||
// get a unique id
|
||||
export const uniqId = () => Date.now().toString(36) + Math.random().toString(36).substring(2)
|
||||
|
||||
function encodeShape(data: any): number {
|
||||
if (typeof data === 'number') {
|
||||
return data
|
||||
}
|
||||
function encodeShape(data: PieceShape): EncodedPieceShape {
|
||||
/* encoded in 1 byte:
|
||||
00000000
|
||||
^^ top
|
||||
|
|
@ -44,10 +43,7 @@ function encodeShape(data: any): number {
|
|||
| ((data.left + 1) << 6)
|
||||
}
|
||||
|
||||
function decodeShape(data: any) {
|
||||
if (typeof data !== 'number') {
|
||||
return data
|
||||
}
|
||||
function decodeShape(data: EncodedPieceShape): PieceShape {
|
||||
return {
|
||||
top: (data >> 0 & 0b11) - 1,
|
||||
right: (data >> 2 & 0b11) - 1,
|
||||
|
|
@ -56,17 +52,11 @@ function decodeShape(data: any) {
|
|||
}
|
||||
}
|
||||
|
||||
function encodeTile(data: any): Array<any> {
|
||||
if (Array.isArray(data)) {
|
||||
return data
|
||||
}
|
||||
function encodeTile(data: Piece): EncodedPiece {
|
||||
return [data.idx, data.pos.x, data.pos.y, data.z, data.owner, data.group]
|
||||
}
|
||||
|
||||
function decodeTile(data: any) {
|
||||
if (!Array.isArray(data)) {
|
||||
return data
|
||||
}
|
||||
function decodeTile(data: EncodedPiece): Piece {
|
||||
return {
|
||||
idx: data[0],
|
||||
pos: {
|
||||
|
|
@ -79,10 +69,7 @@ function decodeTile(data: any) {
|
|||
}
|
||||
}
|
||||
|
||||
function encodePlayer(data: any): Array<any> {
|
||||
if (Array.isArray(data)) {
|
||||
return data
|
||||
}
|
||||
function encodePlayer(data: Player): EncodedPlayer {
|
||||
return [
|
||||
data.id,
|
||||
data.x,
|
||||
|
|
@ -96,10 +83,7 @@ function encodePlayer(data: any): Array<any> {
|
|||
]
|
||||
}
|
||||
|
||||
function decodePlayer(data: any) {
|
||||
if (!Array.isArray(data)) {
|
||||
return data
|
||||
}
|
||||
function decodePlayer(data: EncodedPlayer): Player {
|
||||
return {
|
||||
id: data[0],
|
||||
x: data[1],
|
||||
|
|
@ -145,7 +129,7 @@ function decodeGame(data: any) {
|
|||
}
|
||||
}
|
||||
|
||||
function coordByTileIdx(info: any, tileIdx: number) {
|
||||
function coordByTileIdx(info: any, tileIdx: number): Point {
|
||||
const wTiles = info.width / info.tileSize
|
||||
return {
|
||||
x: tileIdx % wTiles,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue