From 11e12ee906685c426890f019cef3785889afd175 Mon Sep 17 00:00:00 2001 From: Jared Miller Date: Tue, 24 Feb 2026 22:35:21 -0500 Subject: [PATCH] Add run state module with createRunState and rewards deck builder --- src/run.js | 28 +++++++++++++++++++++++++++ src/run.test.js | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 src/run.js create mode 100644 src/run.test.js diff --git a/src/run.js b/src/run.js new file mode 100644 index 0000000..38f57bc --- /dev/null +++ b/src/run.js @@ -0,0 +1,28 @@ +import { getAllCards, getStarterDeck } from "./cards.js"; +import { shuffle } from "./state.js"; + +export function createRunState(character) { + return { + character, + hp: 11, + maxHp: 11, + deck: [...getStarterDeck(character)], + cardRewardsDeck: buildRewardsDeck(character), + potions: [], + combatCount: 0, + }; +} + +function buildRewardsDeck(character) { + const ids = []; + for (const card of getAllCards()) { + if ( + card.character === character && + (card.rarity === "common" || card.rarity === "uncommon") && + !card.id.endsWith("+") + ) { + ids.push(card.id); + } + } + return shuffle(ids); +} diff --git a/src/run.test.js b/src/run.test.js new file mode 100644 index 0000000..56c0886 --- /dev/null +++ b/src/run.test.js @@ -0,0 +1,51 @@ +import { beforeAll, describe, expect, test } from "bun:test"; +import { getAllCards, initCards } from "./cards.js"; +import { initEnemies } from "./enemies.js"; +import { createRunState } from "./run.js"; + +beforeAll(async () => { + await Promise.all([initCards(), initEnemies()]); +}); + +describe("createRunState", () => { + test("initializes ironclad with correct defaults", () => { + const run = createRunState("ironclad"); + expect(run.character).toBe("ironclad"); + expect(run.hp).toBe(11); + expect(run.maxHp).toBe(11); + expect(run.deck).toEqual([ + "strike_r", + "strike_r", + "strike_r", + "strike_r", + "strike_r", + "defend_r", + "defend_r", + "defend_r", + "defend_r", + "bash", + ]); + expect(run.combatCount).toBe(0); + expect(run.potions).toEqual([]); + }); + + test("rewards deck has more than 20 cards, excludes starters and rares and upgraded", () => { + const run = createRunState("ironclad"); + expect(run.cardRewardsDeck.length).toBeGreaterThan(20); + for (const cardId of run.cardRewardsDeck) { + const card = getAllCards().find((c) => c.id === cardId); + expect(card).toBeDefined(); + expect(card.rarity).not.toBe("starter"); + expect(card.rarity).not.toBe("rare"); + expect(cardId.endsWith("+")).toBe(false); + } + }); + + test("rewards deck is shuffled", () => { + const run = createRunState("ironclad"); + const sorted = [...run.cardRewardsDeck].sort(); + // at least one card should be out of sorted order + const allSorted = run.cardRewardsDeck.every((id, i) => id === sorted[i]); + expect(allSorted).toBe(false); + }); +});