import numpy as np import matplotlib.pyplot as plt class CharacterStatistics: def __init__(self, characters): self.characters = characters self.characters_array = np.array([c.to_list() for c in characters]) # 前n名排行榜 def find_highest_cultivation(self, n=1): sorted_characters = sorted(self.characters, key=lambda c: (c.cultivation_rank, c.cultivation_level), reverse=True) return sorted_characters[:n] # 宗族人数排行榜 def rank_top_clans(self, top_n=4): clan_size = {} for c in self.characters: clan_size[c.clan] = clan_size.get(c.clan, 0) + 1 sorted_clans = sorted(clan_size.items(), key=lambda x: x[1], reverse=True)[:top_n] return sorted_clans # real_age、apparent_age、cultivation_level、cultivation_rank 分布图 def plot_attribute_distribution(self): attributes = ['Real Age', 'Apparent Age', 'Cultivation Level', 'Cultivation Rank'] attribute_indices = [0, 1, 2, 3] fig, axs = plt.subplots(2, 2, figsize=(10, 8)) axs = axs.flatten() for i, ax in enumerate(axs): ax.hist(self.characters_array[:, attribute_indices[i]], bins=20, edgecolor='black') ax.set_xlabel(attributes[i]) ax.set_ylabel('Frequency') plt.tight_layout() return fig # real_age、apparent_age、cultivation_level、cultivation_rank、孩子数量 统计平均数 def calculate_average_attributes(self): real_age_mean = np.mean(self.characters_array[:, 0]) apparent_age_mean = np.mean(self.characters_array[:, 1]) cultivation_level_mean = np.mean(self.characters_array[:, 2]) cultivation_rank_mean = np.mean(self.characters_array[:, 3]) child_count_mean = np.mean(self.characters_array[:, 19]) return real_age_mean, apparent_age_mean, cultivation_level_mean, cultivation_rank_mean, child_count_mean # 画出 cultivation_rank (x轴) 和 4项combat_power的关系(y轴) def plot_combat_power_vs_cultivation_rank(self): fig, axs = plt.subplots(2, 2, figsize=(10, 8)) axs = axs.flatten() for i, combat_power in enumerate(['Attack Power', 'Defense Power', 'Attack Speed', 'Health Points']): combat_power_data = [] for rank in range(6): rank_data = self.characters_array[self.characters_array[:,3]==rank, i+5] combat_power_data.append(rank_data) axs[i].boxplot(combat_power_data) axs[i].set_title(combat_power) axs[i].set_xlabel('Cultivation Rank') axs[i].set_ylabel('Value') plt.tight_layout() return fig def calculate_average_special_constitution(self): special_constitution_mean = np.mean(self.characters_array[:, 9:13], axis=0) return special_constitution_mean def calculate_average_spiritual_roots(self): spiritual_roots_mean = np.mean(self.characters_array[:, 13:18], axis=0) return spiritual_roots_mean # 统计无灵根者的数量 def count_zero_spiritual_roots(self): zero_spiritual_roots_count = np.sum(np.all(self.characters_array[:, 13:18] == 0, axis=1)) return zero_spiritual_roots_count # 灵根数量分布图 def plot_sum_spiritual_root_distribution(self): spiritual_roots_sum = np.sum(self.characters_array[:, 13:18], axis=1) fig = plt.figure() plt.hist(spiritual_roots_sum, bins=5, range=(0,5)) plt.xlabel('Number of Spiritual Roots') plt.ylabel('Number of Characters') plt.title('Distribution of Spiritual Roots') return fig # 各灵根人口分布(x轴:5种灵根,y轴:人数) def plot_spiritual_roots_distribution(self): spiritual_roots = self.characters_array[:, 13:18] means = np.mean(spiritual_roots, axis=0) roots = ['Metal', 'Wood', 'Water', 'Fire', 'Earth'] fig = plt.figure() plt.bar(roots, means) plt.xlabel('Spiritual Roots') plt.ylabel('Percentage of Characters') plt.title('Distribution of Spiritual Roots in Population') return fig # 宗族人数分布图 def plot_clan_size_distribution(self): clan_size = {} for c in self.characters: clan_size[c.clan] = clan_size.get(c.clan, 0) + 1 sizes = list(clan_size.values()) fig = plt.figure() plt.hist(sizes, bins=20) plt.xlabel('Clan Size') plt.ylabel('Number of Clans') return fig def summarize(self): print("===== Character Statistics Summary =====") # 打印平均属性 print("Average Attributes:") real_age, apparent_age, cultivation_level, cultivation_rank, child_count = self.calculate_average_attributes() print(f"Real Age: {real_age:.2f}") print(f"Apparent Age: {apparent_age:.2f}") print(f"Cultivation Level: {cultivation_level:.2f}") print(f"Cultivation Rank: {cultivation_rank:.2f}") print(f"Child Count: {child_count:.2f}") # 打印平均特质 print("\nAverage Special Constitutions:") special_names = ['战斗', '合欢', '灵龟', '蜉蝣'] for i, v in enumerate(self.calculate_average_special_constitution()): print(f"{special_names[i]}: {v:.2%}") # 打印平均灵根 print("\nAverage Spiritual Roots:") root_names = ['金', '木', '水', '火', '土'] for i, v in enumerate(self.calculate_average_spiritual_roots()): print(f"{root_names[i]}: {v:.2%}") # 打印统计图 print("\nPlotting graphs...") self.plot_attribute_distribution() # self.plot_combat_power_vs_cultivation_rank() self.plot_spiritual_roots_distribution() self.plot_sum_spiritual_root_distribution() self.plot_clan_size_distribution() self.print_top_cultivators() # 攻击力排行榜 self.print_rank('attack_power', name='Attack Power') # 防御力排行榜 self.print_rank('defense_power', name='Defense Power') self.print_top_clans() print("\n===== End Summary =====\n") # 返回Markdown字符串的总结输出 def summarize_markdown(self): md = "## Character Statistics Summary\n\n" md += "### Average Attributes:\n\n" real_age, apparent_age, cultivation_level, cultivation_rank, child_count = self.calculate_average_attributes() md += f"Real Age: {real_age:.2f}\n\n" md += f"Apparent Age: {apparent_age:.2f}\n\n" md += f"Cultivation Level: {cultivation_level:.2f}\n\n" md += f"Cultivation Rank: {cultivation_rank:.2f}\n\n" md += f"Child Count: {child_count:.2f}\n\n" md += "### Average Special Constitutions:\n\n" special_names = ['战斗', '合欢', '灵龟', '蜉蝣'] for i, v in enumerate(self.calculate_average_special_constitution()): md += f"{special_names[i]}: {v:.2%}\n\n" md += "### Average Spiritual Roots:\n\n" root_names = ['金', '木', '水', '火', '土'] for i, v in enumerate(self.calculate_average_spiritual_roots()): md += f"{root_names[i]}: {v:.2%}\n\n" # md += "### Plotting graphs...\n\n" # 画图并保存 fig1 = self.plot_attribute_distribution() # fig1.savefig('./attribute_distribution.png') # md += "#### Attribute Distribution\n\n" # md += "![Attribute Distribution](./attribute_distribution.png)\n\n" fig2 = self.plot_spiritual_roots_distribution() # fig2.savefig('./spiritual_roots_distribution.png') # md += "#### Spiritual Roots Distribution\n\n" # md += "![Spiritual Roots Distribution](./spiritual_roots_distribution.png)\n\n" fig3 = self.plot_sum_spiritual_root_distribution() # fig3.savefig('./sum_spiritual_roots_distribution.png') # md += "#### Sum Spiritual Roots Distribution\n\n" # md += "![Sum Spiritual Roots Distribution](./sum_spiritual_roots_distribution.png)\n\n" fig4 = self.plot_clan_size_distribution() # fig4.savefig('clan_size_distribution.png') # md += "#### Clan Size Distribution\n\n" # md += "![Clan Size Distribution](clan_size_distribution.png)\n\n" md += "#### Top Cultivators\n\n" md += self.print_top_cultivators_markdown() md += "#### Attack Power Ranking\n\n" md += self.print_rank_markdown('attack_power', name='Attack Power') md += "#### Defense Power Ranking\n\n" md += self.print_rank_markdown('defense_power', name='Defense Power') md += "#### Top Clans\n\n" md += self.print_top_clans_markdown() return md, fig1, fig2, fig3, fig4 def print_top_cultivators(self, top_n=10): print("\n== Top Cultivators ==") print("{:<10} {:>10} {:>10} {:>10} {:>10}".format('Name', 'Clan', 'Rank', 'Level', '境界')) for c in self.find_highest_cultivation(top_n): print("{:<10} {:>10} {:>10} {:>10} {:>10}".format(c.name, c.clan, c.cultivation_rank, c.cultivation_level, c.view_rank())) def print_top_cultivators_markdown(self, n=10): md = f"| Name | Clan | Cultivation Rank | Cultivation Level | 境界\n" md += "| ---- | ---- | ---------------- | ---------------- | ----\n" for c in self.find_highest_cultivation(n): md += f"| {c.name} | {c.clan} | {c.cultivation_rank:.2f} | {c.cultivation_level:.2f} | {c.view_rank()}\n" return md def print_rank(self, rank_key, top_n=10, name=None): print(f"\n== {'Name' if name is None else name} Rank ==") sorted_characters = sorted(self.characters, key=lambda c: c.combat_power[rank_key], reverse=True) print("{:<10} {:>10} {:>10} {:>10} {:>10}".format('Name', rank_key if name is None else name, 'Rank', 'Level', '境界')) for c in sorted_characters[:top_n]: print("{:<10} {:>10}{:>10} {:>10} {:>10}".format(c.name, c.combat_power[rank_key], c.cultivation_rank, c.cultivation_level, c.view_rank())) def print_rank_markdown(self, attr, name=None, n=10): md = f"| Name | {attr if name is None else name} | Cultivation Rank | Cultivation Level | 境界\n" md += "| ---- | ---- | ---------------- | ---------------- | ----\n" sorted_characters = sorted(self.characters, key=lambda c: c.combat_power[attr], reverse=True) for c in sorted_characters[:n]: md += f"| {c.name} | {c.combat_power[attr]:.2f} | {c.cultivation_rank:.2f} | {c.cultivation_level:.2f} | {c.view_rank()}\n" return md def print_top_clans(self, top_n=4): print("\n== Top Clans ==") print("{:<10} {:>10}".format('Clan', 'Members')) for clan, size in self.rank_top_clans(top_n): print("{:<10} {:>10}".format(clan, size)) def print_top_clans_markdown(self, n=10): md = "| Clan | Clan Size |\n" md += "| -------- | --------- |\n" for clan, size in self.rank_top_clans(n): md += f"| {clan} | {size} |\n" return md