Create generate_draft_pool_seeded.py
This commit is contained in:
parent
9309adb4d4
commit
8c4d05282b
2 changed files with 149 additions and 1 deletions
21
cube_pool.py
21
cube_pool.py
|
|
@ -5,7 +5,7 @@ import dataclasses
|
||||||
import itertools
|
import itertools
|
||||||
import random
|
import random
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from typing import Dict, List, Set
|
from typing import Dict, List, Set, Tuple
|
||||||
|
|
||||||
import cubecobra_csv
|
import cubecobra_csv
|
||||||
from cubecobra_csv import CubeCard
|
from cubecobra_csv import CubeCard
|
||||||
|
|
@ -45,6 +45,25 @@ class CubePool:
|
||||||
def get_category(self, color_category: str) -> List[CubeCard]:
|
def get_category(self, color_category: str) -> List[CubeCard]:
|
||||||
return self._categories[color_category]
|
return self._categories[color_category]
|
||||||
|
|
||||||
|
def split_category_by_tag(self, color_category_to_split: str, tag: str,
|
||||||
|
yes_category: str, no_category: str) -> None:
|
||||||
|
existing = self._categories[color_category_to_split]
|
||||||
|
del self._categories[color_category_to_split]
|
||||||
|
new_yes, new_no = [], []
|
||||||
|
for card in existing:
|
||||||
|
if tag in card.tags:
|
||||||
|
new_yes.append(card)
|
||||||
|
else:
|
||||||
|
new_no.append(card)
|
||||||
|
self._categories[yes_category] = new_yes
|
||||||
|
self._categories[no_category] = new_no
|
||||||
|
|
||||||
|
def join_categories(self, categories_to_join: List[str], joined_category: str):
|
||||||
|
joined = list(itertools.chain.from_iterable(self._categories[c] for c in categories_to_join))
|
||||||
|
for c in categories_to_join:
|
||||||
|
del(self._categories[c])
|
||||||
|
self._categories[joined_category] = joined
|
||||||
|
|
||||||
|
|
||||||
def load_pools(csv_path: str, pool_tags: Set[str]) -> Dict[str, CubePool]:
|
def load_pools(csv_path: str, pool_tags: Set[str]) -> Dict[str, CubePool]:
|
||||||
pools = defaultdict(CubePool)
|
pools = defaultdict(CubePool)
|
||||||
|
|
|
||||||
129
generate_draft_pool_seeded.py
Normal file
129
generate_draft_pool_seeded.py
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
# Generate a draft pool for mtgadraft.tk or dr4ft.info
|
||||||
|
# Seeds color categories.
|
||||||
|
import collections
|
||||||
|
import itertools
|
||||||
|
import math
|
||||||
|
import random
|
||||||
|
|
||||||
|
import cube_pool
|
||||||
|
import cubecobra_csv
|
||||||
|
|
||||||
|
from cubecobra_csv import CubeCard
|
||||||
|
|
||||||
|
DEBUG_PRINT = False
|
||||||
|
|
||||||
|
SEATS = 5
|
||||||
|
SEEDING = [
|
||||||
|
'oowubrgcfxxxx',
|
||||||
|
'owubrgcfxxxxx',
|
||||||
|
'wubrgcfxxxxxx',
|
||||||
|
'wubrgcfxxxxxx'
|
||||||
|
]
|
||||||
|
ROUNDS = len(SEEDING)
|
||||||
|
PACKS = ROUNDS * SEATS
|
||||||
|
|
||||||
|
FIXING_TAG = 'gold_land'
|
||||||
|
CATEGORIES_TO_INCLUDE_ALL = ['f']
|
||||||
|
|
||||||
|
CUBE_NAME = 'TheElegantCube_fetched'
|
||||||
|
|
||||||
|
OUTPUT_FILENAME = 'cards_in_draft.txt'
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
csv_path = cubecobra_csv.request_cube_csv('TheElegantCube_fetched', 'elegant')
|
||||||
|
|
||||||
|
pools = cube_pool.load_pools(csv_path, {'core', 'occasional'})
|
||||||
|
pools['core'].split_category_by_tag('l', FIXING_TAG, 'f', 'l')
|
||||||
|
pools['core'].join_categories(['m', 'h'], 'm')
|
||||||
|
|
||||||
|
seeded_slots_per_category = collections.Counter(itertools.chain.from_iterable(SEEDING))
|
||||||
|
seeded_size_per_category = {}
|
||||||
|
for category in 'owubrgcflmx':
|
||||||
|
seeded_category_size = seeded_slots_per_category[category] * SEATS
|
||||||
|
print(f'seeded_category_size of cat {category} is {seeded_category_size}')
|
||||||
|
seeded_size_per_category[category] = seeded_category_size
|
||||||
|
|
||||||
|
total_core_pool_to_use = sum(seeded_size_per_category.values()) - seeded_size_per_category['o']
|
||||||
|
for category in CATEGORIES_TO_INCLUDE_ALL:
|
||||||
|
total_core_pool_to_use -= seeded_size_per_category[category]
|
||||||
|
print('total_core_pool_to_use %d' % total_core_pool_to_use)
|
||||||
|
|
||||||
|
core_size_per_category = {}
|
||||||
|
core_size_to_split = 0
|
||||||
|
for category in 'wubrgcflm':
|
||||||
|
core_category_size = len(pools['core'].get_category(category))
|
||||||
|
print(f'core size of cat {category} is {core_category_size}')
|
||||||
|
core_size_per_category[category] = core_category_size
|
||||||
|
if category not in CATEGORIES_TO_INCLUDE_ALL:
|
||||||
|
core_size_to_split += core_category_size
|
||||||
|
|
||||||
|
print(f'total_core_pool_to_use: {total_core_pool_to_use}')
|
||||||
|
print(f'core_size_to_split: {core_size_to_split}')
|
||||||
|
percentage_of_core = total_core_pool_to_use / core_size_to_split
|
||||||
|
print(f'percentage of core to use: {percentage_of_core}')
|
||||||
|
|
||||||
|
desired_size_per_category = {}
|
||||||
|
for category in 'wubrgcflm':
|
||||||
|
if category in CATEGORIES_TO_INCLUDE_ALL:
|
||||||
|
desired_category_size = core_size_per_category[category]
|
||||||
|
else:
|
||||||
|
desired_category_size = math.ceil(percentage_of_core * core_size_per_category[category])
|
||||||
|
print(f'desired size of cat {category} is {desired_category_size}')
|
||||||
|
desired_size_per_category[category] = desired_category_size
|
||||||
|
|
||||||
|
leftover_pool = []
|
||||||
|
for category in 'wubrgcflm':
|
||||||
|
assert(seeded_size_per_category[category] <= desired_size_per_category[category]), \
|
||||||
|
(f'Cannot seed {seeded_size_per_category[category]} cards from category {category} from desired size '
|
||||||
|
f'{desired_size_per_category[category]}')
|
||||||
|
leftover_category_size = desired_size_per_category[category] - seeded_size_per_category[category]
|
||||||
|
leftovers = pools['core'].draw_from_category(category, leftover_category_size)
|
||||||
|
leftover_pool.extend(leftovers)
|
||||||
|
random.shuffle(leftover_pool)
|
||||||
|
|
||||||
|
position_pools_per_round = []
|
||||||
|
for round_seeding in SEEDING:
|
||||||
|
position_pools = []
|
||||||
|
for pos, category in enumerate(round_seeding):
|
||||||
|
if category in 'wubrgcflm':
|
||||||
|
drawn = pools['core'].draw_from_category(category, SEATS)
|
||||||
|
elif category in 'x':
|
||||||
|
drawn = None
|
||||||
|
elif category in 'o':
|
||||||
|
drawn = pools['occasional'].wide_sample(SEATS)
|
||||||
|
else:
|
||||||
|
raise ValueError(f'Category cannot be {category}')
|
||||||
|
position_pools.append(drawn)
|
||||||
|
position_pools_per_round.append(position_pools)
|
||||||
|
|
||||||
|
|
||||||
|
boosters = []
|
||||||
|
for round_seeding, position_pools in zip(SEEDING, position_pools_per_round):
|
||||||
|
for s in range(SEATS):
|
||||||
|
booster = []
|
||||||
|
for category, position_pool in zip(round_seeding, position_pools):
|
||||||
|
if category in 'owubrgcflm':
|
||||||
|
card = position_pool.pop()
|
||||||
|
elif category in 'x':
|
||||||
|
card = leftover_pool.pop()
|
||||||
|
booster.append(card)
|
||||||
|
|
||||||
|
boosters.append(booster)
|
||||||
|
|
||||||
|
with open(OUTPUT_FILENAME, 'wb') as f:
|
||||||
|
for booster in boosters:
|
||||||
|
def render_card_line(card: CubeCard) -> str:
|
||||||
|
if DEBUG_PRINT:
|
||||||
|
return f'{card.name} ({card.color_category})'
|
||||||
|
else:
|
||||||
|
return card.name
|
||||||
|
booster_names = [render_card_line(card) for card in booster]
|
||||||
|
booster_contents = '\n'.join(booster_names).encode('utf-8')
|
||||||
|
f.write(booster_contents)
|
||||||
|
f.write(b'\n\n')
|
||||||
|
print(f'Wrote {len(boosters)} boosters to {OUTPUT_FILENAME}')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue