mirror of
https://github.com/mwisnowski/mtg_python_deckbuilder.git
synced 2025-12-16 23:50:12 +01:00
feature: add non-basic land types to tagging mechanics
This commit is contained in:
parent
fbb85645e6
commit
4a8d71b16b
6 changed files with 402 additions and 177 deletions
|
|
@ -44,8 +44,14 @@ class LandMiscUtilityMixin:
|
|||
return
|
||||
basics = self._basic_land_names()
|
||||
already = set(self.card_library.keys())
|
||||
top_n = getattr(bc, 'MISC_LAND_TOP_POOL_SIZE', 30)
|
||||
top_n = getattr(bc, 'MISC_LAND_TOP_POOL_SIZE', 60)
|
||||
use_full = getattr(bc, 'MISC_LAND_USE_FULL_POOL', False)
|
||||
if not use_full:
|
||||
rng = getattr(self, 'rng', None)
|
||||
pool_multiplier = rng.uniform(1.2, 2.0) if rng else 1.5
|
||||
top_n = int(top_n * pool_multiplier)
|
||||
if getattr(self, 'show_diagnostics', False):
|
||||
self.output_func(f"[Diagnostics] Misc Step pool size multiplier: {pool_multiplier:.2f}x (base={getattr(bc, 'MISC_LAND_TOP_POOL_SIZE', 60)} → effective={top_n})")
|
||||
effective_n = 999999 if use_full else top_n
|
||||
top_candidates = bu.select_top_land_candidates(df, already, basics, effective_n)
|
||||
# Dynamic EDHREC keep percent
|
||||
|
|
|
|||
|
|
@ -730,6 +730,18 @@ def build_catalog(limit: int, verbose: bool) -> Dict[str, Any]:
|
|||
merged = [s for s in merged if s not in special_noise]
|
||||
# If theme is one of the special ones, keep the other if present (no action needed beyond above filter logic).
|
||||
|
||||
# Land type theme filtering: Gates/Caves/Spheres are land types, not artifact/token mechanics.
|
||||
# Rationale: These themes tag specific land cards, creating spurious correlations with artifact/token
|
||||
# themes when those cards happen to also produce artifacts/tokens (e.g., Tireless Tracker in Gates decks).
|
||||
# Filter out artifact/token synergies that don't make thematic sense for land-type-matters strategies.
|
||||
land_type_themes = {"Gates Matter"}
|
||||
incompatible_with_land_types = {
|
||||
"Investigate", "Clue Token", "Detective Kindred"
|
||||
}
|
||||
if theme in land_type_themes:
|
||||
merged = [s for s in merged if s not in incompatible_with_land_types]
|
||||
# For non-land-type themes, don't filter (they can legitimately synergize with these)
|
||||
|
||||
if synergy_cap > 0 and len(merged) > synergy_cap:
|
||||
ce_len = len(curated_list) + len([s for s in enforced_list if s not in curated_list])
|
||||
if ce_len < synergy_cap:
|
||||
|
|
|
|||
|
|
@ -417,6 +417,8 @@ def _tag_mechanical_themes(df: pd.DataFrame, color: str) -> None:
|
|||
print('\n====================\n')
|
||||
tag_for_bending(df, color)
|
||||
print('\n====================\n')
|
||||
tag_for_land_types(df, color)
|
||||
print('\n====================\n')
|
||||
tag_for_web_slinging(df, color)
|
||||
print('\n====================\n')
|
||||
tag_for_tokens(df, color)
|
||||
|
|
@ -4239,6 +4241,55 @@ def tag_for_web_slinging(df: pd.DataFrame, color: str) -> None:
|
|||
logger.error(f'Error tagging Web-Slinging keywords: {str(e)}')
|
||||
raise
|
||||
|
||||
### Tag for land types
|
||||
def tag_for_land_types(df: pd.DataFrame, color: str) -> None:
|
||||
"""Tag card for specific non-basic land types.
|
||||
|
||||
Looks for 'Cave', 'Desert', 'Gate', 'Lair', 'Locus', 'Sphere', 'Urza's' in rules text and applies tags accordingly.
|
||||
"""
|
||||
try:
|
||||
cave_mask = (
|
||||
(tag_utils.create_text_mask(df, 'Cave') & ~tag_utils.create_text_mask(df, 'scavenge')) |
|
||||
tag_utils.create_type_mask(df, 'Cave')
|
||||
)
|
||||
desert_mask = (
|
||||
tag_utils.create_text_mask(df, 'Desert') |
|
||||
tag_utils.create_type_mask(df, 'Desert')
|
||||
)
|
||||
gate_mask = (
|
||||
(
|
||||
tag_utils.create_text_mask(df, 'Gate') &
|
||||
~tag_utils.create_text_mask(df, 'Agate') &
|
||||
~tag_utils.create_text_mask(df, 'Legate') &
|
||||
~tag_utils.create_text_mask(df, 'Throw widethe Gates') &
|
||||
~tag_utils.create_text_mask(df, 'Eternity Gate') &
|
||||
~tag_utils.create_text_mask(df, 'Investigates')
|
||||
) |
|
||||
tag_utils.create_text_mask(df, 'Gate card') |
|
||||
tag_utils.create_type_mask(df, 'Gate')
|
||||
)
|
||||
lair_mask = (tag_utils.create_type_mask(df, 'Lair'))
|
||||
locus_mask = (tag_utils.create_type_mask(df, 'Locus'))
|
||||
sphere_mask = (
|
||||
(tag_utils.create_text_mask(df, 'Sphere') & ~tag_utils.create_text_mask(df, 'Detention Sphere')) |
|
||||
tag_utils.create_type_mask(df, 'Sphere'))
|
||||
urzas_mask = (tag_utils.create_type_mask(df, "Urza's"))
|
||||
rules = [
|
||||
{'mask': cave_mask, 'tags': ['Caves Matter', 'Lands Matter']},
|
||||
{'mask': desert_mask, 'tags': ['Deserts Matter', 'Lands Matter']},
|
||||
{'mask': gate_mask, 'tags': ['Gates Matter', 'Lands Matter']},
|
||||
{'mask': lair_mask, 'tags': ['Lairs Matter', 'Lands Matter']},
|
||||
{'mask': locus_mask, 'tags': ['Locus Matter', 'Lands Matter']},
|
||||
{'mask': sphere_mask, 'tags': ['Spheres Matter', 'Lands Matter']},
|
||||
{'mask': urzas_mask, 'tags': ["Urza's Lands Matter", 'Lands Matter']},
|
||||
]
|
||||
|
||||
tag_utils.tag_with_rules_and_logging(df, rules, 'non-basic land types', color=color, logger=logger)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f'Error tagging non-basic land types: {str(e)}')
|
||||
raise
|
||||
|
||||
## Big Mana
|
||||
def create_big_mana_cost_mask(df: pd.DataFrame) -> pd.Series:
|
||||
"""Create a boolean mask for cards with high mana costs or X costs.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue