@haelp/teto
Version:
A typescript-based controllable TETR.IO client.
1 lines • 13.6 kB
Source Map (JSON)
{"version":3,"sources":["../../../src/engine/garbage/index.ts"],"sourcesContent":["import { deepCopy, RNG } from \"../utils\";\n\nexport interface GarbageQueueInitializeParams {\n cap: {\n value: number;\n marginTime: number;\n increase: number;\n absolute: number;\n max: number;\n };\n messiness: {\n change: number;\n within: number;\n nosame: boolean;\n timeout: number;\n center: boolean;\n };\n\n garbage: {\n speed: number;\n holeSize: number;\n };\n\n multiplier: {\n value: number;\n increase: number;\n marginTime: number;\n };\n\n bombs: boolean;\n\n seed: number;\n boardWidth: number;\n rounding: \"down\" | \"rng\";\n openerPhase: number;\n specialBonus: boolean;\n}\n\nexport interface Garbage {\n frame: number;\n amount: number;\n size: number;\n}\n\nexport interface IncomingGarbage extends Garbage {\n cid: number;\n gameid: number;\n confirmed: boolean;\n}\nexport interface OutgoingGarbage extends Garbage {\n id: number;\n column: number;\n}\n\nexport interface GarbageQueueSnapshot {\n seed: number;\n lastTankTime: number;\n lastColumn: number | null;\n sent: number;\n hasChangedColumn: boolean;\n lastReceivedCount: number;\n queue: IncomingGarbage[];\n}\n\nexport class GarbageQueue {\n options: GarbageQueueInitializeParams;\n\n queue: IncomingGarbage[];\n\n lastTankTime: number = 0;\n lastColumn: number | null = null;\n hasChangedColumn: boolean = false;\n lastReceivedCount: number = 0;\n rng: RNG;\n\n // for opener phase calculations\n sent = 0;\n\n constructor(options: GarbageQueueInitializeParams) {\n this.options = deepCopy(options);\n if (!this.options.cap.absolute)\n this.options.cap.absolute = Number.MAX_SAFE_INTEGER;\n\n this.queue = [];\n\n this.rng = new RNG(this.options.seed);\n }\n\n snapshot(): GarbageQueueSnapshot {\n return {\n seed: this.rng.seed,\n lastTankTime: this.lastTankTime,\n lastColumn: this.lastColumn,\n sent: this.sent,\n hasChangedColumn: this.hasChangedColumn,\n lastReceivedCount: this.lastReceivedCount,\n queue: deepCopy(this.queue)\n };\n }\n\n fromSnapshot(snapshot: GarbageQueueSnapshot) {\n this.queue = deepCopy(snapshot.queue);\n this.lastTankTime = snapshot.lastTankTime;\n this.lastColumn = snapshot.lastColumn;\n this.rng = new RNG(snapshot.seed);\n this.sent = snapshot.sent;\n this.hasChangedColumn = snapshot.hasChangedColumn;\n this.lastReceivedCount = snapshot.lastReceivedCount;\n }\n\n rngex() {\n return this.rng.nextFloat();\n }\n\n get size() {\n return this.queue.reduce((a, b) => a + b.amount, 0);\n }\n\n resetReceivedCount() {\n this.lastReceivedCount = 0;\n }\n\n receive(...args: IncomingGarbage[]) {\n this.queue.push(...args.filter((arg) => arg.amount > 0));\n\n while (this.size > this.options.cap.absolute) {\n const total = this.size;\n if (this.queue.at(-1)!.amount <= total - this.options.cap.absolute) {\n this.queue.pop();\n } else {\n this.queue.at(-1)!.amount -= total - this.options.cap.absolute;\n }\n }\n }\n\n confirm(cid: number, gameid: number, frame: number) {\n const obj = this.queue.find((g) => g.cid === cid && g.gameid === gameid);\n if (!obj) return false;\n obj.frame = frame;\n obj.confirmed = true;\n return true;\n }\n\n cancel(\n amount: number,\n pieceCount: number,\n legacy: { openerPhase?: boolean } = {}\n ) {\n let send = amount,\n cancel = 0;\n\n let cancelled: IncomingGarbage[] = [];\n if (\n pieceCount + 1 <=\n this.options.openerPhase - (legacy.openerPhase ? 1 : 0) &&\n this.size >= this.sent\n )\n cancel += amount;\n while ((send > 0 || cancel > 0) && this.size > 0) {\n this.queue[0].amount--;\n if (\n cancelled.length === 0 ||\n cancelled[cancelled.length - 1].cid !== this.queue[0].cid\n ) {\n cancelled.push({ ...this.queue[0], amount: 1 });\n } else {\n cancelled[cancelled.length - 1].amount++;\n }\n if (this.queue[0].amount <= 0) {\n this.queue.shift();\n if (this.rngex() < this.options.messiness.change) {\n this.#reroll_column();\n this.hasChangedColumn = true;\n }\n }\n if (send > 0) send--;\n else cancel--;\n }\n\n this.sent += send;\n return [send, cancelled] as const;\n }\n\n get #columnWidth() {\n return Math.max(\n 0,\n this.options.boardWidth - (this.options.garbage.holeSize - 1)\n );\n }\n\n #reroll_column() {\n const centerBuffer = this.options.messiness.center\n ? Math.round(this.options.boardWidth / 5)\n : 0;\n\n let col: number;\n if (this.options.messiness.nosame && this.lastColumn !== null) {\n col =\n centerBuffer +\n Math.floor(this.rngex() * (this.#columnWidth - 1 - 2 * centerBuffer));\n if (col >= this.lastColumn) col++;\n } else {\n col =\n centerBuffer +\n Math.floor(this.rngex() * (this.#columnWidth - 2 * centerBuffer));\n }\n\n this.lastColumn = col;\n return col;\n }\n\n tank(frame: number, cap: number, hard: boolean): OutgoingGarbage[] {\n if (this.queue.length === 0) return [];\n\n const res: OutgoingGarbage[] = [];\n\n this.queue = this.queue.sort((a, b) => a.frame - b.frame);\n\n if (\n this.options.messiness.timeout &&\n frame >= this.lastTankTime + this.options.messiness.timeout\n ) {\n this.#reroll_column();\n this.hasChangedColumn = true;\n }\n\n const tankAll = false;\n const lines = tankAll\n ? 400\n : Math.floor(Math.min(cap, this.options.cap.max));\n\n for (let i = 0; i < lines && this.queue.length !== 0; i++) {\n const item = this.queue[0];\n\n // TODO: Fix this\n // The real game uses an \"active\" system where garbages have a proptery, may be an issue later\n if (item.frame + this.options.garbage.speed > (hard ? frame : frame - 1))\n break;\n\n item.amount--;\n this.lastReceivedCount++;\n\n let col: number = this.lastColumn!;\n if (\n (col === null || this.rngex() < this.options.messiness.within) &&\n !this.hasChangedColumn\n ) {\n col = this.#reroll_column();\n this.hasChangedColumn = true;\n }\n\n res.push({\n ...item,\n amount: 1,\n column: col,\n id: item.cid\n });\n\n this.hasChangedColumn = false;\n\n if (item.amount <= 0) {\n this.queue.shift();\n\n if (this.rngex() < this.options.messiness.change) {\n this.#reroll_column();\n this.hasChangedColumn = true;\n }\n }\n }\n\n return res;\n }\n\n round(amount: number): number {\n switch (this.options.rounding) {\n case \"down\":\n return Math.floor(amount);\n case \"rng\":\n const floored = Math.floor(amount);\n if (floored === amount) return floored;\n const decimal = amount - floored;\n return floored + (this.rngex() < decimal ? 1 : 0);\n default:\n throw new Error(`Invalid rounding mode ${this.options.rounding}`);\n }\n }\n}\n\nexport * from \"./legacy\";\n"],"names":["deepCopy","RNG","GarbageQueue","options","queue","lastTankTime","lastColumn","hasChangedColumn","lastReceivedCount","rng","sent","cap","absolute","Number","MAX_SAFE_INTEGER","seed","snapshot","fromSnapshot","rngex","nextFloat","size","reduce","a","b","amount","resetReceivedCount","receive","args","push","filter","arg","total","at","pop","confirm","cid","gameid","frame","obj","find","g","confirmed","cancel","pieceCount","legacy","send","cancelled","openerPhase","length","shift","messiness","change","Math","max","boardWidth","garbage","holeSize","centerBuffer","center","round","col","nosame","floor","tank","hard","res","sort","timeout","tankAll","lines","min","i","item","speed","within","column","id","rounding","floored","decimal","Error"],"mappings":"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"}