111 lines
3.8 KiB
Markdown
111 lines
3.8 KiB
Markdown
## Registry System: Position-Based Card Details
|
|
|
|
### Overview
|
|
The registry uses a **position-based lookup system** that maps card positions (1-78) to interpretive data stored in `CardDetailsRegistry`. This system is independent of card names, allowing the same registry entries to work across different deck variants.
|
|
|
|
### Design Principle
|
|
**Card position is the permanent identifier**, not the card name. This means:
|
|
- Card #44 is always "Magus position" in the deck order
|
|
- If you rename card #44 to "Magus", "Magician", "Mage", or any other variant, it still maps to the same registry entry
|
|
- Different deck variants can have completely different names but use the same spiritual/interpretive data
|
|
|
|
### File Organization
|
|
Your deck files follow this numbering (which drives card position):
|
|
- **1-14**: Cups (Ace, Ten, 2-9, Knight, Prince, Princess, Queen)
|
|
- **15-28**: Pentacles/Disks (same structure)
|
|
- **29-42**: Swords (same structure)
|
|
- **43-64**: Major Arcana (43=Fool, 44=Magus, ..., 64=Universe)
|
|
- **65-78**: Wands (same structure)
|
|
|
|
Example: `44_Magus.webp` → Card at position 44 → Magus name → Registry position 44 → Details for position 44
|
|
|
|
### Position-Based Lookup Process
|
|
|
|
```
|
|
Card created with number (position)
|
|
↓
|
|
card.number = 44
|
|
↓
|
|
load_into_card(card)
|
|
↓
|
|
get_by_position(44)
|
|
↓
|
|
Position 44 maps to registry key "I" (1st trump after Fool)
|
|
↓
|
|
registry.get("I") → Returns Magician/Magus details
|
|
↓
|
|
Details loaded into card object (independent of card.name)
|
|
```
|
|
|
|
### Position Mapping
|
|
|
|
**Minor Arcana Positions:**
|
|
- 1-14: Cups - Maps to "Ace of Cups" through "Queen of Cups"
|
|
- 15-28: Pentacles - Maps to "Ace of Pentacles" through "Queen of Pentacles"
|
|
- 29-42: Swords - Maps to "Ace of Swords" through "Queen of Swords"
|
|
- 65-78: Wands - Maps to "Ace of Wands" through "Queen of Wands"
|
|
|
|
**Major Arcana Positions:**
|
|
- 43 → "o" (Roman for 0/Fool)
|
|
- 44 → "I" (Roman for 1/Magus)
|
|
- 45 → "II" (Roman for 2)
|
|
- ...continuing through...
|
|
- 64 → "XXI" (Roman for 21/Universe)
|
|
|
|
### Implementation
|
|
|
|
```python
|
|
def _build_position_map(self) -> Dict[int, str]:
|
|
"""
|
|
Maps card position (1-78) to registry key:
|
|
- Minor Arcana: position → card name ("Ace of Cups", etc.)
|
|
- Major Arcana: position → Roman numeral ("o", "I", "II", etc.)
|
|
"""
|
|
# Builds complete 1-78 mapping
|
|
return position_map
|
|
|
|
def get_by_position(self, position: int) -> Optional[Dict[str, Any]]:
|
|
"""Get details for a card by its position (1-78)."""
|
|
registry_key = self._position_map.get(position)
|
|
return self._details.get(registry_key)
|
|
|
|
def load_into_card(self, card: 'Card') -> bool:
|
|
"""Load card details using position-based lookup."""
|
|
details = self.get_by_position(card.number)
|
|
# Populate card with: explanation, interpretation, keywords, etc.
|
|
```
|
|
|
|
### Why Position-Based?
|
|
|
|
1. **Deck Variant Independence**: Different decks can use completely different names
|
|
2. **Stable Identity**: Card position never changes across variants
|
|
3. **Scalable**: Easily support new deck variants by just changing card names
|
|
4. **Future Proof**: New interpretations can be added keyed to positions, not names
|
|
|
|
### Example Flow
|
|
|
|
File: `44_Magus.webp`
|
|
↓
|
|
Card object: number=44, name="Magus", arcana="Major"
|
|
↓
|
|
`load_into_card(card)` called
|
|
↓
|
|
`get_by_position(44)` returns registry key "I"
|
|
↓
|
|
Registry lookup: `registry.get("I")`
|
|
↓
|
|
Populates card with Magician/Magus interpretation:
|
|
- keywords: ["manifestation", "resourcefulness", ...]
|
|
- interpretation: "Communication; Conscious Will; ..."
|
|
- guidance: "Focus your energy and intention..."
|
|
|
|
### Key Point
|
|
|
|
Even if you rename card #44 to something completely different, it will still load the same interpretation because the lookup is based on **position (44)**, not **name ("Magus")**.
|
|
|
|
↓
|
|
Registry lookup: `registry.get("o")`
|
|
↓
|
|
Populates card with: explanation, interpretation, keywords, etc.
|
|
|