@haelp/teto
Version:
A typescript-based controllable TETR.IO client.
1 lines • 6.25 kB
Source Map (JSON)
{"version":3,"sources":["../../../src/utils/bot-wrapper/index.ts"],"sourcesContent":["import type { Engine } from \"../../engine\";\nimport type { Game } from \"../../types\";\nimport { adapters } from \"../adapters\";\n\nexport interface BotWrapperConfig {\n pps: number;\n}\n\nexport class BotWrapper<\n T extends adapters.Types.CustomMessageData = adapters.Types.CustomMessageData\n> {\n config: BotWrapperConfig;\n adapter: adapters.Adapter<T>;\n\n nextFrame!: number;\n needsNewMove = false;\n\n static nextFrame(engine: Engine, target: number) {\n return ((engine.stats.pieces + 1) / target) * 60;\n }\n\n static frames(\n engine: Engine,\n keys: adapters.Types.AdapterKey[]\n ): Game.Tick.Keypress[] {\n const round = (r: number) => Math.round(r * 10) / 10;\n\n let running = engine.frame + engine.subframe;\n\n return keys.flatMap((key): [Game.Tick.Keypress, Game.Tick.Keypress] => {\n const firstFrame = {\n type: \"keydown\" as const,\n frame: Math.floor(running),\n data: {\n key:\n key === \"dasLeft\"\n ? \"moveLeft\"\n : key === \"dasRight\"\n ? \"moveRight\"\n : key,\n subframe: round(running - Math.floor(running))\n }\n };\n\n if (key === \"dasLeft\" || key === \"dasRight\") {\n running = round(running + engine.handling.das);\n } else if (key === \"softDrop\") {\n running = round(running + 0.1);\n }\n\n const secondFrame = {\n type: \"keyup\" as const,\n frame: Math.floor(running),\n data: {\n key:\n key === \"dasLeft\"\n ? \"moveLeft\"\n : key === \"dasRight\"\n ? \"moveRight\"\n : key,\n subframe: round(running - Math.floor(running))\n }\n };\n\n return [firstFrame, secondFrame];\n });\n }\n\n constructor(adapter: adapters.Adapter<T>, config: BotWrapperConfig) {\n this.config = config;\n this.adapter = adapter;\n\n this.init = this.init.bind(this);\n this.tick = this.tick.bind(this);\n this.stop = this.stop.bind(this);\n }\n\n async init(engine: Engine, config?: T[\"config\"]) {\n if (engine.handling.arr !== 0)\n throw new Error(\"BotWrapper requires 0 ARR handling.\");\n if (engine.handling.sdf !== 41)\n throw new Error(\"BotWrapper requires 41 SDF handling.\");\n\n await this.adapter.initialize();\n this.adapter.config(engine, config);\n\n engine.events.on(\"queue.add\", (pieces) => this.adapter.addPieces(pieces));\n\n this.nextFrame = BotWrapper.nextFrame(engine, this.config.pps);\n }\n\n async tick(\n engine: Engine,\n events: Game.Client.Event[],\n data?: Partial<Pick<T, \"state\" | \"play\">>\n ) {\n const fullData = {\n state: undefined,\n play: undefined,\n ...data\n };\n if (events.find((event) => event.type === \"garbage\")) {\n this.adapter.update(engine, fullData.state);\n }\n if (engine.frame >= this.nextFrame) {\n if (this.needsNewMove) {\n this.nextFrame = BotWrapper.nextFrame(engine, this.config.pps);\n\t\t\t\tthis.needsNewMove = false;\t\n\t\t\t}\n else {\n const { keys } = await this.adapter.play(engine, fullData.play);\n\n const frames = BotWrapper.frames(engine, keys);\n\n\t\t\t\tthis.needsNewMove = true;\n\n return frames;\n }\n }\n\n return [];\n }\n\n stop() {\n this.adapter.stop();\n }\n}\n"],"names":["BotWrapper","config","adapter","nextFrame","needsNewMove","engine","target","stats","pieces","frames","keys","round","r","Math","running","frame","subframe","flatMap","key","firstFrame","type","floor","data","handling","das","secondFrame","init","bind","tick","stop","arr","Error","sdf","initialize","events","on","addPieces","pps","fullData","state","undefined","play","find","event","update"],"mappings":"AAQA,OAAO,MAAMA;IAGXC,OAAyB;IACzBC,QAA6B;IAE7BC,UAAmB;IACnBC,eAAe,MAAM;IAErB,OAAOD,UAAUE,MAAc,EAAEC,MAAc,EAAE;QAC/C,OAAO,AAAED,CAAAA,OAAOE,KAAK,CAACC,MAAM,GAAG,CAAA,IAAKF,SAAU;IAChD;IAEA,OAAOG,OACLJ,MAAc,EACdK,IAAiC,EACX;QACtB,MAAMC,QAAQ,CAACC,IAAcC,KAAKF,KAAK,CAACC,IAAI,MAAM;QAElD,IAAIE,UAAUT,OAAOU,KAAK,GAAGV,OAAOW,QAAQ;QAE5C,OAAON,KAAKO,OAAO,CAAC,CAACC;YACnB,MAAMC,aAAa;gBACjBC,MAAM;gBACNL,OAAOF,KAAKQ,KAAK,CAACP;gBAClBQ,MAAM;oBACJJ,KACEA,QAAQ,YACJ,aACAA,QAAQ,aACN,cACAA;oBACRF,UAAUL,MAAMG,UAAUD,KAAKQ,KAAK,CAACP;gBACvC;YACF;YAEA,IAAII,QAAQ,aAAaA,QAAQ,YAAY;gBAC3CJ,UAAUH,MAAMG,UAAUT,OAAOkB,QAAQ,CAACC,GAAG;YAC/C,OAAO,IAAIN,QAAQ,YAAY;gBAC7BJ,UAAUH,MAAMG,UAAU;YAC5B;YAEA,MAAMW,cAAc;gBAClBL,MAAM;gBACNL,OAAOF,KAAKQ,KAAK,CAACP;gBAClBQ,MAAM;oBACJJ,KACEA,QAAQ,YACJ,aACAA,QAAQ,aACN,cACAA;oBACRF,UAAUL,MAAMG,UAAUD,KAAKQ,KAAK,CAACP;gBACvC;YACF;YAEA,OAAO;gBAACK;gBAAYM;aAAY;QAClC;IACF;IAEA,YAAYvB,OAA4B,EAAED,MAAwB,CAAE;QAClE,IAAI,CAACA,MAAM,GAAGA;QACd,IAAI,CAACC,OAAO,GAAGA;QAEf,IAAI,CAACwB,IAAI,GAAG,IAAI,CAACA,IAAI,CAACC,IAAI,CAAC,IAAI;QAC/B,IAAI,CAACC,IAAI,GAAG,IAAI,CAACA,IAAI,CAACD,IAAI,CAAC,IAAI;QAC/B,IAAI,CAACE,IAAI,GAAG,IAAI,CAACA,IAAI,CAACF,IAAI,CAAC,IAAI;IACjC;IAEA,MAAMD,KAAKrB,MAAc,EAAEJ,MAAoB,EAAE;QAC/C,IAAII,OAAOkB,QAAQ,CAACO,GAAG,KAAK,GAC1B,MAAM,IAAIC,MAAM;QAClB,IAAI1B,OAAOkB,QAAQ,CAACS,GAAG,KAAK,IAC1B,MAAM,IAAID,MAAM;QAElB,MAAM,IAAI,CAAC7B,OAAO,CAAC+B,UAAU;QAC7B,IAAI,CAAC/B,OAAO,CAACD,MAAM,CAACI,QAAQJ;QAE5BI,OAAO6B,MAAM,CAACC,EAAE,CAAC,aAAa,CAAC3B,SAAW,IAAI,CAACN,OAAO,CAACkC,SAAS,CAAC5B;QAEjE,IAAI,CAACL,SAAS,GAAGH,WAAWG,SAAS,CAACE,QAAQ,IAAI,CAACJ,MAAM,CAACoC,GAAG;IAC/D;IAEA,MAAMT,KACJvB,MAAc,EACd6B,MAA2B,EAC3BZ,IAAyC,EACzC;QACA,MAAMgB,WAAW;YACfC,OAAOC;YACPC,MAAMD;YACN,GAAGlB,IAAI;QACT;QACA,IAAIY,OAAOQ,IAAI,CAAC,CAACC,QAAUA,MAAMvB,IAAI,KAAK,YAAY;YACpD,IAAI,CAAClB,OAAO,CAAC0C,MAAM,CAACvC,QAAQiC,SAASC,KAAK;QAC5C;QACA,IAAIlC,OAAOU,KAAK,IAAI,IAAI,CAACZ,SAAS,EAAE;YAClC,IAAI,IAAI,CAACC,YAAY,EAAE;gBACrB,IAAI,CAACD,SAAS,GAAGH,WAAWG,SAAS,CAACE,QAAQ,IAAI,CAACJ,MAAM,CAACoC,GAAG;gBACjE,IAAI,CAACjC,YAAY,GAAG;YACrB,OACQ;gBACH,MAAM,EAAEM,IAAI,EAAE,GAAG,MAAM,IAAI,CAACR,OAAO,CAACuC,IAAI,CAACpC,QAAQiC,SAASG,IAAI;gBAE9D,MAAMhC,SAAST,WAAWS,MAAM,CAACJ,QAAQK;gBAE7C,IAAI,CAACN,YAAY,GAAG;gBAEhB,OAAOK;YACT;QACF;QAEA,OAAO,EAAE;IACX;IAEAoB,OAAO;QACL,IAAI,CAAC3B,OAAO,CAAC2B,IAAI;IACnB;AACF"}