some more type hinting etc

This commit is contained in:
Zutatensuppe 2021-05-17 02:32:33 +02:00
parent 432e1b6668
commit ee7804a594
18 changed files with 161 additions and 150 deletions

View file

@ -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,
}

View file

@ -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 }

View file

@ -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

View file

@ -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,