aboutsummaryrefslogtreecommitdiff
path: root/artifact_analysis.py
diff options
context:
space:
mode:
Diffstat (limited to 'artifact_analysis.py')
-rw-r--r--artifact_analysis.py249
1 files changed, 249 insertions, 0 deletions
diff --git a/artifact_analysis.py b/artifact_analysis.py
new file mode 100644
index 0000000..dab4693
--- /dev/null
+++ b/artifact_analysis.py
@@ -0,0 +1,249 @@
+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() \ No newline at end of file