From 8a69ca9f7360bdf9228ef4bb7e3f5d11df1583b5 Mon Sep 17 00:00:00 2001 From: Garrett Mills Date: Wed, 28 Oct 2026 22:03:45 -0500 Subject: [PATCH] Deck builder: cost tiles for unowned cards and cards in other decks Idea and Building decks get two more Deck analysis tiles: what the copies you don't own would cost, and what the owned copies other building/built decks are holding are worth. Both count copies, not cards. Co-Authored-By: Claude Opus 5.5 --- src/deckAnalysis.ts | 17 ++++++++++++++--- src/views/DeckView.tsx | 6 ++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/deckAnalysis.ts b/src/deckAnalysis.ts index b9b8ef1..746553d 100644 --- a/src/deckAnalysis.ts +++ b/src/deckAnalysis.ts @@ -6,6 +6,10 @@ import { COLORS, Deck, DeckEntry, isPhysical, legalStatusFor, Partner } from "./ /** Copies of a deck card you'd need to acquire to cover the deck. */ export const shortBy = (e: DeckEntry) => Math.max(0, e.quantity - e.quantity_owned); +/** Owned copies of a deck card you can't use because other building/built + * decks claim them. */ +export const claimedElsewhere = (e: DeckEntry) => Math.max(0, Math.min(e.quantity, e.quantity_owned) - e.quantity_spare); + export interface DeckStats { totalCards: number; uniqueCards: number; @@ -14,6 +18,10 @@ export interface DeckStats { /** USD for every copy in the deck, commander included; cards without a * known price count as $0. */ totalCost: number; + /** USD for the copies you'd need to buy (see `shortBy`). */ + unownedCost: number; + /** USD for the owned copies other decks are holding (see `claimedElsewhere`). */ + elsewhereCost: number; curve: { label: string; count: number; @@ -102,9 +110,10 @@ export function computeDeckStats(contents: DeckEntry[]): DeckStats { } // Unlike the rest, cost counts the commander: it's a card you have to buy. - const totalCost = contents - .filter((e) => !e.is_maybeboard) - .reduce((sum, e) => sum + e.price_usd * e.quantity, 0); + const mainboard = contents.filter((e) => !e.is_maybeboard); + const totalCost = mainboard.reduce((sum, e) => sum + e.price_usd * e.quantity, 0); + const unownedCost = mainboard.reduce((sum, e) => sum + e.price_usd * shortBy(e), 0); + const elsewhereCost = mainboard.reduce((sum, e) => sum + e.price_usd * claimedElsewhere(e), 0); return { totalCards, @@ -112,6 +121,8 @@ export function computeDeckStats(contents: DeckEntry[]): DeckStats { landCount, avgManaValue, totalCost, + unownedCost, + elsewhereCost, curve, colorCounts, colorlessCount, diff --git a/src/views/DeckView.tsx b/src/views/DeckView.tsx index b9e6de0..b85d828 100644 --- a/src/views/DeckView.tsx +++ b/src/views/DeckView.tsx @@ -1299,6 +1299,12 @@ function DeckBuilder({ + {(deck.status === "idea" || deck.status === "building") && ( + <> + + + + )}