@firestone-hs/simulate-bgs-battle 1.1.610 → 1.1.612

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,7 +9,6 @@ exports.Bonker = {
9
9
  return { dmgDoneByAttacker: 0, dmgDoneByDefender: 0 };
10
10
  }
11
11
  const mult = minion.cardId === "BG20_104_G" ? 2 : 1;
12
- console.debug('Bonker', minion.cardId, mult, "BG20_104_G");
13
12
  for (const target of input.attackingBoard.filter((e) => e.entityId !== minion.entityId)) {
14
13
  (0, blood_gems_1.playBloodGemsOn)(minion, target, 1 * mult, input.attackingBoard, input.attackingHero, input.gameState);
15
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"bonker.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/bonker.ts"],"names":[],"mappings":";;;AAEA,+DAAiE;AAIpD,QAAA,MAAM,GAAiB;IACnC,OAAO,EAAE,0BAAoD;IAC7D,iBAAiB,EAAE,CAAC,MAAmB,EAAE,KAAoB,EAAE,EAAE;QAChE,IAAI,MAAM,KAAK,KAAK,CAAC,QAAQ,EAAE;YAC9B,OAAO,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC;SACtD;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,iBAA8B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,eAA4B,CAAC;QACxE,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC,EAAE;YACxF,IAAA,4BAAe,EAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;SACtG;QAED,OAAO,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC;IACvD,CAAC;CACD,CAAC","sourcesContent":["import { CardIds } from '@firestone-hs/reference-data';\r\nimport { BoardEntity } from '../../../board-entity';\r\nimport { playBloodGemsOn } from '../../../simulation/blood-gems';\r\nimport { OnAttackInput } from '../../../simulation/on-attack';\r\nimport { OnAttackCard } from '../../card.interface';\r\n\r\nexport const Bonker: OnAttackCard = {\r\n\tcardIds: [CardIds.Bonker_BG20_104, CardIds.Bonker_BG20_104_G],\r\n\tonAnyMinionAttack: (minion: BoardEntity, input: OnAttackInput) => {\r\n\t\tif (minion !== input.attacker) {\r\n\t\t\treturn { dmgDoneByAttacker: 0, dmgDoneByDefender: 0 };\r\n\t\t}\r\n\r\n\t\tconst mult = minion.cardId === CardIds.Bonker_BG20_104_G ? 2 : 1;\r\n\t\tconsole.debug('Bonker', minion.cardId, mult, CardIds.Bonker_BG20_104_G);\r\n\t\tfor (const target of input.attackingBoard.filter((e) => e.entityId !== minion.entityId)) {\r\n\t\t\tplayBloodGemsOn(minion, target, 1 * mult, input.attackingBoard, input.attackingHero, input.gameState);\r\n\t\t}\r\n\r\n\t\treturn { dmgDoneByAttacker: 0, dmgDoneByDefender: 0 };\r\n\t},\r\n};\r\n"]}
1
+ {"version":3,"file":"bonker.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/bonker.ts"],"names":[],"mappings":";;;AAEA,+DAAiE;AAIpD,QAAA,MAAM,GAAiB;IACnC,OAAO,EAAE,0BAAoD;IAC7D,iBAAiB,EAAE,CAAC,MAAmB,EAAE,KAAoB,EAAE,EAAE;QAChE,IAAI,MAAM,KAAK,KAAK,CAAC,QAAQ,EAAE;YAC9B,OAAO,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC;SACtD;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,iBAA8B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC,EAAE;YACxF,IAAA,4BAAe,EAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;SACtG;QAED,OAAO,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC;IACvD,CAAC;CACD,CAAC","sourcesContent":["import { CardIds } from '@firestone-hs/reference-data';\r\nimport { BoardEntity } from '../../../board-entity';\r\nimport { playBloodGemsOn } from '../../../simulation/blood-gems';\r\nimport { OnAttackInput } from '../../../simulation/on-attack';\r\nimport { OnAttackCard } from '../../card.interface';\r\n\r\nexport const Bonker: OnAttackCard = {\r\n\tcardIds: [CardIds.Bonker_BG20_104, CardIds.Bonker_BG20_104_G],\r\n\tonAnyMinionAttack: (minion: BoardEntity, input: OnAttackInput) => {\r\n\t\tif (minion !== input.attacker) {\r\n\t\t\treturn { dmgDoneByAttacker: 0, dmgDoneByDefender: 0 };\r\n\t\t}\r\n\r\n\t\tconst mult = minion.cardId === CardIds.Bonker_BG20_104_G ? 2 : 1;\r\n\t\tfor (const target of input.attackingBoard.filter((e) => e.entityId !== minion.entityId)) {\r\n\t\t\tplayBloodGemsOn(minion, target, 1 * mult, input.attackingBoard, input.attackingHero, input.gameState);\r\n\t\t}\r\n\r\n\t\treturn { dmgDoneByAttacker: 0, dmgDoneByDefender: 0 };\r\n\t},\r\n};\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"simulate-bgs-battle.js","sourceRoot":"","sources":["../src/simulate-bgs-battle.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { AllCardsService, CardIds } from '@firestone-hs/reference-data';\r\nimport { BgsBattleInfo } from './bgs-battle-info';\r\nimport { hasDeathrattleSpawnEnchantment } from './cards/card.interface';\r\nimport { CardsData } from './cards/cards-data';\r\nimport { cardMappings } from './cards/impl/_card-mappings';\r\nimport { cloneInput3 } from './input-clone';\r\nimport { buildFinalInput } from './input-sanitation';\r\nimport { SimulationResult } from './simulation-result';\r\nimport { FullGameState } from './simulation/internal-game-state';\r\nimport { SharedState } from './simulation/shared-state';\r\nimport { Simulator } from './simulation/simulator';\r\nimport { Spectator } from './simulation/spectator/spectator';\r\n\r\nlet globalCards = new AllCardsService();\r\n\r\nexport const assignCards = (cards: AllCardsService) => {\r\n\tglobalCards = cards;\r\n};\r\n\r\n// This example demonstrates a NodeJS 8.10 async handler[1], however of course you could use\r\n// the more traditional callback-style handler.\r\n// [1]: https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/\r\nexport default async (event): Promise<any> => {\r\n\tif (!event.body?.length) {\r\n\t\tconsole.warn('missing event body', event);\r\n\t\treturn;\r\n\t}\r\n\r\n\tconst battleInput: BgsBattleInfo = JSON.parse(event.body);\r\n\tconst cards = globalCards;\r\n\tawait cards.initializeCardsDb();\r\n\tconst cardsData = new CardsData(cards, false);\r\n\tcardsData.inititialize(\r\n\t\tbattleInput.gameState?.validTribes ?? battleInput.options?.validTribes,\r\n\t\tbattleInput.gameState?.anomalies ?? [],\r\n\t);\r\n\tconst battleIterator = simulateBattle(battleInput, cards, cardsData);\r\n\r\n\t// Iterate through all intermediate results to reach the final result\r\n\tlet result = battleIterator.next();\r\n\twhile (!result.done) {\r\n\t\tresult = battleIterator.next();\r\n\t}\r\n\r\n\tconst simulationResult = result.value;\r\n\t// console.debug('simulationResult', simulationResult);\r\n\r\n\tconst response = {\r\n\t\tstatusCode: 200,\r\n\t\tisBase64Encoded: false,\r\n\t\tbody: JSON.stringify(simulationResult),\r\n\t};\r\n\treturn response;\r\n};\r\n\r\nexport const simulateBattle = function* (\r\n\tbattleInput: BgsBattleInfo,\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n): Generator<SimulationResult, SimulationResult, void> {\r\n\tif (!cards?.getCards()?.length) {\r\n\t\tconsole.error('[simulate-bgs-battle] reference cards are empty, cannot simulate battle', cards);\r\n\t\treturn null;\r\n\t}\r\n\t// !battleInput.options?.skipInfoLogs && console.time('full-sim');\r\n\tconst start = Date.now();\r\n\tconst maxAcceptableDuration = battleInput.options?.maxAcceptableDuration || 8000;\r\n\tconst numberOfSimulations = battleInput.options?.numberOfSimulations || 8000;\r\n\tconst intermediateSteps = battleInput.options?.intermediateResults ?? 200;\r\n\tconst damageConfidence = battleInput.options?.damageConfidence ?? 0.9;\r\n\tconst includeOutcomeSamples = battleInput.options?.includeOutcomeSamples ?? true;\r\n\tconst simulationResult: SimulationResult = {\r\n\t\twonLethal: 0,\r\n\t\twon: 0,\r\n\t\ttied: 0,\r\n\t\tlost: 0,\r\n\t\tlostLethal: 0,\r\n\t\tdamageWons: [],\r\n\t\tdamageWon: 0,\r\n\t\tdamageWonRange: null,\r\n\t\tdamageLosts: [],\r\n\t\tdamageLost: 0,\r\n\t\tdamageLostRange: null,\r\n\t\twonLethalPercent: undefined,\r\n\t\twonPercent: undefined,\r\n\t\ttiedPercent: undefined,\r\n\t\tlostPercent: undefined,\r\n\t\tlostLethalPercent: undefined,\r\n\t\taverageDamageWon: undefined,\r\n\t\taverageDamageLost: undefined,\r\n\t};\r\n\r\n\tconst spectator = new Spectator(includeOutcomeSamples);\r\n\tconst inputReady = buildFinalInput(battleInput, cards, cardsData);\r\n\t!battleInput.options?.skipInfoLogs && console.time('simulation');\r\n\tconst outcomes = {};\r\n\tfor (let i = 0; i < numberOfSimulations; i++) {\r\n\t\tconst input: BgsBattleInfo = cloneInput3(inputReady);\r\n\t\tconst inputClone: BgsBattleInfo = cloneInput3(inputReady);\r\n\t\tconst gameState: FullGameState = {\r\n\t\t\tallCards: cards,\r\n\t\t\tcardsData: cardsData,\r\n\t\t\tspectator: spectator,\r\n\t\t\tsharedState: new SharedState(),\r\n\t\t\tcurrentTurn: input.gameState.currentTurn,\r\n\t\t\tvalidTribes: input.gameState.validTribes,\r\n\t\t\tanomalies: input.gameState.anomalies,\r\n\t\t\tgameState: {\r\n\t\t\t\tplayer: {\r\n\t\t\t\t\tplayer: input.playerBoard.player,\r\n\t\t\t\t\tboard: input.playerBoard.board,\r\n\t\t\t\t\tteammate: input.playerTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\topponent: {\r\n\t\t\t\t\tplayer: input.opponentBoard.player,\r\n\t\t\t\t\tboard: input.opponentBoard.board,\r\n\t\t\t\t\tteammate: input.opponentTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\tplayerInitial: {\r\n\t\t\t\t\tplayer: inputClone.playerBoard.player,\r\n\t\t\t\t\tboard: inputClone.playerBoard.board,\r\n\t\t\t\t\tteammate: inputClone.playerTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\topponentInitial: {\r\n\t\t\t\t\tplayer: inputClone.opponentBoard.player,\r\n\t\t\t\t\tboard: inputClone.opponentBoard.board,\r\n\t\t\t\t\tteammate: inputClone.opponentTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t},\r\n\t\t};\r\n\t\tconst simulator = new Simulator(gameState);\r\n\t\tconst battleResult = simulator.simulateSingleBattle(gameState.gameState.player, gameState.gameState.opponent);\r\n\t\tif (Date.now() - start > maxAcceptableDuration) {\r\n\t\t\t// Can happen in case of inifinite boards, or a bug. Don't hog the user's computer in that case\r\n\t\t\tconsole.warn('Stopping simulation after', i, 'iterations and ', Date.now() - start, 'ms');\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tif (!battleResult) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif (battleResult.result === 'won') {\r\n\t\t\tsimulationResult.won++;\r\n\t\t\tsimulationResult.damageWon += battleResult.damageDealt;\r\n\t\t\tsimulationResult.damageWons.push(battleResult.damageDealt);\r\n\t\t\tif (battleResult.damageDealt >= battleInput.opponentBoard.player.hpLeft) {\r\n\t\t\t\tsimulationResult.wonLethal++;\r\n\t\t\t}\r\n\t\t} else if (battleResult.result === 'lost') {\r\n\t\t\tsimulationResult.lost++;\r\n\t\t\tsimulationResult.damageLost += battleResult.damageDealt;\r\n\t\t\tsimulationResult.damageLosts.push(battleResult.damageDealt);\r\n\t\t\toutcomes[battleResult.damageDealt] = (outcomes[battleResult.damageDealt] ?? 0) + 1;\r\n\t\t\tif (\r\n\t\t\t\tbattleInput.playerBoard.player.hpLeft &&\r\n\t\t\t\tbattleResult.damageDealt >= battleInput.playerBoard.player.hpLeft\r\n\t\t\t) {\r\n\t\t\t\tsimulationResult.lostLethal++;\r\n\t\t\t}\r\n\t\t} else if (battleResult.result === 'tied') {\r\n\t\t\tsimulationResult.tied++;\r\n\t\t}\r\n\t\tspectator.commitBattleResult(battleResult.result);\r\n\r\n\t\t// Yield intermediate result every 200 iterations\r\n\t\tif (!!intermediateSteps && i > 0 && i % intermediateSteps === 0) {\r\n\t\t\tupdateSimulationResult(simulationResult, inputReady, damageConfidence);\r\n\t\t\tyield simulationResult;\r\n\t\t}\r\n\t}\r\n\tupdateSimulationResult(simulationResult, inputReady, damageConfidence);\r\n\t!battleInput.options?.skipInfoLogs && console.timeEnd('simulation');\r\n\tspectator.prune();\r\n\tsimulationResult.outcomeSamples = spectator.buildOutcomeSamples(battleInput.gameState);\r\n\t// Avoid sending this verbose data\r\n\r\n\tsimulationResult.damageWons = [];\r\n\tsimulationResult.damageLosts = [];\r\n\t// !battleInput.options?.skipInfoLogs && console.timeEnd('full-sim');\r\n\t// console.debug(\r\n\t// \t'no-format',\r\n\t// \t'[bgs-simulator] simulated battle',\r\n\t// \tJSON.stringify(battleInput),\r\n\t// \tJSON.stringify(simulationResult),\r\n\t// );\r\n\treturn simulationResult;\r\n};\r\n\r\nconst updateSimulationResult = (simulationResult: SimulationResult, input: BgsBattleInfo, damageConfidence: number) => {\r\n\tconst totalMatches = simulationResult.won + simulationResult.tied + simulationResult.lost;\r\n\tsimulationResult.wonPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.won)) / totalMatches) / 10,\r\n\t\tsimulationResult.won,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.wonLethalPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10,\r\n\t\tsimulationResult.wonLethal,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.lostPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.lost)) / totalMatches) / 10,\r\n\t\tsimulationResult.lost,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.lostLethalPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10,\r\n\t\tsimulationResult.lostLethal,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.tiedPercent = checkRounding(\r\n\t\tMath.max(0, 100 - simulationResult.lostPercent - simulationResult.wonPercent),\r\n\t\tsimulationResult.tied,\r\n\t\ttotalMatches,\r\n\t);\r\n\r\n\t// simulationResult.wonLethalPercent = Math.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10;\r\n\t// simulationResult.lostLethalPercent = Math.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10;\r\n\tconst totalDamageWon = simulationResult.damageWons.reduce((a, b) => a + b, 0);\r\n\tconst totalDamageLost = simulationResult.damageLosts.reduce((a, b) => a + b, 0);\r\n\tconst damageWonRange = calculateDamageRange(simulationResult.damageWons, damageConfidence);\r\n\tconst damageLostRange = calculateDamageRange(simulationResult.damageLosts, damageConfidence);\r\n\tsimulationResult.averageDamageWon = simulationResult.won ? totalDamageWon / simulationResult.won : 0;\r\n\tsimulationResult.averageDamageLost = simulationResult.lost ? totalDamageLost / simulationResult.lost : 0;\r\n\tsimulationResult.damageWonRange = simulationResult.won ? damageWonRange : null;\r\n\tsimulationResult.damageLostRange = simulationResult.lost ? damageLostRange : null;\r\n\r\n\tif (\r\n\t\tsimulationResult.averageDamageWon > 0 &&\r\n\t\tsimulationResult.averageDamageWon < input.playerBoard.player.tavernTier\r\n\t) {\r\n\t\tconsole.warn('average damage won issue');\r\n\t}\r\n\tif (\r\n\t\tsimulationResult.averageDamageLost > 0 &&\r\n\t\tsimulationResult.averageDamageLost < input.opponentBoard.player.tavernTier\r\n\t) {\r\n\t\tconsole.warn('average damage lost issue');\r\n\t}\r\n};\r\n\r\nconst calculateDamageRange = (damageArray: number[], damageConfidence: number): { min: number; max: number } => {\r\n\tif (damageArray.length === 0) {\r\n\t\treturn { min: 0, max: 0 };\r\n\t}\r\n\r\n\t// Sort the array\r\n\tconst sortedDamage = [...damageArray].sort((a, b) => a - b);\r\n\r\n\t// Calculate the 10th and 90th percentiles\r\n\tconst percentile = (arr: number[], p: number) => {\r\n\t\tconst index = Math.floor(p * arr.length);\r\n\t\treturn arr[index];\r\n\t};\r\n\r\n\tconst minDamage = percentile(sortedDamage, 1 - damageConfidence);\r\n\tconst maxDamage = percentile(sortedDamage, damageConfidence);\r\n\r\n\treturn { min: minDamage, max: maxDamage };\r\n};\r\n\r\nconst checkRounding = (roundedValue: number, initialValue: number, totalValue: number): number => {\r\n\tif (roundedValue === 0 && initialValue !== 0) {\r\n\t\treturn 0.01;\r\n\t}\r\n\tif (roundedValue === 100 && initialValue !== totalValue) {\r\n\t\treturn 99.9;\r\n\t}\r\n\treturn roundedValue;\r\n};\r\n\r\n// Used when triggering random deathrattles\r\nconst VALID_DEATHRATTLE_ENCHANTMENTS = [\r\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_BG_BOT_312e,\r\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_TB_BaconUps_032e,\r\n\tCardIds.LivingSpores_LivingSporesEnchantment,\r\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000e,\r\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000_Ge,\r\n\tCardIds.Sneed_SneedsReplicator,\r\n\tCardIds.SneedsReplicator_ReplicateEnchantment,\r\n\tCardIds.EarthRecollectionEnchantment, // Spirit Raptor\r\n\tCardIds.FireRecollectionEnchantment,\r\n\tCardIds.LightningRecollectionEnchantment,\r\n\tCardIds.WaterRecollectionEnchantment,\r\n\tCardIds.EarthInvocation_ElementEarthEnchantment, // Summon a 1/1\r\n\tCardIds.LightningInvocation, // Deal 1 damage to 5 enemy minions\r\n\t// CardIds.SurfNSurf_CrabRidingEnchantment_BG27_004e,\r\n\t// CardIds.SurfNSurf_CrabRidingEnchantment_BG27_004_Ge,\r\n\t// CardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055e,\r\n\t// CardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055_Ge,\r\n\tCardIds.BoonOfBeetles_BeetleSwarmEnchantment_BG28_603e,\r\n\tCardIds.RustyTrident_TridentsTreasureEnchantment_BG30_MagicItem_917e,\r\n\tCardIds.HoggyBank_GemInTheBankEnchantment_BG30_MagicItem_411e,\r\n\tCardIds.JarredFrostling_FrostyGlobeEnchantment_BG30_MagicItem_952e,\r\n\tCardIds.CaduceusReactor_CaduceusReactorEnchantment_BG31_HERO_801ptee,\r\n\tCardIds.AutoAssembler_AutoAssemblerEnchantment_BG32_172e,\r\n\tCardIds.AutoAssembler_AutoAssemblerEnchantment_BG32_172_Ge,\r\n];\r\nconst validDeathrattleEnchantmentsFromMapping = [];\r\nexport const isValidDeathrattleEnchantment = (cardId: string): boolean => {\r\n\tif (VALID_DEATHRATTLE_ENCHANTMENTS.includes(cardId as CardIds)) {\r\n\t\treturn true;\r\n\t}\r\n\tif (validDeathrattleEnchantmentsFromMapping.length === 0) {\r\n\t\tfor (const cardImpl of Object.values(cardMappings)) {\r\n\t\t\t// Also includes non-enchantments, but since we only match this against the enchants list, it's fine\r\n\t\t\tif (hasDeathrattleSpawnEnchantment(cardImpl)) {\r\n\t\t\t\tvalidDeathrattleEnchantmentsFromMapping.push(...cardImpl.cardIds);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn validDeathrattleEnchantmentsFromMapping.includes(cardId);\r\n};\r\n\r\n// const cleanEnchantmentsForEntity = (\r\n// \tenchantments: { cardId: string; originEntityId?: number; timing: number }[],\r\n// \tentityIds: readonly number[],\r\n// ): { cardId: string; originEntityId?: number; timing: number }[] => {\r\n// \treturn enchantments.filter(\r\n// \t\t(enchant) =>\r\n// \t\t\tentityIds.indexOf(enchant.originEntityId) !== -1 ||\r\n// \t\t\tvalidEnchantments.indexOf(enchant.cardId as CardIds) !== -1,\r\n// \t);\r\n// };\r\n"]}
1
+ {"version":3,"file":"simulate-bgs-battle.js","sourceRoot":"","sources":["../src/simulate-bgs-battle.ts"],"names":[],"mappings":";;;AACA,iEAAwE;AAExE,2DAAwE;AACxE,mDAA+C;AAC/C,gEAA2D;AAC3D,+CAA4C;AAC5C,yDAAqD;AAGrD,4DAAwD;AACxD,sDAAmD;AACnD,gEAA6D;AAE7D,IAAI,WAAW,GAAG,IAAI,gCAAe,EAAE,CAAC;AAEjC,MAAM,WAAW,GAAG,CAAC,KAAsB,EAAE,EAAE;IACrD,WAAW,GAAG,KAAK,CAAC;AACrB,CAAC,CAAC;AAFW,QAAA,WAAW,eAEtB;AAKF,kBAAe,KAAK,EAAE,KAAK,EAAgB,EAAE;;IAC5C,IAAI,CAAC,CAAA,MAAA,KAAK,CAAC,IAAI,0CAAE,MAAM,CAAA,EAAE;QACxB,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;QAC1C,OAAO;KACP;IAED,MAAM,WAAW,GAAkB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAG,WAAW,CAAC;IAC1B,MAAM,KAAK,CAAC,iBAAiB,EAAE,CAAC;IAChC,MAAM,SAAS,GAAG,IAAI,sBAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9C,SAAS,CAAC,YAAY,CACrB,MAAA,MAAA,WAAW,CAAC,SAAS,0CAAE,WAAW,mCAAI,MAAA,WAAW,CAAC,OAAO,0CAAE,WAAW,EACtE,MAAA,MAAA,WAAW,CAAC,SAAS,0CAAE,SAAS,mCAAI,EAAE,CACtC,CAAC;IACF,MAAM,cAAc,GAAG,IAAA,sBAAc,EAAC,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAGrE,IAAI,MAAM,GAAG,cAAc,CAAC,IAAI,EAAE,CAAC;IACnC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE;QACpB,MAAM,GAAG,cAAc,CAAC,IAAI,EAAE,CAAC;KAC/B;IAED,MAAM,gBAAgB,GAAG,MAAM,CAAC,KAAK,CAAC;IAGtC,MAAM,QAAQ,GAAG;QAChB,UAAU,EAAE,GAAG;QACf,eAAe,EAAE,KAAK;QACtB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;KACtC,CAAC;IACF,OAAO,QAAQ,CAAC;AACjB,CAAC,CAAC;AAEK,MAAM,cAAc,GAAG,QAAQ,CAAC,EACtC,WAA0B,EAC1B,KAAsB,EACtB,SAAoB;;IAEpB,IAAI,CAAC,CAAA,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,QAAQ,EAAE,0CAAE,MAAM,CAAA,EAAE;QAC/B,OAAO,CAAC,KAAK,CAAC,yEAAyE,EAAE,KAAK,CAAC,CAAC;QAChG,OAAO,IAAI,CAAC;KACZ;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,qBAAqB,GAAG,CAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,qBAAqB,KAAI,IAAI,CAAC;IACjF,MAAM,mBAAmB,GAAG,CAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,mBAAmB,KAAI,IAAI,CAAC;IAC7E,MAAM,iBAAiB,GAAG,MAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,mBAAmB,mCAAI,GAAG,CAAC;IAC1E,MAAM,gBAAgB,GAAG,MAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,gBAAgB,mCAAI,GAAG,CAAC;IACtE,MAAM,qBAAqB,GAAG,MAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,qBAAqB,mCAAI,IAAI,CAAC;IACjF,MAAM,gBAAgB,GAAqB;QAC1C,SAAS,EAAE,CAAC;QACZ,GAAG,EAAE,CAAC;QACN,IAAI,EAAE,CAAC;QACP,IAAI,EAAE,CAAC;QACP,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,EAAE;QACd,SAAS,EAAE,CAAC;QACZ,cAAc,EAAE,IAAI;QACpB,WAAW,EAAE,EAAE;QACf,UAAU,EAAE,CAAC;QACb,eAAe,EAAE,IAAI;QACrB,gBAAgB,EAAE,SAAS;QAC3B,UAAU,EAAE,SAAS;QACrB,WAAW,EAAE,SAAS;QACtB,WAAW,EAAE,SAAS;QACtB,iBAAiB,EAAE,SAAS;QAC5B,gBAAgB,EAAE,SAAS;QAC3B,iBAAiB,EAAE,SAAS;KAC5B,CAAC;IAEF,MAAM,SAAS,GAAG,IAAI,qBAAS,CAAC,qBAAqB,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,IAAA,kCAAe,EAAC,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAClE,CAAC,CAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,YAAY,CAAA,IAAI,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,EAAE,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,mBAAmB,EAAE,CAAC,EAAE,EAAE;QAC7C,MAAM,KAAK,GAAkB,IAAA,yBAAW,EAAC,UAAU,CAAC,CAAC;QACrD,MAAM,UAAU,GAAkB,IAAA,yBAAW,EAAC,UAAU,CAAC,CAAC;QAC1D,MAAM,SAAS,GAAkB;YAChC,QAAQ,EAAE,KAAK;YACf,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,SAAS;YACpB,WAAW,EAAE,IAAI,0BAAW,EAAE;YAC9B,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW;YACxC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW;YACxC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,SAAS;YACpC,SAAS,EAAE;gBACV,MAAM,EAAE;oBACP,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,MAAM;oBAChC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,KAAK;oBAC9B,QAAQ,EAAE,KAAK,CAAC,mBAAmB;iBACnC;gBACD,QAAQ,EAAE;oBACT,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,MAAM;oBAClC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,KAAK;oBAChC,QAAQ,EAAE,KAAK,CAAC,qBAAqB;iBACrC;gBACD,aAAa,EAAE;oBACd,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,MAAM;oBACrC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK;oBACnC,QAAQ,EAAE,UAAU,CAAC,mBAAmB;iBACxC;gBACD,eAAe,EAAE;oBAChB,MAAM,EAAE,UAAU,CAAC,aAAa,CAAC,MAAM;oBACvC,KAAK,EAAE,UAAU,CAAC,aAAa,CAAC,KAAK;oBACrC,QAAQ,EAAE,UAAU,CAAC,qBAAqB;iBAC1C;aACD;SACD,CAAC;QACF,MAAM,SAAS,GAAG,IAAI,qBAAS,CAAC,SAAS,CAAC,CAAC;QAC3C,MAAM,YAAY,GAAG,SAAS,CAAC,oBAAoB,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC9G,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,qBAAqB,EAAE;YAE/C,OAAO,CAAC,IAAI,CAAC,2BAA2B,EAAE,CAAC,EAAE,iBAAiB,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC;YAC1F,MAAM;SACN;QACD,IAAI,CAAC,YAAY,EAAE;YAClB,SAAS;SACT;QACD,IAAI,YAAY,CAAC,MAAM,KAAK,KAAK,EAAE;YAClC,gBAAgB,CAAC,GAAG,EAAE,CAAC;YACvB,gBAAgB,CAAC,SAAS,IAAI,YAAY,CAAC,WAAW,CAAC;YACvD,gBAAgB,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;YAC3D,IAAI,YAAY,CAAC,WAAW,IAAI,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE;gBACxE,gBAAgB,CAAC,SAAS,EAAE,CAAC;aAC7B;SACD;aAAM,IAAI,YAAY,CAAC,MAAM,KAAK,MAAM,EAAE;YAC1C,gBAAgB,CAAC,IAAI,EAAE,CAAC;YACxB,gBAAgB,CAAC,UAAU,IAAI,YAAY,CAAC,WAAW,CAAC;YACxD,gBAAgB,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;YAC5D,QAAQ,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,MAAA,QAAQ,CAAC,YAAY,CAAC,WAAW,CAAC,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACnF,IACC,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM;gBACrC,YAAY,CAAC,WAAW,IAAI,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAChE;gBACD,gBAAgB,CAAC,UAAU,EAAE,CAAC;aAC9B;SACD;aAAM,IAAI,YAAY,CAAC,MAAM,KAAK,MAAM,EAAE;YAC1C,gBAAgB,CAAC,IAAI,EAAE,CAAC;SACxB;QACD,SAAS,CAAC,kBAAkB,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAGlD,IAAI,CAAC,CAAC,iBAAiB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,iBAAiB,KAAK,CAAC,EAAE;YAChE,sBAAsB,CAAC,gBAAgB,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC;YACvE,MAAM,gBAAgB,CAAC;SACvB;KACD;IACD,sBAAsB,CAAC,gBAAgB,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC;IACvE,CAAC,CAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,YAAY,CAAA,IAAI,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACpE,SAAS,CAAC,KAAK,EAAE,CAAC;IAClB,gBAAgB,CAAC,cAAc,GAAG,SAAS,CAAC,mBAAmB,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IAGvF,gBAAgB,CAAC,UAAU,GAAG,EAAE,CAAC;IACjC,gBAAgB,CAAC,WAAW,GAAG,EAAE,CAAC;IAElC,OAAO,gBAAgB,CAAC;AACzB,CAAC,CAAC;AA5HW,QAAA,cAAc,kBA4HzB;AAEF,MAAM,sBAAsB,GAAG,CAAC,gBAAkC,EAAE,KAAoB,EAAE,gBAAwB,EAAE,EAAE;IACrH,MAAM,YAAY,GAAG,gBAAgB,CAAC,GAAG,GAAG,gBAAgB,CAAC,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC;IAC1F,gBAAgB,CAAC,UAAU,GAAG,aAAa,CAC1C,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,EACnE,gBAAgB,CAAC,GAAG,EACpB,YAAY,CACZ,CAAC;IACF,gBAAgB,CAAC,gBAAgB,GAAG,aAAa,CAChD,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,EACzE,gBAAgB,CAAC,SAAS,EAC1B,YAAY,CACZ,CAAC;IACF,gBAAgB,CAAC,WAAW,GAAG,aAAa,CAC3C,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,EACpE,gBAAgB,CAAC,IAAI,EACrB,YAAY,CACZ,CAAC;IACF,gBAAgB,CAAC,iBAAiB,GAAG,aAAa,CACjD,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,EAC1E,gBAAgB,CAAC,UAAU,EAC3B,YAAY,CACZ,CAAC;IACF,gBAAgB,CAAC,WAAW,GAAG,aAAa,CAC3C,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,gBAAgB,CAAC,WAAW,GAAG,gBAAgB,CAAC,UAAU,CAAC,EAC7E,gBAAgB,CAAC,IAAI,EACrB,YAAY,CACZ,CAAC;IAIF,MAAM,cAAc,GAAG,gBAAgB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9E,MAAM,eAAe,GAAG,gBAAgB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAChF,MAAM,cAAc,GAAG,oBAAoB,CAAC,gBAAgB,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;IAC3F,MAAM,eAAe,GAAG,oBAAoB,CAAC,gBAAgB,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAC7F,gBAAgB,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrG,gBAAgB,CAAC,iBAAiB,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACzG,gBAAgB,CAAC,cAAc,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/E,gBAAgB,CAAC,eAAe,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC;IAElF,IACC,gBAAgB,CAAC,gBAAgB,GAAG,CAAC;QACrC,gBAAgB,CAAC,gBAAgB,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,EACtE;QACD,OAAO,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;KACzC;IACD,IACC,gBAAgB,CAAC,iBAAiB,GAAG,CAAC;QACtC,gBAAgB,CAAC,iBAAiB,GAAG,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,UAAU,EACzE;QACD,OAAO,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;KAC1C;AACF,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,CAAC,WAAqB,EAAE,gBAAwB,EAAgC,EAAE;IAC9G,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE;QAC7B,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;KAC1B;IAGD,MAAM,YAAY,GAAG,CAAC,GAAG,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAG5D,MAAM,UAAU,GAAG,CAAC,GAAa,EAAE,CAAS,EAAE,EAAE;QAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;QACzC,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,EAAE,CAAC,GAAG,gBAAgB,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;IAE7D,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;AAC3C,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,YAAoB,EAAE,YAAoB,EAAE,UAAkB,EAAU,EAAE;IAChG,IAAI,YAAY,KAAK,CAAC,IAAI,YAAY,KAAK,CAAC,EAAE;QAC7C,OAAO,IAAI,CAAC;KACZ;IACD,IAAI,YAAY,KAAK,GAAG,IAAI,YAAY,KAAK,UAAU,EAAE;QACxD,OAAO,IAAI,CAAC;KACZ;IACD,OAAO,YAAY,CAAC;AACrB,CAAC,CAAC;AAGF,MAAM,8BAA8B,GAAG;;;;;;;;;;;;;;;;;;;;;CAyBtC,CAAC;AACF,MAAM,uCAAuC,GAAG,EAAE,CAAC;AAC5C,MAAM,6BAA6B,GAAG,CAAC,MAAc,EAAW,EAAE;IACxE,IAAI,8BAA8B,CAAC,QAAQ,CAAC,MAAiB,CAAC,EAAE;QAC/D,OAAO,IAAI,CAAC;KACZ;IACD,IAAI,uCAAuC,CAAC,MAAM,KAAK,CAAC,EAAE;QACzD,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,6BAAY,CAAC,EAAE;YAEnD,IAAI,IAAA,+CAA8B,EAAC,QAAQ,CAAC,EAAE;gBAC7C,uCAAuC,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;aAClE;SACD;KACD;IACD,OAAO,uCAAuC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACjE,CAAC,CAAC;AAbW,QAAA,6BAA6B,iCAaxC","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { AllCardsService, CardIds } from '@firestone-hs/reference-data';\r\nimport { BgsBattleInfo } from './bgs-battle-info';\r\nimport { hasDeathrattleSpawnEnchantment } from './cards/card.interface';\r\nimport { CardsData } from './cards/cards-data';\r\nimport { cardMappings } from './cards/impl/_card-mappings';\r\nimport { cloneInput3 } from './input-clone';\r\nimport { buildFinalInput } from './input-sanitation';\r\nimport { SimulationResult } from './simulation-result';\r\nimport { FullGameState } from './simulation/internal-game-state';\r\nimport { SharedState } from './simulation/shared-state';\r\nimport { Simulator } from './simulation/simulator';\r\nimport { Spectator } from './simulation/spectator/spectator';\r\n\r\nlet globalCards = new AllCardsService();\r\n\r\nexport const assignCards = (cards: AllCardsService) => {\r\n\tglobalCards = cards;\r\n};\r\n\r\n// This example demonstrates a NodeJS 8.10 async handler[1], however of course you could use\r\n// the more traditional callback-style handler.\r\n// [1]: https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/\r\nexport default async (event): Promise<any> => {\r\n\tif (!event.body?.length) {\r\n\t\tconsole.warn('missing event body', event);\r\n\t\treturn;\r\n\t}\r\n\r\n\tconst battleInput: BgsBattleInfo = JSON.parse(event.body);\r\n\tconst cards = globalCards;\r\n\tawait cards.initializeCardsDb();\r\n\tconst cardsData = new CardsData(cards, false);\r\n\tcardsData.inititialize(\r\n\t\tbattleInput.gameState?.validTribes ?? battleInput.options?.validTribes,\r\n\t\tbattleInput.gameState?.anomalies ?? [],\r\n\t);\r\n\tconst battleIterator = simulateBattle(battleInput, cards, cardsData);\r\n\r\n\t// Iterate through all intermediate results to reach the final result\r\n\tlet result = battleIterator.next();\r\n\twhile (!result.done) {\r\n\t\tresult = battleIterator.next();\r\n\t}\r\n\r\n\tconst simulationResult = result.value;\r\n\t// console.debug('simulationResult', simulationResult);\r\n\r\n\tconst response = {\r\n\t\tstatusCode: 200,\r\n\t\tisBase64Encoded: false,\r\n\t\tbody: JSON.stringify(simulationResult),\r\n\t};\r\n\treturn response;\r\n};\r\n\r\nexport const simulateBattle = function* (\r\n\tbattleInput: BgsBattleInfo,\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n): Generator<SimulationResult, SimulationResult, void> {\r\n\tif (!cards?.getCards()?.length) {\r\n\t\tconsole.error('[simulate-bgs-battle] reference cards are empty, cannot simulate battle', cards);\r\n\t\treturn null;\r\n\t}\r\n\t// !battleInput.options?.skipInfoLogs && console.time('full-sim');\r\n\tconst start = Date.now();\r\n\tconst maxAcceptableDuration = battleInput.options?.maxAcceptableDuration || 8000;\r\n\tconst numberOfSimulations = battleInput.options?.numberOfSimulations || 8000;\r\n\tconst intermediateSteps = battleInput.options?.intermediateResults ?? 200;\r\n\tconst damageConfidence = battleInput.options?.damageConfidence ?? 0.9;\r\n\tconst includeOutcomeSamples = battleInput.options?.includeOutcomeSamples ?? true;\r\n\tconst simulationResult: SimulationResult = {\r\n\t\twonLethal: 0,\r\n\t\twon: 0,\r\n\t\ttied: 0,\r\n\t\tlost: 0,\r\n\t\tlostLethal: 0,\r\n\t\tdamageWons: [],\r\n\t\tdamageWon: 0,\r\n\t\tdamageWonRange: null,\r\n\t\tdamageLosts: [],\r\n\t\tdamageLost: 0,\r\n\t\tdamageLostRange: null,\r\n\t\twonLethalPercent: undefined,\r\n\t\twonPercent: undefined,\r\n\t\ttiedPercent: undefined,\r\n\t\tlostPercent: undefined,\r\n\t\tlostLethalPercent: undefined,\r\n\t\taverageDamageWon: undefined,\r\n\t\taverageDamageLost: undefined,\r\n\t};\r\n\r\n\tconst spectator = new Spectator(includeOutcomeSamples);\r\n\tconst inputReady = buildFinalInput(battleInput, cards, cardsData);\r\n\t!battleInput.options?.skipInfoLogs && console.time('simulation');\r\n\tconst outcomes = {};\r\n\tfor (let i = 0; i < numberOfSimulations; i++) {\r\n\t\tconst input: BgsBattleInfo = cloneInput3(inputReady);\r\n\t\tconst inputClone: BgsBattleInfo = cloneInput3(inputReady);\r\n\t\tconst gameState: FullGameState = {\r\n\t\t\tallCards: cards,\r\n\t\t\tcardsData: cardsData,\r\n\t\t\tspectator: spectator,\r\n\t\t\tsharedState: new SharedState(),\r\n\t\t\tcurrentTurn: input.gameState.currentTurn,\r\n\t\t\tvalidTribes: input.gameState.validTribes,\r\n\t\t\tanomalies: input.gameState.anomalies,\r\n\t\t\tgameState: {\r\n\t\t\t\tplayer: {\r\n\t\t\t\t\tplayer: input.playerBoard.player,\r\n\t\t\t\t\tboard: input.playerBoard.board,\r\n\t\t\t\t\tteammate: input.playerTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\topponent: {\r\n\t\t\t\t\tplayer: input.opponentBoard.player,\r\n\t\t\t\t\tboard: input.opponentBoard.board,\r\n\t\t\t\t\tteammate: input.opponentTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\tplayerInitial: {\r\n\t\t\t\t\tplayer: inputClone.playerBoard.player,\r\n\t\t\t\t\tboard: inputClone.playerBoard.board,\r\n\t\t\t\t\tteammate: inputClone.playerTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\topponentInitial: {\r\n\t\t\t\t\tplayer: inputClone.opponentBoard.player,\r\n\t\t\t\t\tboard: inputClone.opponentBoard.board,\r\n\t\t\t\t\tteammate: inputClone.opponentTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t},\r\n\t\t};\r\n\t\tconst simulator = new Simulator(gameState);\r\n\t\tconst battleResult = simulator.simulateSingleBattle(gameState.gameState.player, gameState.gameState.opponent);\r\n\t\tif (Date.now() - start > maxAcceptableDuration) {\r\n\t\t\t// Can happen in case of inifinite boards, or a bug. Don't hog the user's computer in that case\r\n\t\t\tconsole.warn('Stopping simulation after', i, 'iterations and ', Date.now() - start, 'ms');\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tif (!battleResult) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif (battleResult.result === 'won') {\r\n\t\t\tsimulationResult.won++;\r\n\t\t\tsimulationResult.damageWon += battleResult.damageDealt;\r\n\t\t\tsimulationResult.damageWons.push(battleResult.damageDealt);\r\n\t\t\tif (battleResult.damageDealt >= battleInput.opponentBoard.player.hpLeft) {\r\n\t\t\t\tsimulationResult.wonLethal++;\r\n\t\t\t}\r\n\t\t} else if (battleResult.result === 'lost') {\r\n\t\t\tsimulationResult.lost++;\r\n\t\t\tsimulationResult.damageLost += battleResult.damageDealt;\r\n\t\t\tsimulationResult.damageLosts.push(battleResult.damageDealt);\r\n\t\t\toutcomes[battleResult.damageDealt] = (outcomes[battleResult.damageDealt] ?? 0) + 1;\r\n\t\t\tif (\r\n\t\t\t\tbattleInput.playerBoard.player.hpLeft &&\r\n\t\t\t\tbattleResult.damageDealt >= battleInput.playerBoard.player.hpLeft\r\n\t\t\t) {\r\n\t\t\t\tsimulationResult.lostLethal++;\r\n\t\t\t}\r\n\t\t} else if (battleResult.result === 'tied') {\r\n\t\t\tsimulationResult.tied++;\r\n\t\t}\r\n\t\tspectator.commitBattleResult(battleResult.result);\r\n\r\n\t\t// Yield intermediate result every 200 iterations\r\n\t\tif (!!intermediateSteps && i > 0 && i % intermediateSteps === 0) {\r\n\t\t\tupdateSimulationResult(simulationResult, inputReady, damageConfidence);\r\n\t\t\tyield simulationResult;\r\n\t\t}\r\n\t}\r\n\tupdateSimulationResult(simulationResult, inputReady, damageConfidence);\r\n\t!battleInput.options?.skipInfoLogs && console.timeEnd('simulation');\r\n\tspectator.prune();\r\n\tsimulationResult.outcomeSamples = spectator.buildOutcomeSamples(battleInput.gameState);\r\n\t// Avoid sending this verbose data\r\n\r\n\tsimulationResult.damageWons = [];\r\n\tsimulationResult.damageLosts = [];\r\n\t// !battleInput.options?.skipInfoLogs && console.timeEnd('full-sim');\r\n\treturn simulationResult;\r\n};\r\n\r\nconst updateSimulationResult = (simulationResult: SimulationResult, input: BgsBattleInfo, damageConfidence: number) => {\r\n\tconst totalMatches = simulationResult.won + simulationResult.tied + simulationResult.lost;\r\n\tsimulationResult.wonPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.won)) / totalMatches) / 10,\r\n\t\tsimulationResult.won,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.wonLethalPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10,\r\n\t\tsimulationResult.wonLethal,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.lostPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.lost)) / totalMatches) / 10,\r\n\t\tsimulationResult.lost,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.lostLethalPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10,\r\n\t\tsimulationResult.lostLethal,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.tiedPercent = checkRounding(\r\n\t\tMath.max(0, 100 - simulationResult.lostPercent - simulationResult.wonPercent),\r\n\t\tsimulationResult.tied,\r\n\t\ttotalMatches,\r\n\t);\r\n\r\n\t// simulationResult.wonLethalPercent = Math.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10;\r\n\t// simulationResult.lostLethalPercent = Math.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10;\r\n\tconst totalDamageWon = simulationResult.damageWons.reduce((a, b) => a + b, 0);\r\n\tconst totalDamageLost = simulationResult.damageLosts.reduce((a, b) => a + b, 0);\r\n\tconst damageWonRange = calculateDamageRange(simulationResult.damageWons, damageConfidence);\r\n\tconst damageLostRange = calculateDamageRange(simulationResult.damageLosts, damageConfidence);\r\n\tsimulationResult.averageDamageWon = simulationResult.won ? totalDamageWon / simulationResult.won : 0;\r\n\tsimulationResult.averageDamageLost = simulationResult.lost ? totalDamageLost / simulationResult.lost : 0;\r\n\tsimulationResult.damageWonRange = simulationResult.won ? damageWonRange : null;\r\n\tsimulationResult.damageLostRange = simulationResult.lost ? damageLostRange : null;\r\n\r\n\tif (\r\n\t\tsimulationResult.averageDamageWon > 0 &&\r\n\t\tsimulationResult.averageDamageWon < input.playerBoard.player.tavernTier\r\n\t) {\r\n\t\tconsole.warn('average damage won issue');\r\n\t}\r\n\tif (\r\n\t\tsimulationResult.averageDamageLost > 0 &&\r\n\t\tsimulationResult.averageDamageLost < input.opponentBoard.player.tavernTier\r\n\t) {\r\n\t\tconsole.warn('average damage lost issue');\r\n\t}\r\n};\r\n\r\nconst calculateDamageRange = (damageArray: number[], damageConfidence: number): { min: number; max: number } => {\r\n\tif (damageArray.length === 0) {\r\n\t\treturn { min: 0, max: 0 };\r\n\t}\r\n\r\n\t// Sort the array\r\n\tconst sortedDamage = [...damageArray].sort((a, b) => a - b);\r\n\r\n\t// Calculate the 10th and 90th percentiles\r\n\tconst percentile = (arr: number[], p: number) => {\r\n\t\tconst index = Math.floor(p * arr.length);\r\n\t\treturn arr[index];\r\n\t};\r\n\r\n\tconst minDamage = percentile(sortedDamage, 1 - damageConfidence);\r\n\tconst maxDamage = percentile(sortedDamage, damageConfidence);\r\n\r\n\treturn { min: minDamage, max: maxDamage };\r\n};\r\n\r\nconst checkRounding = (roundedValue: number, initialValue: number, totalValue: number): number => {\r\n\tif (roundedValue === 0 && initialValue !== 0) {\r\n\t\treturn 0.01;\r\n\t}\r\n\tif (roundedValue === 100 && initialValue !== totalValue) {\r\n\t\treturn 99.9;\r\n\t}\r\n\treturn roundedValue;\r\n};\r\n\r\n// Used when triggering random deathrattles\r\nconst VALID_DEATHRATTLE_ENCHANTMENTS = [\r\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_BG_BOT_312e,\r\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_TB_BaconUps_032e,\r\n\tCardIds.LivingSpores_LivingSporesEnchantment,\r\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000e,\r\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000_Ge,\r\n\tCardIds.Sneed_SneedsReplicator,\r\n\tCardIds.SneedsReplicator_ReplicateEnchantment,\r\n\tCardIds.EarthRecollectionEnchantment, // Spirit Raptor\r\n\tCardIds.FireRecollectionEnchantment,\r\n\tCardIds.LightningRecollectionEnchantment,\r\n\tCardIds.WaterRecollectionEnchantment,\r\n\tCardIds.EarthInvocation_ElementEarthEnchantment, // Summon a 1/1\r\n\tCardIds.LightningInvocation, // Deal 1 damage to 5 enemy minions\r\n\t// CardIds.SurfNSurf_CrabRidingEnchantment_BG27_004e,\r\n\t// CardIds.SurfNSurf_CrabRidingEnchantment_BG27_004_Ge,\r\n\t// CardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055e,\r\n\t// CardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055_Ge,\r\n\tCardIds.BoonOfBeetles_BeetleSwarmEnchantment_BG28_603e,\r\n\tCardIds.RustyTrident_TridentsTreasureEnchantment_BG30_MagicItem_917e,\r\n\tCardIds.HoggyBank_GemInTheBankEnchantment_BG30_MagicItem_411e,\r\n\tCardIds.JarredFrostling_FrostyGlobeEnchantment_BG30_MagicItem_952e,\r\n\tCardIds.CaduceusReactor_CaduceusReactorEnchantment_BG31_HERO_801ptee,\r\n\tCardIds.AutoAssembler_AutoAssemblerEnchantment_BG32_172e,\r\n\tCardIds.AutoAssembler_AutoAssemblerEnchantment_BG32_172_Ge,\r\n];\r\nconst validDeathrattleEnchantmentsFromMapping = [];\r\nexport const isValidDeathrattleEnchantment = (cardId: string): boolean => {\r\n\tif (VALID_DEATHRATTLE_ENCHANTMENTS.includes(cardId as CardIds)) {\r\n\t\treturn true;\r\n\t}\r\n\tif (validDeathrattleEnchantmentsFromMapping.length === 0) {\r\n\t\tfor (const cardImpl of Object.values(cardMappings)) {\r\n\t\t\t// Also includes non-enchantments, but since we only match this against the enchants list, it's fine\r\n\t\t\tif (hasDeathrattleSpawnEnchantment(cardImpl)) {\r\n\t\t\t\tvalidDeathrattleEnchantmentsFromMapping.push(...cardImpl.cardIds);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn validDeathrattleEnchantmentsFromMapping.includes(cardId);\r\n};\r\n\r\n// const cleanEnchantmentsForEntity = (\r\n// \tenchantments: { cardId: string; originEntityId?: number; timing: number }[],\r\n// \tentityIds: readonly number[],\r\n// ): { cardId: string; originEntityId?: number; timing: number }[] => {\r\n// \treturn enchantments.filter(\r\n// \t\t(enchant) =>\r\n// \t\t\tentityIds.indexOf(enchant.originEntityId) !== -1 ||\r\n// \t\t\tvalidEnchantments.indexOf(enchant.cardId as CardIds) !== -1,\r\n// \t);\r\n// };\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firestone-hs/simulate-bgs-battle",
3
- "version": "1.1.610",
3
+ "version": "1.1.612",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "lint": "eslint --color --fix --ext .ts .",