import json from collections import defaultdict, Counter from typing import Dict, List class ArtifactAnalyzer: def __init__(self): self.artifacts = [] self.characters = {} def load_data(self): """Load artifact and character data""" with open('data.json', 'r') as f: data = json.load(f) self.artifacts = data['artifacts'] with open('characters.json', 'r') as f: self.characters = json.load(f) def analyze_artifact_distribution(self): """Analyze artifact set and slot distribution""" print("="*60) print("šŸ“¦ ARTIFACT INVENTORY ANALYSIS") print("="*60) # Basic counts total_artifacts = len(self.artifacts) five_star_count = sum(1 for art in self.artifacts if art['rarity'] == 5) four_star_count = sum(1 for art in self.artifacts if art['rarity'] == 4) print(f"Total Artifacts: {total_artifacts}") print(f"5⭐ Artifacts: {five_star_count} ({five_star_count/total_artifacts*100:.1f}%)") print(f"4⭐ Artifacts: {four_star_count} ({four_star_count/total_artifacts*100:.1f}%)") # Set distribution set_counts = Counter(art['setKey'] for art in self.artifacts) print(f"\nšŸŽ­ Artifact Sets ({len(set_counts)} unique sets):") for set_name, count in set_counts.most_common(): print(f" {set_name}: {count} pieces") # Slot distribution slot_counts = Counter(art['slotKey'] for art in self.artifacts) print(f"\nšŸŽÆ Slot Distribution:") slot_names = {'flower': 'Flower', 'plume': 'Feather', 'sands': 'Sands', 'goblet': 'Goblet', 'circlet': 'Circlet'} for slot, count in slot_counts.items(): print(f" {slot_names.get(slot, slot)}: {count} pieces") def analyze_main_stats(self): """Analyze main stat distribution by slot""" print(f"\nšŸ“Š MAIN STAT ANALYSIS") print("="*60) # Group by slot slot_main_stats = defaultdict(Counter) for art in self.artifacts: slot_main_stats[art['slotKey']][art['mainStatKey']] += 1 slot_names = {'flower': 'Flower', 'plume': 'Feather', 'sands': 'Sands', 'goblet': 'Goblet', 'circlet': 'Circlet'} for slot, main_stats in slot_main_stats.items(): print(f"\n{slot_names.get(slot, slot)}:") total_slot = sum(main_stats.values()) for main_stat, count in main_stats.most_common(): percentage = count / total_slot * 100 print(f" {main_stat}: {count} ({percentage:.1f}%)") def analyze_levels_and_quality(self): """Analyze artifact levels and upgrade status""" print(f"\nšŸ“ˆ ARTIFACT QUALITY ANALYSIS") print("="*60) # Level distribution level_counts = Counter(art['level'] for art in self.artifacts) print(f"Level Distribution:") for level in sorted(level_counts.keys(), reverse=True): count = level_counts[level] percentage = count / len(self.artifacts) * 100 print(f" Level {level}: {count} ({percentage:.1f}%)") # Maxed artifacts maxed_5star = sum(1 for art in self.artifacts if art['level'] == 20 and art['rarity'] == 5) maxed_4star = sum(1 for art in self.artifacts if art['level'] >= 16 and art['rarity'] == 4) print(f"\nMaxed Artifacts:") print(f" 5⭐ Level 20: {maxed_5star}") print(f" 4⭐ Level 16+: {maxed_4star}") # Average level by rarity five_star_levels = [art['level'] for art in self.artifacts if art['rarity'] == 5] four_star_levels = [art['level'] for art in self.artifacts if art['rarity'] == 4] if five_star_levels: avg_5star = sum(five_star_levels) / len(five_star_levels) print(f"\nAverage Levels:") print(f" 5⭐ Average: {avg_5star:.1f}") if four_star_levels: avg_4star = sum(four_star_levels) / len(four_star_levels) print(f" 4⭐ Average: {avg_4star:.1f}") def analyze_character_assignments(self): """Analyze which characters have artifacts assigned""" print(f"\nšŸ‘„ CHARACTER ASSIGNMENT ANALYSIS") print("="*60) # Count assignments assignments = Counter() unassigned_count = 0 for art in self.artifacts: location = art.get('location', '') if location and location.strip(): assignments[location] += 1 else: unassigned_count += 1 print(f"Assigned Artifacts: {sum(assignments.values())}") print(f"Unassigned Artifacts: {unassigned_count}") print(f"Assignment Rate: {sum(assignments.values())/len(self.artifacts)*100:.1f}%") if assignments: print(f"\nCharacter Assignments:") for char, count in assignments.most_common(): print(f" {char}: {count} pieces") # Show set composition for each character char_artifacts = [art for art in self.artifacts if art.get('location') == char] char_sets = Counter(art['setKey'] for art in char_artifacts) set_summary = ", ".join(f"{set_name}({count})" for set_name, count in char_sets.items()) print(f" Sets: {set_summary}") def analyze_substats(self): """Analyze substat distribution and quality""" print(f"\n⚔ SUBSTAT ANALYSIS") print("="*60) # Count substat occurrences substat_counts = Counter() substat_values = defaultdict(list) for art in self.artifacts: for substat in art.get('substats', []): key = substat['key'] value = substat['value'] substat_counts[key] += 1 substat_values[key].append(value) print(f"Substat Frequency (across all artifacts):") for stat, count in substat_counts.most_common(): avg_value = sum(substat_values[stat]) / len(substat_values[stat]) max_value = max(substat_values[stat]) print(f" {stat}: {count} rolls (avg: {avg_value:.1f}, max: {max_value:.1f})") # High-value substats print(f"\nHigh-Value Substat Instances:") high_value_thresholds = { 'critRate_': 10.0, 'critDMG_': 20.0, 'atk_': 15.0, 'hp_': 15.0, 'def_': 18.0, 'enerRech_': 20.0, 'eleMas': 60.0 } for art in self.artifacts: high_value_substats = [] for substat in art.get('substats', []): key = substat['key'] value = substat['value'] threshold = high_value_thresholds.get(key, float('inf')) if value >= threshold: high_value_substats.append(f"{key}:{value}") if high_value_substats: set_name = art['setKey'] slot = art['slotKey'] level = art['level'] print(f" {set_name} {slot} L{level}: {', '.join(high_value_substats)}") def analyze_optimization_potential(self): """Analyze potential for optimization""" print(f"\nšŸŽÆ OPTIMIZATION POTENTIAL") print("="*60) # Unassigned high-level artifacts unassigned_maxed = [art for art in self.artifacts if not art.get('location', '').strip() and ((art['rarity'] == 5 and art['level'] == 20) or (art['rarity'] == 4 and art['level'] >= 16))] print(f"Unassigned High-Level Artifacts: {len(unassigned_maxed)}") if unassigned_maxed: print("Available for optimization:") slot_counts = Counter(art['slotKey'] for art in unassigned_maxed) for slot, count in slot_counts.items(): print(f" {slot}: {count} pieces") # Character coverage known_chars = set(self.characters.keys()) assigned_chars = set(art.get('location', '') for art in self.artifacts if art.get('location', '').strip()) print(f"\nCharacter Coverage:") print(f" Known characters: {len(known_chars)}") print(f" Characters with artifacts: {len(assigned_chars)}") unoptimized_chars = known_chars - assigned_chars if unoptimized_chars: print(f" Unoptimized characters: {', '.join(unoptimized_chars)}") # Set bonus potential print(f"\nSet Bonus Analysis:") for set_name, count in Counter(art['setKey'] for art in self.artifacts).items(): if count >= 4: bonus_type = "4-piece" if count >= 4 else "2-piece" print(f" {set_name}: {count} pieces (can form {bonus_type} set)") def run_full_analysis(self): """Run complete artifact analysis""" print("šŸ” GENSHIN IMPACT ARTIFACT ANALYSIS") print("="*80) self.load_data() self.analyze_artifact_distribution() self.analyze_main_stats() self.analyze_levels_and_quality() self.analyze_character_assignments() self.analyze_substats() self.analyze_optimization_potential() print(f"\n{'='*80}") print("šŸ“‹ ANALYSIS COMPLETE") print("="*80) print("Use this information to:") print("• Identify which artifacts need upgrading") print("• Find optimization opportunities") print("• Plan future artifact farming") print("• Optimize character builds") def main(): analyzer = ArtifactAnalyzer() analyzer.run_full_analysis() if __name__ == "__main__": main()