From 9cc423f1e3b0a1d9e498c522cb550709e348eed7 Mon Sep 17 00:00:00 2001 From: Supremist Date: Thu, 30 Oct 2025 01:16:56 +0200 Subject: Add weapon damage comparison graph --- main.py | 89 ++++++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 66 insertions(+), 23 deletions(-) (limited to 'main.py') diff --git a/main.py b/main.py index 53993f1..0a25394 100644 --- a/main.py +++ b/main.py @@ -5,8 +5,15 @@ from creature import CreaturePlan from actions import Attack from items import Weapon +from collections import defaultdict + +import matplotlib.pyplot as plt +from matplotlib.ticker import AutoLocator, AutoMinorLocator, MultipleLocator + import pb2e +plt.style.use('dark_background') + def treat_wounds(check_res, heal_bonus=0): if check_res <= Roll.Fumble: return -d(8) @@ -60,36 +67,72 @@ def main(): treat = d(20).apply(Roll.check, 20, bonus+1).apply(treat_wounds, 15) show_stat("Treat Wounds 20 +1", treat) -def main2(): - ac = 18 - bonus = +8 - dmg = d(6)+4 - attack = d(20).apply(Roll.check, ac, bonus) - show_stat("attack", attack) - total_dmg = attack.apply(strike, dmg+1) - show_stat("dogslicer", total_dmg) - total_dmg = attack.apply(strike, dmg, d(8)) - show_stat("rapier", total_dmg) def test3(): - level = 2 - #char_js = pb2e.download_character(pfb_id=160180) + # char_js = pb2e.download_character(pfb_id=160180) char_js = pb2e.open_character("quizrel2") char_plan = CharacterPlan(char_js) - char = char_plan.build(level) - falcata = Weapon("falcata", "martial", "sword", 8, fatal=12) - char.weapons.append(falcata) - char.update_fundamental_runes() - creature_plan = CreaturePlan(default_difficulty=Difficulty.Moderate) # creature_plan["reflex"] = Difficulty.High # creature_plan["ac"] = Difficulty.High - creature = creature_plan.build(level) - attack = Attack(char, creature, falcata) - print(char.toJSON()) - print(f"Attack +{attack.bonus()} vs AC {attack.target.ac()}") - show_stat("roll", attack.roll()) - show_stat("falcata", attack.strike()) + + def calc_damage(level): + char = char_plan.build(level) + creature = creature_plan.build(level) + creature["ac"] -= 2 + falcata = Weapon("falcata", "martial", "sword", 8, fatal=12) + sword = Weapon("sword", "martial", "sword", 8) + rapier = Weapon("rapier", "martial", "sword", 6, finesse=True, deadly=8) + sword2 = Weapon("sword_d6", "martial", "sword", 6) + char.weapons = [falcata, sword, rapier, sword2] + char.update_fundamental_runes() + + # print(char.toJSON()) + # attack = Attack(char, creature, falcata) + # print(Roll.short_str(attack.roll())) + # print(f"Attack +{attack.bonus()} vs AC {attack.target.ac()} dmg +{attack.damage_bonus()}") + # show_stat("roll", attack.roll()) + # show_stat("falcata", attack.strike()) + + res = dict() + for weapon in char.weapons: + attack = Attack(char, creature, weapon) + res[weapon.name] = attack.strike().expected() + # res["hp"] = creature["hp"] + return res + + # calc_damage(20) + + levelup_view("Weapons Comparison", "Expected Damage", calc_damage) + + + +def levelup_view(title, ylabel, fn): + # Example data + levels = list(range(1, 21)) + table = defaultdict(list) + for level in levels: + res = fn(level) + for k,v in res.items(): + table[k].append(v) + + fig, ax = plt.subplots() + fig.set_size_inches(18.5, 10.5) + + # Plot multiple lines on the same plane + for label, values in table.items(): + plt.plot(levels, values, label=label) + + # Add labels and legend + plt.xlabel("Level") + plt.ylabel(ylabel) + plt.title(title) + ax.grid(True, linestyle='--', alpha=0.4) + ax.xaxis.set_major_locator(MultipleLocator(1)) + ax.yaxis.set_major_locator(AutoLocator()) + ax.yaxis.set_minor_locator(AutoMinorLocator()) + plt.legend() + plt.show() if __name__ == '__main__': -- cgit v1.2.3