mirror of
https://github.com/mwisnowski/mtg_python_deckbuilder.git
synced 2025-09-22 04:50:46 +02:00
Adjusted some logic in setup to filter out any banned cards, as well as add the layout column to allow for easily seeing 'Normal', 'MDFC', or 'Transform cards.
Added logic for 'Kindred Support' tagging in tagger
This commit is contained in:
parent
c81a5fb64e
commit
f9ae7fa41e
3 changed files with 111 additions and 111 deletions
29
main.py
29
main.py
|
@ -1,10 +1,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
#import os
|
||||
import inquirer.prompt # type: ignore
|
||||
#import pandas as pd # type: ignore
|
||||
#import requests # type: ignore
|
||||
#import scrython # type: ignore
|
||||
import sys
|
||||
|
||||
from pathlib import Path
|
||||
|
@ -24,20 +20,28 @@ while True:
|
|||
choices=['Setup', 'Build a Deck', 'Get Card Info', 'Quit'],
|
||||
carousel=True)
|
||||
]
|
||||
try:
|
||||
answer = inquirer.prompt(question)
|
||||
if answer is None:
|
||||
print("Operation cancelled. Returning to menu...")
|
||||
choice = 'Menu'
|
||||
continue
|
||||
choice = answer['menu']
|
||||
except (KeyError, TypeError):
|
||||
print("Invalid input. Please try again.")
|
||||
choice = 'Menu'
|
||||
|
||||
# Run through initial setup
|
||||
while choice == 'Setup':
|
||||
setup.setup()
|
||||
choice = 'Menu'
|
||||
break
|
||||
|
||||
|
||||
# Make a new deck
|
||||
while choice == 'Build a Deck':
|
||||
print('Deck building not yet implemented')
|
||||
choice = 'Menu'
|
||||
break
|
||||
|
||||
|
||||
# Get a cards info
|
||||
while choice == 'Get Card Info':
|
||||
|
@ -47,15 +51,20 @@ while True:
|
|||
message='Would you like to look up another card?'
|
||||
)
|
||||
]
|
||||
try:
|
||||
answer = inquirer.prompt(question)
|
||||
if answer is None:
|
||||
print("Operation cancelled. Returning to menu...")
|
||||
choice = 'Menu'
|
||||
continue
|
||||
new_card = answer['continue']
|
||||
if new_card:
|
||||
choice == 'Get Card Info'
|
||||
else:
|
||||
choice = 'Get Card Info' # Fixed == to = for assignment
|
||||
except (KeyError, TypeError):
|
||||
print("Invalid input. Returning to menu...")
|
||||
choice = 'Menu'
|
||||
break
|
||||
|
||||
# Quit
|
||||
while choice == 'Quit':
|
||||
sys.exit()
|
||||
break
|
||||
|
57
setup.py
57
setup.py
|
@ -37,12 +37,15 @@ def filter_by_color(df, column_name, value, new_csv_name):
|
|||
filtered_df = filtered_df.loc[filtered_df['securityStamp'] != 'heart']
|
||||
filtered_df = filtered_df.loc[filtered_df['securityStamp'] != 'acorn']
|
||||
|
||||
for card in banned_cards:
|
||||
filtered_df = filtered_df[~filtered_df['name'].str.contains(card)]
|
||||
|
||||
card_types = ['Plane —', 'Conspiracy', 'Vanguard', 'Scheme', 'Phenomenon', 'Stickers', 'Attraction', 'Hero', 'Contraption']
|
||||
for card_type in card_types:
|
||||
filtered_df = filtered_df[~filtered_df['type'].str.contains(card_type)]
|
||||
filtered_df['faceName'] = filtered_df['faceName'].fillna(filtered_df['name'])
|
||||
filtered_df.drop_duplicates(subset='faceName', keep='first', inplace=True)
|
||||
columns_to_keep = ['name', 'faceName','edhrecRank','colorIdentity', 'colors', 'manaCost', 'manaValue', 'type', 'text', 'power', 'toughness', 'keywords']
|
||||
columns_to_keep = ['name', 'faceName','edhrecRank','colorIdentity', 'colors', 'manaCost', 'manaValue', 'type', 'layout', 'text', 'power', 'toughness', 'keywords']
|
||||
filtered_df = filtered_df[columns_to_keep]
|
||||
filtered_df.sort_values(by='name', key=lambda col: col.str.lower(), inplace=True)
|
||||
|
||||
|
@ -93,12 +96,15 @@ def set_lands():
|
|||
filtered_df = filtered_df.loc[filtered_df['securityStamp'] != 'heart']
|
||||
filtered_df = filtered_df.loc[filtered_df['securityStamp'] != 'acorn']
|
||||
|
||||
card_types = ['Plane —', 'Conspiracy', 'Vanguard', 'Scheme', 'Phenomenon', 'Stickers', 'Attraction', 'Hero']
|
||||
for card in banned_cards:
|
||||
filtered_df = filtered_df[~filtered_df['name'].str.contains(card)]
|
||||
|
||||
card_types = ['Plane —', 'Conspiracy', 'Vanguard', 'Scheme', 'Phenomenon', 'Stickers', 'Attraction', 'Hero', 'Contraption']
|
||||
for card_type in card_types:
|
||||
filtered_df = filtered_df[~filtered_df['type'].str.contains(card_type)]
|
||||
filtered_df['faceName'] = filtered_df['faceName'].fillna(filtered_df['name'])
|
||||
filtered_df.drop_duplicates(subset='faceName', keep='first', inplace=True)
|
||||
columns_to_keep = ['name', 'faceName','edhrecRank','colorIdentity', 'colors', 'manaCost', 'manaValue', 'type', 'layout', 'text']
|
||||
columns_to_keep = ['name', 'faceName','edhrecRank','colorIdentity', 'colors', 'manaCost', 'manaValue', 'type', 'layout', 'text', 'power', 'toughness', 'keywords']
|
||||
filtered_df = filtered_df[columns_to_keep]
|
||||
filtered_df.sort_values(by='edhrecRank', inplace=True)
|
||||
filtered_df.to_csv(f'{csv_directory}/land_cards.csv', index=False)
|
||||
|
@ -156,12 +162,15 @@ def determine_commanders():
|
|||
filtered_df = filtered_df.loc[filtered_df['securityStamp'] != 'heart']
|
||||
filtered_df = filtered_df.loc[filtered_df['securityStamp'] != 'acorn']
|
||||
|
||||
card_types = ['Plane —', 'Conspiracy', 'Vanguard', 'Scheme', 'Phenomena', 'Stickers', 'Attraction']
|
||||
for card in banned_cards:
|
||||
filtered_df = filtered_df[~filtered_df['name'].str.contains(card)]
|
||||
|
||||
card_types = ['Plane —', 'Conspiracy', 'Vanguard', 'Scheme', 'Phenomenon', 'Stickers', 'Attraction', 'Hero', 'Contraption']
|
||||
for card_type in card_types:
|
||||
filtered_df = filtered_df[~filtered_df['type'].str.contains(card_type)]
|
||||
filtered_df['faceName'] = filtered_df['faceName'].fillna(filtered_df['name'])
|
||||
filtered_df.drop_duplicates(subset='faceName', keep='first', inplace=True)
|
||||
columns_to_keep = ['name', 'faceName','edhrecRank','colorIdentity', 'colors', 'manaCost', 'manaValue', 'type', 'keywords', 'text', 'power', 'toughness']
|
||||
columns_to_keep = ['name', 'faceName','edhrecRank','colorIdentity', 'colors', 'manaCost', 'manaValue', 'type', 'layout', 'text', 'power', 'toughness', 'keywords']
|
||||
filtered_df = filtered_df[columns_to_keep]
|
||||
filtered_df.sort_values(by='name', key=lambda col: col.str.lower(), inplace=True)
|
||||
filtered_df.to_csv(f'{csv_directory}/commander_cards.csv', index=False)
|
||||
|
@ -192,7 +201,7 @@ def initial_setup():
|
|||
print('Checking for color identity sorted files.\n')
|
||||
|
||||
# For loop to iterate through the colors
|
||||
for i in range(len(colors), len(color_abrv)):
|
||||
for i in range(min(len(colors), len(color_abrv))):
|
||||
print(f'Checking for {colors[i]}_cards.csv.')
|
||||
try:
|
||||
with open(f'{csv_directory}/{colors[i]}_cards.csv', 'r', encoding='utf-8'):
|
||||
|
@ -282,40 +291,6 @@ def regenerate_csv_by_color(color):
|
|||
# Lastly, create a file with all lands, or cards that have a land on at least one face
|
||||
set_lands()
|
||||
|
||||
def generate_staple_lists():
|
||||
for color in colors:
|
||||
staples = []
|
||||
print(f'Checking for {color} staples file.')
|
||||
try:
|
||||
with open(f'staples/{color}.txt', 'r') as file:
|
||||
staples = file.read().split('\n')
|
||||
del staples[-1]
|
||||
print(f'{color.capitalize()} staples:')
|
||||
print('\n'.join(staples), '\n')
|
||||
|
||||
except FileNotFoundError:
|
||||
print(f'{color.capitalize()} staples file not found.')
|
||||
print(f'Generating {color} staples list.')
|
||||
df = pd.read_csv(f'{csv_directory}/{color}_cards.csv')
|
||||
df['edhrecRank'] = pd.to_numeric(df['edhrecRank'], downcast='integer', errors='coerce')
|
||||
df = df.dropna(subset=['edhrecRank'])
|
||||
df['edhrecRank'] = df['edhrecRank'].astype(int)
|
||||
columns_to_keep = ['name', 'edhrecRank', 'type']
|
||||
df = df[columns_to_keep]
|
||||
df.sort_values(by='edhrecRank', key=lambda col: col, inplace=True)
|
||||
i = 1
|
||||
y = 0
|
||||
while len(staples) < 20 and y < len(df):
|
||||
for index, row in df.iterrows():
|
||||
if row['edhrecRank'] == i:
|
||||
if 'Land' not in row['type'] and row['name'] not in banned_cards:
|
||||
staples.append(row['name'])
|
||||
i += 1
|
||||
y += 1
|
||||
with open(f'staples/{color}.txt', 'w') as f:
|
||||
for items in staples:
|
||||
f.write('%s\n' %items)
|
||||
|
||||
def add_tags():
|
||||
pass
|
||||
|
||||
|
@ -349,7 +324,7 @@ def setup():
|
|||
break
|
||||
break
|
||||
|
||||
#regenerate_csvs_all()
|
||||
regenerate_csvs_all()
|
||||
#regenerate_csv_by_color('white')
|
||||
#determine_commanders()
|
||||
#set_lands()
|
94
tagger.py
94
tagger.py
|
@ -1,5 +1,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import pandas as pd # type: ignore
|
||||
|
||||
import settings
|
||||
|
@ -8,45 +9,46 @@ from settings import artifact_tokens, csv_directory, colors, counter_types, ench
|
|||
from setup import regenerate_csv_by_color
|
||||
from utility import pluralize, sort_list
|
||||
|
||||
karnstruct = '0/0 colorless Construct'
|
||||
|
||||
### Setup
|
||||
## Load the dataframe
|
||||
def load_dataframe(color):
|
||||
# Setup an output file for card processing
|
||||
"""f = open(f'tag_output/{color}_tagging.txt', 'w+')
|
||||
f.write(f'Begin tagging {color}_cards.csv.\n')
|
||||
f.close()"""
|
||||
|
||||
# Iterate through the defined {color}_cards.csv file to find spells matter cards
|
||||
print(f'Loading {color}_cards.csv as a pandas dataframe.\n')
|
||||
# Setup dataframe
|
||||
while True:
|
||||
"""Load and validate the card dataframe for a given color"""
|
||||
try:
|
||||
with open(f'{csv_directory}/{color}_cards.csv', 'r', encoding='utf-8') as f:
|
||||
print(f'{color}_cards.csv found.')
|
||||
f.close()
|
||||
break
|
||||
except FileNotFoundError:
|
||||
filepath = f'{csv_directory}/{color}_cards.csv'
|
||||
|
||||
# Check if file exists, regenerate if needed
|
||||
if not os.path.exists(filepath):
|
||||
print(f'{color}_cards.csv not found, regenerating it.')
|
||||
regenerate_csv_by_color(color)
|
||||
check_df = pd.read_csv(f'{csv_directory}/{color}_cards.csv')
|
||||
column_checks = ['creatureTypes', 'themeTags']
|
||||
if 'themeTags' not in check_df.columns or 'creatureTypes' not in check_df.columns:
|
||||
for column in column_checks:
|
||||
if column in check_df.columns:
|
||||
print(f'"{column}" column in {color}_cards.csv.')
|
||||
elif column not in check_df.columns:
|
||||
print(f'"{column}" column not found in {color}_cards.csv.\n')
|
||||
if column == 'creatureTypes':
|
||||
kindred_tagging(check_df, color)
|
||||
if column == 'themeTags':
|
||||
create_theme_tags(check_df, color)
|
||||
if 'themeTags' in check_df.columns and 'creatureTypes' in check_df.columns:
|
||||
df = pd.read_csv(f'{csv_directory}/{color}_cards.csv', converters={'themeTags': pd.eval, 'creatureTypes': pd.eval})
|
||||
|
||||
# Load initial dataframe for validation
|
||||
check_df = pd.read_csv(filepath)
|
||||
|
||||
# Validate required columns
|
||||
required_columns = ['creatureTypes', 'themeTags']
|
||||
missing_columns = [col for col in required_columns if col not in check_df.columns]
|
||||
|
||||
# Handle missing columns
|
||||
if missing_columns:
|
||||
print(f"Missing columns: {missing_columns}")
|
||||
if 'creatureTypes' not in check_df.columns:
|
||||
kindred_tagging(check_df, color)
|
||||
if 'themeTags' not in check_df.columns:
|
||||
create_theme_tags(check_df, color)
|
||||
|
||||
# Load final dataframe with proper converters
|
||||
df = pd.read_csv(filepath, converters={'themeTags': pd.eval, 'creatureTypes': pd.eval})
|
||||
|
||||
# Process the dataframe
|
||||
tag_by_color(df, color)
|
||||
|
||||
except FileNotFoundError as e:
|
||||
print(f'Error: {e}')
|
||||
except pd.errors.ParserError:
|
||||
print('Error parsing the CSV file.')
|
||||
except Exception as e:
|
||||
print(f'An unexpected error occurred: {e}')
|
||||
|
||||
## Tag cards on a color-by-color basis
|
||||
def tag_by_color(df, color):
|
||||
|
||||
|
@ -130,6 +132,7 @@ def kindred_tagging(df, color):
|
|||
df.at[index, 'creatureTypes'] = kindred_tags
|
||||
print(f'Creature types set in {color}_cards.csv.\n')
|
||||
print('==========\n')
|
||||
|
||||
# Set outlaws
|
||||
print(f'Checking for and setting Outlaw types in {color}_cards.csv')
|
||||
outlaws = ['Assassin', 'Mercenary', 'Pirate', 'Rogue', 'Warlock']
|
||||
|
@ -144,19 +147,17 @@ def kindred_tagging(df, color):
|
|||
df.at[index, 'creatureTypes'] = kindred_tags
|
||||
print(f'Outlaw types set in {color}_cards.csv.\n')
|
||||
print('==========\n')
|
||||
|
||||
# Check for creature types in text (i.e. how 'Voja, Jaws of the Conclave' cares about Elves)
|
||||
print(f'Checking for and setting creature types found in the text of cards in {color}_cards.csv')
|
||||
|
||||
for index, row in df.iterrows():
|
||||
kindred_tags = row['creatureTypes']
|
||||
if pd.isna(row['text']):
|
||||
continue
|
||||
split_text = row['text'].split()
|
||||
ignore_list = ['Elite Inquisitor', 'Breaker of Armies', 'Cleopatra, Exiled Pharaoh', 'Nath\'s Buffoon']
|
||||
for creature_type in settings.creature_types:
|
||||
if ('Elite Inquisitor' in row['name']
|
||||
or 'Breaker of Armies' in row['name']
|
||||
or 'Cleopatra, Exiled Pharaoh' in row['name']
|
||||
or 'Nath\'s Buffoon' in row['name']):
|
||||
if row['name'] in ignore_list:
|
||||
continue
|
||||
if creature_type in row['name']:
|
||||
continue
|
||||
|
@ -167,8 +168,6 @@ def kindred_tagging(df, color):
|
|||
if creature_type not in row['name']:
|
||||
if creature_type not in kindred_tags:
|
||||
kindred_tags.append(creature_type)
|
||||
if creature_type in outlaws:
|
||||
kindred_tags.append(creature_type)
|
||||
df.at[index, 'creatureTypes'] = kindred_tags
|
||||
|
||||
# Tag for pluralized types (i.e. Elves, Wolves, etc...) in textbox
|
||||
|
@ -176,10 +175,9 @@ def kindred_tagging(df, color):
|
|||
if pluralize(f'{creature_type}') not in row['name']:
|
||||
if creature_type not in kindred_tags:
|
||||
kindred_tags.append(creature_type)
|
||||
if creature_type in outlaws:
|
||||
kindred_tags.append(creature_type)
|
||||
df.at[index, 'creatureTypes'] = kindred_tags
|
||||
print(f'Creature types from text set in {color}_cards.csv.\n')
|
||||
|
||||
# Overwrite file with creature type tags
|
||||
columns_to_keep = ['name', 'faceName','edhrecRank', 'colorIdentity', 'colors', 'manaCost', 'manaValue', 'type', 'creatureTypes', 'text', 'power', 'toughness', 'keywords']
|
||||
df = df[columns_to_keep]
|
||||
|
@ -256,6 +254,24 @@ def add_creatures_to_tags(df, color):
|
|||
|
||||
# Overwrite file with kindred tags added
|
||||
print(f'Creature types added to theme tags in {color}_cards.csv.\n')
|
||||
print('==========\n')
|
||||
|
||||
# Set Kindred Support
|
||||
print(f'Checking for and setting Kindred Support tag in {color}_cards.csv')
|
||||
all_kindred = ['changeling', 'choose a creature type', 'shares a creature type',
|
||||
'shares at least one creature type', 'you control of the chosen type']
|
||||
|
||||
for index, row in df.iterrows():
|
||||
if pd.isna(row['text']):
|
||||
continue
|
||||
theme_tags = row['themeTags']
|
||||
#if all_kindred in row['text'].lower():
|
||||
for item in all_kindred:
|
||||
if item in row['text'].lower():
|
||||
if 'Kindred Support' not in theme_tags:
|
||||
theme_tags.extend(['Kindred Support'])
|
||||
df.at[index, 'themeTags'] = theme_tags
|
||||
print(f'"Kindred Support" tag set in {color}_cards.csv.\n')
|
||||
|
||||
## Add keywords to theme tags
|
||||
def tag_for_keywords(df, color):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue