From 46bd6e6d2bec14c571c0da9b816e8ea7f273b730 Mon Sep 17 00:00:00 2001 From: Jared Miller Date: Tue, 24 Feb 2026 22:36:18 -0500 Subject: [PATCH] Add reward reveal, pick, and skip functions to run module --- src/run.js | 21 +++++++++++++++++ src/run.test.js | 62 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/src/run.js b/src/run.js index 38f57bc..be0daa2 100644 --- a/src/run.js +++ b/src/run.js @@ -13,6 +13,27 @@ export function createRunState(character) { }; } +export function revealRewards(run) { + const count = Math.min(3, run.cardRewardsDeck.length); + const revealed = run.cardRewardsDeck.slice(0, count); + const cardRewardsDeck = run.cardRewardsDeck.slice(count); + return { revealed, run: { ...run, cardRewardsDeck } }; +} + +export function pickReward(run, revealed, index) { + return { + ...run, + deck: [...run.deck, revealed[index]], + }; +} + +export function skipRewards(run, revealed) { + return { + ...run, + cardRewardsDeck: shuffle([...run.cardRewardsDeck, ...revealed]), + }; +} + function buildRewardsDeck(character) { const ids = []; for (const card of getAllCards()) { diff --git a/src/run.test.js b/src/run.test.js index 56c0886..59ae0db 100644 --- a/src/run.test.js +++ b/src/run.test.js @@ -1,7 +1,12 @@ import { beforeAll, describe, expect, test } from "bun:test"; import { getAllCards, initCards } from "./cards.js"; import { initEnemies } from "./enemies.js"; -import { createRunState } from "./run.js"; +import { + createRunState, + pickReward, + revealRewards, + skipRewards, +} from "./run.js"; beforeAll(async () => { await Promise.all([initCards(), initEnemies()]); @@ -49,3 +54,58 @@ describe("createRunState", () => { expect(allSorted).toBe(false); }); }); + +describe("rewards", () => { + test("revealRewards removes 3 from rewards deck and returns them", () => { + const run = createRunState("ironclad"); + const originalLen = run.cardRewardsDeck.length; + const { revealed, run: updated } = revealRewards(run); + expect(revealed).toHaveLength(3); + expect(updated.cardRewardsDeck).toHaveLength(originalLen - 3); + }); + + test("revealRewards handles deck with fewer than 3 cards", () => { + const run = createRunState("ironclad"); + const modified = { ...run, cardRewardsDeck: ["card_a", "card_b"] }; + const { revealed, run: updated } = revealRewards(modified); + expect(revealed).toHaveLength(2); + expect(updated.cardRewardsDeck).toHaveLength(0); + }); + + test("revealRewards with empty deck returns empty revealed", () => { + const run = { ...createRunState("ironclad"), cardRewardsDeck: [] }; + const { revealed, run: updated } = revealRewards(run); + expect(revealed).toHaveLength(0); + expect(updated.cardRewardsDeck).toHaveLength(0); + }); + + test("pickReward adds picked card to deck", () => { + const run = createRunState("ironclad"); + const originalDeckLen = run.deck.length; + const { revealed, run: afterReveal } = revealRewards(run); + const updated = pickReward(afterReveal, revealed, 0); + expect(updated.deck).toHaveLength(originalDeckLen + 1); + expect(updated.deck).toContain(revealed[0]); + }); + + test("pickReward discards unpicked cards", () => { + const run = createRunState("ironclad"); + const { revealed, run: afterReveal } = revealRewards(run); + const rewardsDeckLen = afterReveal.cardRewardsDeck.length; + const updated = pickReward(afterReveal, revealed, 1); + // unpicked cards are gone, not returned to rewards deck + expect(updated.cardRewardsDeck).toHaveLength(rewardsDeckLen); + expect(updated.deck).not.toContain(revealed[0]); + expect(updated.deck).toContain(revealed[1]); + expect(updated.deck).not.toContain(revealed[2]); + }); + + test("skipRewards reshuffles all 3 back into rewards deck", () => { + const run = createRunState("ironclad"); + const { revealed, run: afterReveal } = revealRewards(run); + const rewardsDeckLen = afterReveal.cardRewardsDeck.length; + const updated = skipRewards(afterReveal, revealed); + expect(updated.cardRewardsDeck).toHaveLength(rewardsDeckLen + 3); + expect(updated.deck).toHaveLength(run.deck.length); // deck unchanged + }); +});