From 27f2934a62030eaf1bf6cc1f7f34802d3e1b86f3 Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Sun, 8 Jun 2025 20:34:11 -0500 Subject: add boss overview pages --- scripts/generate_boss_html.py | 303 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100755 scripts/generate_boss_html.py (limited to 'scripts/generate_boss_html.py') diff --git a/scripts/generate_boss_html.py b/scripts/generate_boss_html.py new file mode 100755 index 00000000..46ebd15f --- /dev/null +++ b/scripts/generate_boss_html.py @@ -0,0 +1,303 @@ +#!/usr/bin/env python3 +"""Generate html page of an AI boss opponent""" + +# TODO: support multiple languages + +import argparse +from pathlib import Path +from string import Template +import re +import yaml + +from data import name2file +import generate_card_hover_links + +SETS = {"kraken": "kraken", "tyrant": "tyrant"} +NAMES = {"kraken": "The Kraken", "tyrant": "The Tyrant"} +DESCS = { + "kraken": + "Face the evil of the sea. Overcome the kraken, the fierce epicenter of the ozean, which employs creatures of the depth to stop your offense.
Since the kraken does not move and can not win it is the perfect boss to start.", + "tyrant": "" # TODO +} + +TEMPLATE = """ + + + + + ${boss_name} + + + + +
+
+

${boss_name}

+cards[pdf] +map +ai-companion +

${desc}

+
+ +
+

Win Condition

+

${win_condition}

+

Starting Deck

+

${start_deck}

+

Recommended Draft ?

+

${draft}

+

Instructions

+

${instructions}

+
+
+ + +""" + + +def name_to_map(name: str) -> str: + """Return the map's file name of a boss""" + return name.lower().replace(" ", "-") + + +def wincon_desc(map_def: dict) -> str: + """Format a map's win condition""" + wincon = map_def['win_condition'] + if isinstance(wincon, str): + return wincon.capitalize() + + s = "" + for player, wc in wincon.items(): + s += f'
  • {player.capitalize()}: {wc.capitalize()}
  • ' + return f'' + + +def recommended_draft(map_def: dict) -> str: + """Format the map's recommended draft""" + # TODO: improve default draft + # TODO: format multiple recommendations + return map_def.get('draft', '3x[2;8]') + + +def ai_instruction(name: str, rules, lang: str) -> str: + """Extract the boss' instructions from the rules""" + rules_path = Path(rules) / lang / 'ai.md' + with open(rules_path, 'r', encoding='utf-8') as rf: + rules = rf.read() + + p = f'#.*{name}.*\n' + ai_start = re.findall(p, rules) + ai_start = ai_start[0] + + rules = rules[rules.find(ai_start) + len(ai_start):] + # rule taken from mdextractor + instructions = re.findall(r"```(?:\w+\s+)?(.*?)```", rules, re.DOTALL) + return instructions[0].strip() + + +def gen_startdeck_ul(map_def: dict, lang: str) -> str: + if 'start_deck_list' in map_def: + dl = map_def["start_deck_list"].splitlines() + else: + dl = ['3 misc/farmer'] + + s = "" + for card in dl: + cardFmt = "" + parts = card.split() + if len(parts) > 1: + cardFmt = f'{parts[0]} ' + c = parts[1] + else: + c = card + + def gen_link_target(c, lang): + return generate_card_hover_links.gen_link_to_cardlisting( + c, lang, path_prefix='../') + + hlink = generate_card_hover_links.gen_hoverable_link( + c, lambda _: c, gen_link_target, '../latex-build/', lang) + cardFmt += hlink + s += f'\n
  • {cardFmt}
  • ' + return f'' + + +def main(): + # pylint: disable=W0641 + """Generate a boss page""" + + parser = argparse.ArgumentParser(description='generate a boss html page') + parser.add_argument('name', + help='the name of the boss', + choices=['kraken', 'tyrant']) + parser.add_argument('data', help='directory containing the card data') + parser.add_argument('maps', help='directoey containing the map data') + parser.add_argument('rules', help='directoey containing the rules') + + args = parser.parse_args() + + lang = 'en' + boss_name = NAMES[args.name] + desc = DESCS[args.name] + set_name = SETS[args.name] + boss_card = f'{set_name}/{name2file(boss_name)}' + + map_name = name_to_map(boss_name) + map_path = Path(args.maps) / f'{map_name}.yml' + with open(map_path, 'r', encoding='utf-8') as map_file: + map_def = yaml.safe_load(map_file) + + win_condition = wincon_desc(map_def) + start_deck = gen_startdeck_ul(map_def, lang) + draft = recommended_draft(map_def) + instructions = ai_instruction(boss_name, args.rules, lang) + + print(Template(TEMPLATE).substitute(locals())) + + +if __name__ == '__main__': + main() -- cgit v1.2.3