Add exhaust keyword to playCard

This commit is contained in:
Jared Miller 2026-02-25 09:19:59 -05:00
parent 77f65ace98
commit fe95c03529
Signed by: shmup
GPG key ID: 22B5C6D66A38B06C
2 changed files with 48 additions and 2 deletions

View file

@ -164,12 +164,20 @@ export function playCard(state, handIndex, opts = {}) {
const card = getCard(cardId); const card = getCard(cardId);
if (player.energy < card.cost) return null; if (player.energy < card.cost) return null;
if (card.keywords?.includes("unplayable")) return null;
const hand = [...player.hand]; const hand = [...player.hand];
hand.splice(handIndex, 1); hand.splice(handIndex, 1);
const discardPile = [...player.discardPile, cardId]; const exhausted = card.keywords?.includes("exhaust");
const discardPile = exhausted
? [...player.discardPile]
: [...player.discardPile, cardId];
const exhaustPile = exhausted
? [...player.exhaustPile, cardId]
: [...player.exhaustPile];
const energy = player.energy - card.cost; const energy = player.energy - card.cost;
const updatedPlayer = { ...player, hand, discardPile, energy }; const updatedPlayer = { ...player, hand, discardPile, exhaustPile, energy };
const players = state.players.map((p, i) => const players = state.players.map((p, i) =>
i === playerIndex ? updatedPlayer : p, i === playerIndex ? updatedPlayer : p,
); );

View file

@ -316,3 +316,41 @@ describe("createCombatFromRun", () => {
expect(state.enemy).toBe(state.enemies[0]); expect(state.enemy).toBe(state.enemies[0]);
}); });
}); });
describe("playCard - exhaust", () => {
test("exhaust card goes to exhaustPile instead of discardPile", () => {
let state = createCombatState("ironclad", "jaw_worm");
state = drawCards(state, 5);
// manually put true_grit in hand
const player = {
...state.player,
hand: [...state.player.hand, "true_grit"],
};
state = { ...state, player, players: [player] };
const handIndex = state.player.hand.indexOf("true_grit");
const discardBefore = [...state.player.discardPile];
const next = playCard(state, handIndex);
expect(next.player.hand).toHaveLength(state.player.hand.length - 1);
expect(next.player.exhaustPile).toContain("true_grit");
expect(next.player.discardPile).toEqual(discardBefore);
expect(next.player.energy).toBe(state.player.energy - 1);
});
});
describe("playCard - unplayable", () => {
test("unplayable card cannot be played", () => {
let state = createCombatState("ironclad", "jaw_worm");
state = drawCards(state, 5);
// manually put tactician in hand
const player = {
...state.player,
hand: [...state.player.hand, "tactician"],
};
state = { ...state, player, players: [player] };
const handIndex = state.player.hand.indexOf("tactician");
const handBefore = [...state.player.hand];
const result = playCard(state, handIndex);
expect(result).toBeNull();
expect(state.player.hand).toEqual(handBefore);
});
});