mirror of
https://github.com/mwisnowski/mtg_python_deckbuilder.git
synced 2025-09-22 04:50:46 +02:00
Refined land add logic
This commit is contained in:
parent
15ce426ad4
commit
af0ee0e0b6
3 changed files with 540 additions and 181 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,4 +1,6 @@
|
|||
*.csv
|
||||
*.txt
|
||||
*.json
|
||||
test.py
|
||||
.mypy_cache/
|
||||
__pycache__/
|
709
deck_builder.py
709
deck_builder.py
|
@ -11,21 +11,24 @@ from fuzzywuzzy import fuzz, process # type: ignore
|
|||
from settings import csv_directory
|
||||
from setup import determine_commanders, set_lands
|
||||
|
||||
print('Would you like to leverage Scrython for pricing information?')
|
||||
question = [
|
||||
inquirer.Confirm(
|
||||
'scrython',
|
||||
)
|
||||
]
|
||||
answer = inquirer.prompt(question)
|
||||
choice = answer['scrython']
|
||||
if choice:
|
||||
use_scrython = True
|
||||
import scrython # type:ignore
|
||||
else:
|
||||
use_scrython = False
|
||||
|
||||
pd.set_option('display.max_columns', None)
|
||||
pd.set_option('display.max_rows', None)
|
||||
pd.set_option('display.max_colwidth', 20)
|
||||
|
||||
"""def pluralize_list(singular_list):
|
||||
engine = inflect.engine()
|
||||
plural_list = [engine.plural(creature_type) for creature_type in singular_list]
|
||||
return plural_list
|
||||
|
||||
singular_words = settings.creature_types
|
||||
plural_words = pluralize_list(singular_words)
|
||||
creature_type_list = settings.creature_types + plural_words"""
|
||||
#print(plural_words)
|
||||
|
||||
# Basic deck builder, initial plan will just be for kindred support.
|
||||
# Would like to add logic for other themes, as well as automatically go
|
||||
# through the commander and find suitable themes.
|
||||
|
@ -93,7 +96,14 @@ class DeckBuilder:
|
|||
|
||||
# Battles
|
||||
self.battle_cards = []
|
||||
|
||||
|
||||
def price_check(self, card_name):
|
||||
card = scrython.cards.Named(fuzzy=f'{card_name}')
|
||||
card_price = card.prices('usd')
|
||||
#if card_price is None:
|
||||
# card_price = 0.0
|
||||
return card_price
|
||||
|
||||
def determine_commander(self):
|
||||
# Setup dataframe
|
||||
try:
|
||||
|
@ -199,7 +209,6 @@ class DeckBuilder:
|
|||
|
||||
# Set color identity
|
||||
self.color_identity = df.at[0, 'colorIdentity']
|
||||
print(self.color_identity)
|
||||
self.color_identity_full = ''
|
||||
self.determine_color_identity()
|
||||
|
||||
|
@ -400,11 +409,11 @@ class DeckBuilder:
|
|||
def determine_themes(self):
|
||||
themes = self.commander_tags
|
||||
print('Your commander deck will likely have a number of viable themes, but you\'ll want to narrow it down for focus.\n'
|
||||
'This will go through the process of choosing up to three themes for the deck.')
|
||||
'This will go through the process of choosing up to three themes for the deck.\n')
|
||||
while True:
|
||||
# Choose a primary theme
|
||||
print('Choose a primary theme for your commander deck.\n'
|
||||
'This will be the "focus" of the deck, in a kindred deck this will typically be a creature type for example.\n')
|
||||
'This will be the "focus" of the deck, in a kindred deck this will typically be a creature type for example.')
|
||||
question = [
|
||||
inquirer.List('theme',
|
||||
choices=themes,
|
||||
|
@ -432,7 +441,7 @@ class DeckBuilder:
|
|||
choice = answer['theme']
|
||||
while True:
|
||||
if choice == 'Stop Here':
|
||||
print('You\'ve only selected one theme, are you sure you want to stop?')
|
||||
print('You\'ve only selected one theme, are you sure you want to stop?\n')
|
||||
confirm_themes = [
|
||||
inquirer.Confirm(
|
||||
'done',
|
||||
|
@ -458,7 +467,7 @@ class DeckBuilder:
|
|||
|
||||
while not tertiary_theme_chosen:
|
||||
# Tertiary theme
|
||||
print('Choose a secondary theme for your commander deck.\n'
|
||||
print('Choose a tertiary theme for your commander deck.\n'
|
||||
'This will typically be a tertiary focus, or just something else to do that your commander is good at.')
|
||||
question = [
|
||||
inquirer.List('theme',
|
||||
|
@ -469,7 +478,7 @@ class DeckBuilder:
|
|||
choice = answer['theme']
|
||||
while True:
|
||||
if choice == 'Stop Here':
|
||||
print('You\'ve only selected two themes, are you sure you want to stop?')
|
||||
print('You\'ve only selected two themes, are you sure you want to stop?\n')
|
||||
confirm_themes = [
|
||||
inquirer.Confirm(
|
||||
'done',
|
||||
|
@ -495,6 +504,67 @@ class DeckBuilder:
|
|||
# "Free" slots that can be used for anything that isn't the ideals
|
||||
self.free_slots = 99
|
||||
|
||||
if use_scrython:
|
||||
print('Would you like to set an intended max price of the deck?\n'
|
||||
'There will be some leeway of ~10%, with a couple alternative options provided.')
|
||||
question = [
|
||||
inquirer.Confirm(
|
||||
'scrython',
|
||||
)
|
||||
]
|
||||
answer = inquirer.prompt(question)
|
||||
choice = answer['scrython']
|
||||
if choice:
|
||||
self.set_max_deck_price = True
|
||||
print('What would you like the max price to be?')
|
||||
question = [
|
||||
inquirer.Text(
|
||||
'max_price',
|
||||
default='400'
|
||||
)
|
||||
]
|
||||
answer = inquirer.prompt(question)
|
||||
self.max_deck_price = float(answer['max_price'])
|
||||
else:
|
||||
self.set_max_deck_price = False
|
||||
|
||||
print('Would you like to set a max price per card?\n'
|
||||
'There will be some leeway of ~10% when choosing cards and you can choose to keep it or not.')
|
||||
question = [
|
||||
inquirer.Confirm(
|
||||
'scrython',
|
||||
)
|
||||
]
|
||||
answer = inquirer.prompt(question)
|
||||
choice = answer['scrython']
|
||||
if choice:
|
||||
self.set_max_card_price = True
|
||||
print('What would you like the max price to be?')
|
||||
question = [
|
||||
inquirer.Text(
|
||||
'max_price',
|
||||
default='20'
|
||||
)
|
||||
]
|
||||
answer = inquirer.prompt(question)
|
||||
self.max_card_price = float(answer['max_price'])
|
||||
else:
|
||||
self.set_max_card_price = False
|
||||
|
||||
# Determine ramp
|
||||
print('How many pieces of ramp would you like to include?\n'
|
||||
'You\'re gonna want a decent amount of ramp, both getting lands or mana rocks/dorks.\n'
|
||||
'A good baseline is 8-12, scaling up with average CMC.')
|
||||
question = [
|
||||
inquirer.Text(
|
||||
'ramp_prompt',
|
||||
default='8'
|
||||
)
|
||||
]
|
||||
answer = inquirer.prompt(question)
|
||||
self.ideal_ramp = int(answer['ramp_prompt'])
|
||||
self.free_slots -= self.ideal_ramp
|
||||
|
||||
# Determine ideal land count
|
||||
print('How many lands would you like to include?\n'
|
||||
'Before ramp is taken into account, 38-40 would be "normal" for a deck. I personally use 35.\n'
|
||||
|
@ -568,20 +638,6 @@ class DeckBuilder:
|
|||
self.ideal_card_advantage = int(answer['draw_prompt'])
|
||||
self.free_slots -= self.ideal_card_advantage
|
||||
|
||||
# Determine ramp
|
||||
print('How many pieces of ramp would you like to include?\n'
|
||||
'You\'re gonna want a decent amount of ramp, both getting lands or mana rocks/dorks.\n'
|
||||
'A good baseline is 8-12, scaling up with average CMC.')
|
||||
question = [
|
||||
inquirer.Text(
|
||||
'ramp_prompt',
|
||||
default='8'
|
||||
)
|
||||
]
|
||||
answer = inquirer.prompt(question)
|
||||
self.ideal_ramp = int(answer['ramp_prompt'])
|
||||
self.free_slots -= self.ideal_ramp
|
||||
|
||||
# Determine how many protection spells
|
||||
print('How protection spells would you like to include?\n'
|
||||
'This can be individual protection, board protection, fogs, or similar effects.\n'
|
||||
|
@ -626,10 +682,24 @@ class DeckBuilder:
|
|||
|
||||
if len(self.colors) >= 2:
|
||||
self.add_dual_lands()
|
||||
keyboard.wait('space')
|
||||
|
||||
if len(self.colors) >= 3:
|
||||
pass
|
||||
|
||||
# Determine minimum basics to have
|
||||
print('How many basic lands would you like to have at minimum?\n'
|
||||
'This can vary widely depending on your commander, colors in color identity, and what you want to do.\n'
|
||||
'Some decks may be fine with as low as 10, others may want 25.')
|
||||
question = [
|
||||
inquirer.Text(
|
||||
'num_basics',
|
||||
default='20'
|
||||
)
|
||||
]
|
||||
answer = inquirer.prompt(question)
|
||||
self.ideal_protection = int(answer['protection_prompt'])
|
||||
|
||||
self.add_misc_lands()
|
||||
|
||||
rows_to_drop = []
|
||||
|
@ -662,49 +732,80 @@ class DeckBuilder:
|
|||
|
||||
def add_basics(self):
|
||||
self.land_count = 0
|
||||
print(f'Adding {self.ideal_land_count - 5} basic lands.')
|
||||
base_basics = self.ideal_land_count - 5 # Reserve 5 slots for utility lands
|
||||
basics_per_color = base_basics // len(self.colors)
|
||||
remaining_basics = base_basics % len(self.colors)
|
||||
|
||||
color_to_basic = {
|
||||
'W': 'Plains',
|
||||
'U': 'Island',
|
||||
'B': 'Swamp',
|
||||
'R': 'Mountain',
|
||||
'G': 'Forest'
|
||||
}
|
||||
|
||||
if 'Snow' in self.commander_tags:
|
||||
color_to_basic = {
|
||||
'W': 'Snow-Covered Plains',
|
||||
'U': 'Snow-Covered Island',
|
||||
'B': 'Snow-Covered Swamp',
|
||||
'R': 'Snow-Covered Mountain',
|
||||
'G': 'Snow-Covered Forest'
|
||||
}
|
||||
|
||||
print(f'Adding {base_basics} basic lands distributed across {len(self.colors)} colors')
|
||||
|
||||
# Add equal distribution first
|
||||
for color in self.colors:
|
||||
if color == 'W':
|
||||
basic = 'Plains'
|
||||
elif color == 'U':
|
||||
basic = 'Island'
|
||||
elif color == 'B':
|
||||
basic = 'Swamp',
|
||||
elif color == 'R':
|
||||
basic = 'Mountain'
|
||||
elif color == 'G':
|
||||
basic = 'Forest'
|
||||
"""if color =='':
|
||||
basic = 'Wastes'"""
|
||||
num_basics = self.ideal_land_count - 5
|
||||
for _ in range(num_basics // len(self.colors)):
|
||||
self.land_cards.append(basic)
|
||||
self.land_count += 1
|
||||
|
||||
basic = color_to_basic.get(color)
|
||||
if basic:
|
||||
for _ in range(basics_per_color):
|
||||
self.land_cards.append(basic)
|
||||
self.land_count += 1
|
||||
|
||||
# Distribute remaining basics based on color requirements
|
||||
if remaining_basics > 0:
|
||||
for color in self.colors[:remaining_basics]:
|
||||
basic = color_to_basic.get(color)
|
||||
if basic:
|
||||
self.land_cards.append(basic)
|
||||
self.land_count += 1
|
||||
|
||||
def add_standard_non_basics(self):
|
||||
# Add lands that are good in most any commander deck
|
||||
print('Adding "standard" non-basics')
|
||||
lands_to_remove = []
|
||||
self.land_cards.append('Reliquary Tower')
|
||||
lands_to_remove.append('Reliquary Tower')
|
||||
self.land_count += 1
|
||||
if 'Landfall' not in self.commander_tags:
|
||||
self.land_cards.append('Ash Barrens')
|
||||
lands_to_remove.append('Ash Barrens')
|
||||
self.land_count += 1
|
||||
if len(self.colors) > 1:
|
||||
# Adding command Tower
|
||||
self.land_cards.append('Command Tower')
|
||||
lands_to_remove.append('Command Tower')
|
||||
self.land_count += 1
|
||||
|
||||
# Adding Exotic Orchard
|
||||
self.land_cards.append('Exotic Orchard')
|
||||
lands_to_remove.append('Exotic Orchard')
|
||||
self.land_count += 1
|
||||
|
||||
if len(self.colors) <= 2:
|
||||
self.land_cards.append('War Room')
|
||||
self.land_cards.append('War Room')
|
||||
self.land_count += 1
|
||||
if self.commander_power >= 5:
|
||||
self.land_cards.append('Rogue\'s Passage')
|
||||
lands_to_remove.append('Rogue\'s Passage')
|
||||
self.land_count += 1
|
||||
|
||||
for index, row in self.land_df.iterrows():
|
||||
if row['name'] in lands_to_remove:
|
||||
self.land_df = self.land_df.drop(index)
|
||||
|
||||
def add_fetches(self):
|
||||
# Determine how many fetches in total
|
||||
print('How many fetch lands would you like to include?\n'
|
||||
|
@ -722,85 +823,216 @@ class DeckBuilder:
|
|||
|
||||
generic_fetches = ['Evolving Wilds', 'Terramorphic Expanse', 'Shire Terrace', 'Escape Tunnel', 'Promising Vein','Myriad Landscape', 'Fabled Passage', 'Terminal Moraine']
|
||||
fetches = generic_fetches
|
||||
fetches_to_remove = generic_fetches
|
||||
|
||||
# Adding in life fetches
|
||||
print('Would you like to include the pricier fetch-lands (i.e. Prismatic Vista or the Onslaught/Zendikar fetches)?')
|
||||
question = [
|
||||
inquirer.Confirm(
|
||||
'yes',
|
||||
)
|
||||
]
|
||||
answer = inquirer.prompt(question)
|
||||
choice = answer['yes']
|
||||
if choice:
|
||||
# Adding in expensive fetches
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check('Prismatic Vista') is None:
|
||||
fetches_to_remove.append('Prismatic Vista')
|
||||
fetches.append('Prismatic Vista')
|
||||
else:
|
||||
fetches_to_remove.append('Prismatic Vista')
|
||||
fetches.append('Prismatic Vista')
|
||||
if 'W' in self.colors:
|
||||
white_fetches = ['Flooded Strand', 'Windswept Heath', 'Marsh Flats', 'Arid Mesa']
|
||||
for fetch in white_fetches:
|
||||
if fetch not in fetches:
|
||||
fetches.append(fetch)
|
||||
|
||||
if 'U' in self.colors:
|
||||
blue_fetches = ['Flooded Strand', 'Polluted Delta', 'Scalding Tarn', 'Misty Rainforest']
|
||||
for fetch in blue_fetches:
|
||||
if fetch not in fetches:
|
||||
fetches.append(fetch)
|
||||
|
||||
if 'B' in self.colors:
|
||||
black_fetches = ['Polluted Delta', 'Bloodstained Mire', 'Marsh Flats', 'Verdant Catacombs']
|
||||
for fetch in black_fetches:
|
||||
if fetch not in fetches:
|
||||
fetches.append(fetch)
|
||||
|
||||
if 'R' in self.colors:
|
||||
red_fetches = ['Bloodstained Mire', 'Wooded Foothills', 'Scalding Tarn', 'Arid Mesa']
|
||||
for fetch in red_fetches:
|
||||
# White Fetches
|
||||
if 'W' in self.colors:
|
||||
white_fetches = ['Flooded Strand', 'Windswept Heath', 'Marsh Flats', 'Arid Mesa']
|
||||
for fetch in white_fetches:
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(fetch) is None:
|
||||
fetches_to_remove.append(fetch)
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(fetch)) <= self.max_card_price:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
|
||||
if 'G' in self.colors:
|
||||
green_fetches = ['Wooded Foothills', 'Windswept Heath', 'Verdant Catacombs', 'Misty Rainforest']
|
||||
for fetch in green_fetches:
|
||||
|
||||
# Blue fetches
|
||||
if 'U' in self.colors:
|
||||
blue_fetches = ['Flooded Strand', 'Polluted Delta', 'Scalding Tarn', 'Misty Rainforest']
|
||||
for fetch in blue_fetches:
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(fetch) is None:
|
||||
fetches_to_remove.append(fetch)
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(fetch)) <= self.max_card_price:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
|
||||
# Black fetches
|
||||
if 'B' in self.colors:
|
||||
black_fetches = ['Polluted Delta', 'Bloodstained Mire', 'Marsh Flats', 'Verdant Catacombs']
|
||||
for fetch in black_fetches:
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(fetch) is None:
|
||||
fetches_to_remove.append(fetch)
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(fetch)) <= self.max_card_price:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
|
||||
# REd fetches
|
||||
if 'R' in self.colors:
|
||||
red_fetches = ['Bloodstained Mire', 'Wooded Foothills', 'Scalding Tarn', 'Arid Mesa']
|
||||
for fetch in red_fetches:
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(fetch) is None:
|
||||
fetches_to_remove.append(fetch)
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(fetch)) <= self.max_card_price:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
|
||||
# Green fetches
|
||||
if 'G' in self.colors:
|
||||
green_fetches = ['Wooded Foothills', 'Windswept Heath', 'Verdant Catacombs', 'Misty Rainforest']
|
||||
for fetch in green_fetches:
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(fetch) is None:
|
||||
fetches_to_remove.append(fetch)
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(fetch)) <= self.max_card_price:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
|
||||
# Adding in New Capenna Fetches
|
||||
print('Would you like to include the cheaper, New Capenna fetches?')
|
||||
question = [
|
||||
inquirer.Confirm(
|
||||
'yes',
|
||||
)
|
||||
]
|
||||
answer = inquirer.prompt(question)
|
||||
choice = answer['yes']
|
||||
if choice:
|
||||
if 'W' in self.colors:
|
||||
white_fetches = ['Brokers Hideout', 'Obscura Storefront', 'Cabaretti Courtyard']
|
||||
for fetch in white_fetches:
|
||||
# White New Capenna fetches
|
||||
if 'W' in self.colors:
|
||||
white_fetches = ['Brokers Hideout', 'Obscura Storefront', 'Cabaretti Courtyard']
|
||||
for fetch in white_fetches:
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(fetch) is None:
|
||||
fetches_to_remove.append(fetch)
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(fetch)) <= self.max_card_price:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
if 'U' in self.colors:
|
||||
blue_fetches = ['Brokers Hideout', 'Obscura Storefront', 'Maestros Theater']
|
||||
for fetch in blue_fetches:
|
||||
|
||||
# Blue New Capenna Fetches
|
||||
if 'U' in self.colors:
|
||||
blue_fetches = ['Brokers Hideout', 'Obscura Storefront', 'Maestros Theater']
|
||||
for fetch in blue_fetches:
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(fetch) is None:
|
||||
fetches_to_remove.append(fetch)
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(fetch)) <= self.max_card_price:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
|
||||
if 'B' in self.colors:
|
||||
black_fetches = ['Obscura Storefront', 'Maestros Theater', 'Riveteers Overlook']
|
||||
for fetch in black_fetches:
|
||||
|
||||
# Black New Capenna Fetches
|
||||
if 'B' in self.colors:
|
||||
black_fetches = ['Obscura Storefront', 'Maestros Theater', 'Riveteers Overlook']
|
||||
for fetch in black_fetches:
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(fetch) is None:
|
||||
fetches_to_remove.append(fetch)
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(fetch)) <= self.max_card_price:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
|
||||
if 'R' in self.colors:
|
||||
red_fetches = ['Maestros Theater', 'Riveteers Overlook', 'Cabaretti Courtyard']
|
||||
for fetch in red_fetches:
|
||||
|
||||
# Red New Capenna Fetches
|
||||
if 'R' in self.colors:
|
||||
red_fetches = ['Maestros Theater', 'Riveteers Overlook', 'Cabaretti Courtyard']
|
||||
for fetch in red_fetches:
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(fetch) is None:
|
||||
fetches_to_remove.append(fetch)
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(fetch)) <= self.max_card_price:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
|
||||
if 'G' in self.colors:
|
||||
green_fetches = ['Brokers Hideout', 'Riveteers Overlook', 'Cabaretti Courtyard']
|
||||
for fetch in green_fetches:
|
||||
|
||||
# Green New Capenna Fetches
|
||||
if 'G' in self.colors:
|
||||
green_fetches = ['Brokers Hideout', 'Riveteers Overlook', 'Cabaretti Courtyard']
|
||||
for fetch in green_fetches:
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(fetch) is None:
|
||||
fetches_to_remove.append(fetch)
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(fetch)) <= self.max_card_price:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
if fetch not in fetches:
|
||||
fetches_to_remove.append(fetch)
|
||||
fetches.append(fetch)
|
||||
|
||||
fetches_chosen = False
|
||||
|
@ -841,85 +1073,213 @@ class DeckBuilder:
|
|||
fetches_chosen = True
|
||||
break
|
||||
break
|
||||
|
||||
# Add fetches to deck
|
||||
for fetch in fetches_to_add:
|
||||
if fetch not in self.land_cards:
|
||||
self.land_cards.append(fetch)
|
||||
self.land_count += 1
|
||||
|
||||
# Remove Fetches from land_df
|
||||
for index, row in self.land_df.iterrows():
|
||||
if row['name'] in fetches_to_remove:
|
||||
self.land_df = self.land_df.drop(index)
|
||||
|
||||
def add_kindred_lands(self):
|
||||
print('Adding lands that care about the commander having a Kindred theme.')
|
||||
print('Adding general Kindred lands.')
|
||||
kindred_lands = ['Path of Ancestry']
|
||||
|
||||
print('Would you like to include the pricier Kindred lands (i.e. Cavern of Souls and Three Tree City)?')
|
||||
question = [
|
||||
inquirer.Confirm(
|
||||
'yes',
|
||||
)
|
||||
]
|
||||
answer = inquirer.prompt(question)
|
||||
choice = answer['yes']
|
||||
if choice:
|
||||
kindred_lands.extend(['Three Tree City', 'Cavern of Souls'])
|
||||
lands_to_remove = kindred_lands
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
for land in ['Three Tree City', 'Cavern of Souls']:
|
||||
if float(self.price_check(land)) <= self.max_card_price:
|
||||
kindred_lands.append(land)
|
||||
lands_to_remove.append(land)
|
||||
else:
|
||||
lands_to_remove.append(land)
|
||||
|
||||
for land in kindred_lands:
|
||||
if land not in self.land_cards:
|
||||
self.land_cards.append(land)
|
||||
self.land_count += 1
|
||||
|
||||
for index, row in self.land_df.iterrows():
|
||||
if row['name'] in lands_to_remove:
|
||||
self.land_df = self.land_df.drop(land)
|
||||
|
||||
def add_dual_lands(self):
|
||||
# Determine dual-color lands available
|
||||
dual_options = []
|
||||
if ('W' in self.colors and 'U' in self.colors):
|
||||
for index, row in self.land_df.iterrows():
|
||||
if 'Land — Plains Island' == row['type']:
|
||||
dual_options.append(row['name'])
|
||||
for index, row in self.land_df.iterrows():
|
||||
# Azorius Duals
|
||||
if ('W' in self.colors and 'U' in self.colors):
|
||||
if ('Land — Plains Island' == row['type']
|
||||
or 'Snow Land — Plains Island' == row['type']
|
||||
):
|
||||
self.land_df = self.land_df.drop(index)
|
||||
if ('W' in self.colors and 'B' in self.colors):
|
||||
for index, row in self.land_df.iterrows():
|
||||
if 'Land — Plains Swamp' == row['type']:
|
||||
dual_options.append(row['name'])
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(row['name']) is None:
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(row['name'])) <= self.max_card_price:
|
||||
dual_options.append(row['name'])
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
dual_options.append(row['name'])
|
||||
|
||||
# Orzohv Duals
|
||||
if ('W' in self.colors and 'B' in self.colors):
|
||||
if ('Land — Plains Swamp' == row['type']
|
||||
or 'Snow Land — Plains Swamp' == row['type']
|
||||
):
|
||||
self.land_df = self.land_df.drop(index)
|
||||
if ('U' in self.colors and 'B' in self.colors):
|
||||
for index, row in self.land_df.iterrows():
|
||||
if 'Land — Island Swamp' == row['type']:
|
||||
dual_options.append(row['name'])
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(row['name']) is None:
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(row['name'])) <= self.max_card_price:
|
||||
dual_options.append(row['name'])
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
dual_options.append(row['name'])
|
||||
|
||||
# Dimir Duals
|
||||
if ('U' in self.colors and 'B' in self.colors):
|
||||
if ('Land — Island Swamp' == row['type']
|
||||
or 'Snow Land — Island Swamp' == row['type']
|
||||
):
|
||||
self.land_df = self.land_df.drop(index)
|
||||
if ('G' in self.colors and 'B' in self.colors):
|
||||
for index, row in self.land_df.iterrows():
|
||||
if 'Land — Forest Swamp' == row['type']:
|
||||
dual_options.append(row['name'])
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(row['name']) is None:
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(row['name'])) <= self.max_card_price:
|
||||
dual_options.append(row['name'])
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
dual_options.append(row['name'])
|
||||
|
||||
# Golgari Duals
|
||||
if ('G' in self.colors and 'B' in self.colors):
|
||||
if ('Land — Forest Swamp' == row['type']
|
||||
or 'Snow Land — Forest Swamp' == row['type']
|
||||
):
|
||||
self.land_df = self.land_df.drop(index)
|
||||
if ('B' in self.colors and 'R' in self.colors):
|
||||
for index, row in self.land_df.iterrows():
|
||||
if 'Land — Swamp Mountain' == row['type']:
|
||||
dual_options.append(row['name'])
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(row['name']) is None:
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(row['name'])) <= self.max_card_price:
|
||||
dual_options.append(row['name'])
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
dual_options.append(row['name'])
|
||||
|
||||
# Rakdos Duals
|
||||
if ('B' in self.colors and 'R' in self.colors):
|
||||
if ('Land — Swamp Mountain' == row['type']
|
||||
or 'Snow Land — Swamp Mountain' == row['type']
|
||||
):
|
||||
self.land_df = self.land_df.drop(index)
|
||||
if ('G' in self.colors and 'U' in self.colors):
|
||||
for index, row in self.land_df.iterrows():
|
||||
if 'Land — Forest Island' == row['type']:
|
||||
dual_options.append(row['name'])
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(row['name']) is None:
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(row['name'])) <= self.max_card_price:
|
||||
dual_options.append(row['name'])
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
dual_options.append(row['name'])
|
||||
|
||||
# Simic Duals
|
||||
if ('G' in self.colors and 'U' in self.colors):
|
||||
if ('Land — Forest Island' == row['type']
|
||||
or 'Snow Land — Forest Island' == row['type']
|
||||
):
|
||||
self.land_df = self.land_df.drop(index)
|
||||
if ('R' in self.colors and 'G' in self.colors):
|
||||
for index, row in self.land_df.iterrows():
|
||||
if 'Land — Mountain Forest' == row['type']:
|
||||
dual_options.append(row['name'])
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(row['name']) is None:
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(row['name'])) <= self.max_card_price:
|
||||
dual_options.append(row['name'])
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
dual_options.append(row['name'])
|
||||
|
||||
# Gruul Duals
|
||||
if ('R' in self.colors and 'G' in self.colors):
|
||||
if ('Land — Mountain Forest' == row['type']
|
||||
or 'Snow Land — Mountain Forest' == row['type']
|
||||
):
|
||||
self.land_df = self.land_df.drop(index)
|
||||
if ('U' in self.colors and 'R' in self.colors):
|
||||
for index, row in self.land_df.iterrows():
|
||||
if 'Land — Island Mountain' == row['type']:
|
||||
dual_options.append(row['name'])
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(row['name']) is None:
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(row['name'])) <= self.max_card_price:
|
||||
dual_options.append(row['name'])
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
dual_options.append(row['name'])
|
||||
|
||||
# Izzet Duals
|
||||
if ('U' in self.colors and 'R' in self.colors):
|
||||
if ('Land — Island Mountain' == row['type']
|
||||
or 'Snow Land — Island Mountain' == row['type']
|
||||
):
|
||||
self.land_df = self.land_df.drop(index)
|
||||
if ('G' in self.colors and 'W' in self.colors):
|
||||
for index, row in self.land_df.iterrows():
|
||||
if 'Land — Forest Plains' == row['type']:
|
||||
dual_options.append(row['name'])
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(row['name']) is None:
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(row['name'])) <= self.max_card_price:
|
||||
dual_options.append(row['name'])
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
dual_options.append(row['name'])
|
||||
|
||||
# Selesnya Duals
|
||||
if ('G' in self.colors and 'W' in self.colors):
|
||||
if ('Land — Forest Plains' == row['type']
|
||||
or 'Snow Land — Forest Plains' == row['type']
|
||||
):
|
||||
self.land_df = self.land_df.drop(index)
|
||||
if ('R' in self.colors and 'W' in self.colors):
|
||||
for index, row in self.land_df.iterrows():
|
||||
if 'Land — Mountain Plains' == row['type']:
|
||||
dual_options.append(row['name'])
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(row['name']) is None:
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(row['name'])) <= self.max_card_price:
|
||||
dual_options.append(row['name'])
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
dual_options.append(row['name'])
|
||||
|
||||
# Boros Duals
|
||||
if ('R' in self.colors and 'W' in self.colors):
|
||||
if ('Land — Mountain Plains' == row['type']
|
||||
or 'Snow Land — Mountain Plains' == row['type']
|
||||
):
|
||||
self.land_df = self.land_df.drop(index)
|
||||
if (use_scrython and self.set_max_card_price):
|
||||
if self.price_check(row['name']) is None:
|
||||
continue
|
||||
else:
|
||||
if float(self.price_check(row['name'])) <= self.max_card_price:
|
||||
dual_options.append(row['name'])
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
dual_options.append(row['name'])
|
||||
|
||||
# Determine if using the dual-type lands
|
||||
print('Would you like to include dual-type lands (i.e. lands that count as both a Plains and a Swamp for example)?')
|
||||
|
@ -934,20 +1294,6 @@ class DeckBuilder:
|
|||
|
||||
# Add the Duals to a list
|
||||
while choice:
|
||||
# Include OG duals
|
||||
print('Would you like to include the OG dual lands (i.e. Tundra or Plateau)?')
|
||||
og_question = [
|
||||
inquirer.Confirm(
|
||||
'no',
|
||||
)
|
||||
]
|
||||
og_answer = inquirer.prompt(og_question)
|
||||
include_ogs = og_answer['no']
|
||||
og_duals = ['Tundra', 'Underground Sea', 'Badlands', 'Taiga', 'Savannah', 'Scrubland', 'Volcanic Island', 'Bayou', 'Plateau', 'Tropical Island']
|
||||
if not include_ogs:
|
||||
for land in og_duals:
|
||||
if land in dual_options:
|
||||
dual_options.remove(land)
|
||||
print('Here\'s all the dual-type lands in your commander\'s color identity:')
|
||||
print(*dual_options, sep='\n')
|
||||
print('\n')
|
||||
|
@ -959,15 +1305,20 @@ class DeckBuilder:
|
|||
|
||||
def add_misc_lands(self):
|
||||
|
||||
print(self.color_identity)
|
||||
# Add other remaining lands that match color identity
|
||||
rows_to_drop = []
|
||||
for index, row in self.land_df.iterrows():
|
||||
if row['colorIdentity'] not in self.color_identity_options:
|
||||
rows_to_drop.append(index)
|
||||
|
||||
filtered_lands_df = self.land_df.drop(rows_to_drop)
|
||||
|
||||
# Take the first 35 matches based on EDHRec popularity
|
||||
filtered_lands_df = filtered_lands_df.head(35)
|
||||
print(filtered_lands_df[['name']])
|
||||
|
||||
lands_to_add = []
|
||||
|
||||
# Randomly grab 10 lands
|
||||
|
||||
|
||||
def remove_basic(self):
|
||||
|
@ -978,14 +1329,14 @@ class DeckBuilder:
|
|||
elif color == 'U':
|
||||
basic = 'Island'
|
||||
elif color == 'B':
|
||||
basic = 'Swamp',
|
||||
basic = 'Swamp'
|
||||
elif color == 'R':
|
||||
basic = 'Mountain'
|
||||
elif color == 'G':
|
||||
basic = 'Forest'
|
||||
if basic not in basic_lands:
|
||||
basic_lands.append(basic)
|
||||
|
||||
|
||||
basic_land = random.choice(basic_lands)
|
||||
#print(basic_land)
|
||||
self.land_cards.remove(basic_land)
|
||||
|
|
10
settings.py
10
settings.py
|
@ -1,7 +1,8 @@
|
|||
artifact_tokens = ['Blood', 'Clue', 'Food', 'Gold', 'Incubator',
|
||||
'Junk','Map','Powerstone', 'Treasure']
|
||||
|
||||
banned_cards = ['Ancestral Recall', 'Balance', 'Biorhythm', 'Black Lotus',
|
||||
banned_cards = [# in commander
|
||||
'Ancestral Recall', 'Balance', 'Biorhythm', 'Black Lotus',
|
||||
'Braids, Cabal Minion', 'Chaos Orb', 'Coalition Victory',
|
||||
'Channel', 'Dockside Extortionist', 'Emrakul, the Aeons Torn',
|
||||
'Erayo, Soratami Ascendant', 'Falling Star', 'Fastbond',
|
||||
|
@ -15,7 +16,12 @@ banned_cards = ['Ancestral Recall', 'Balance', 'Biorhythm', 'Black Lotus',
|
|||
'Recurring Nightmare', 'Rofellos, Llanowar Emissary', 'Shahrazad',
|
||||
'Sundering Titan', 'Sway of the Stars', 'Sylvan Primordial',
|
||||
'Time Vault', 'Time Walk', 'Tinker', 'Tolarian Academy',
|
||||
'Trade Secrets', 'Upheaval', 'Yawgmoth\'s Bargain']
|
||||
'Trade Secrets', 'Upheaval', 'Yawgmoth\'s Bargain',
|
||||
|
||||
# In constructed
|
||||
'Invoke Prejudice', 'Cleanse', 'Stone-Throwing Devils', 'Pradesh Gypsies',
|
||||
'Jihad', 'Imprison', 'Crusade'
|
||||
]
|
||||
|
||||
board_wipe_tags = ['destroy all', 'destroy each', 'return all', 'return each', 'deals damage to each',
|
||||
'exile all', 'exile each', 'creatures get -X/-X', 'sacrifices all', 'sacrifices each',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue