239 lines
8.0 KiB
Python
239 lines
8.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test script for Religion and Diplomacy features.
|
|
|
|
Verifies that agents are spawned with diverse religions and factions,
|
|
and that the systems work correctly.
|
|
|
|
Usage:
|
|
python tools/test_religion_diplomacy.py [--steps 100]
|
|
"""
|
|
|
|
import argparse
|
|
import sys
|
|
from collections import defaultdict
|
|
from pathlib import Path
|
|
|
|
# Add parent directory for imports
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
|
|
from backend.config import get_config
|
|
from backend.core.engine import GameEngine
|
|
|
|
|
|
def test_agent_diversity(num_agents: int = 50, num_steps: int = 100):
|
|
"""Test that agents have diverse religions and factions."""
|
|
print("\n" + "=" * 70)
|
|
print(" RELIGION & DIPLOMACY SYSTEM TEST")
|
|
print("=" * 70)
|
|
|
|
# Initialize engine
|
|
engine = GameEngine()
|
|
engine.initialize(num_agents)
|
|
|
|
# Analyze agent distribution
|
|
religion_counts = defaultdict(int)
|
|
faction_counts = defaultdict(int)
|
|
faith_levels = []
|
|
|
|
agents = engine.world.agents
|
|
|
|
print(f"\n📊 Initial Agent Distribution ({len(agents)} agents):")
|
|
print("-" * 50)
|
|
|
|
for agent in agents:
|
|
religion = agent.religion.religion.value
|
|
faction = agent.diplomacy.faction.value
|
|
religion_counts[religion] += 1
|
|
faction_counts[faction] += 1
|
|
faith_levels.append(agent.religion.faith)
|
|
|
|
print("\n🕯️ RELIGIONS:")
|
|
for religion, count in sorted(religion_counts.items(), key=lambda x: -x[1]):
|
|
pct = count / len(agents) * 100
|
|
bar = "█" * int(pct / 5)
|
|
print(f" {religion:12s}: {count:3d} ({pct:5.1f}%) {bar}")
|
|
|
|
print("\n⚔️ FACTIONS:")
|
|
for faction, count in sorted(faction_counts.items(), key=lambda x: -x[1]):
|
|
pct = count / len(agents) * 100
|
|
bar = "█" * int(pct / 5)
|
|
print(f" {faction:12s}: {count:3d} ({pct:5.1f}%) {bar}")
|
|
|
|
avg_faith = sum(faith_levels) / len(faith_levels) if faith_levels else 0
|
|
print(f"\n✨ Average Faith: {avg_faith:.1f}")
|
|
|
|
# Check for issues
|
|
issues = []
|
|
|
|
atheist_pct = religion_counts.get("atheist", 0) / len(agents) * 100
|
|
if atheist_pct > 50:
|
|
issues.append(f"⚠️ Too many atheists: {atheist_pct:.1f}% (expected < 50%)")
|
|
|
|
neutral_pct = faction_counts.get("neutral", 0) / len(agents) * 100
|
|
if neutral_pct > 30:
|
|
issues.append(f"⚠️ Too many neutral faction: {neutral_pct:.1f}% (expected < 30%)")
|
|
|
|
if len(religion_counts) < 3:
|
|
issues.append(f"⚠️ Low religion diversity: only {len(religion_counts)} religions")
|
|
|
|
if len(faction_counts) < 3:
|
|
issues.append(f"⚠️ Low faction diversity: only {len(faction_counts)} factions")
|
|
|
|
if issues:
|
|
print("\n⚠️ ISSUES FOUND:")
|
|
for issue in issues:
|
|
print(f" {issue}")
|
|
else:
|
|
print("\n✅ Distribution looks good!")
|
|
|
|
# Run simulation to test mechanics
|
|
print("\n" + "=" * 70)
|
|
print(f" Running {num_steps} step simulation...")
|
|
print("=" * 70)
|
|
|
|
# Track events
|
|
religious_events = []
|
|
diplomatic_events = []
|
|
faith_changes = []
|
|
|
|
initial_faith = {a.id: a.religion.faith for a in agents}
|
|
|
|
for step in range(num_steps):
|
|
turn_log = engine.next_step()
|
|
|
|
# Collect events
|
|
religious_events.extend(turn_log.religious_events)
|
|
diplomatic_events.extend(turn_log.diplomatic_events)
|
|
|
|
if step % 20 == 19:
|
|
sys.stdout.write(f"\r Step {step + 1}/{num_steps}...")
|
|
sys.stdout.flush()
|
|
|
|
print(f"\r Completed {num_steps} steps! ")
|
|
|
|
# Final analysis
|
|
print("\n📈 SIMULATION RESULTS:")
|
|
print("-" * 50)
|
|
|
|
living_agents = engine.world.get_living_agents()
|
|
print(f" Living agents: {len(living_agents)}/{len(agents)}")
|
|
|
|
# Final faith levels
|
|
final_faith = [a.religion.faith for a in living_agents]
|
|
avg_final_faith = sum(final_faith) / len(final_faith) if final_faith else 0
|
|
print(f" Average faith: {avg_final_faith:.1f} (started: {avg_faith:.1f})")
|
|
|
|
# Events summary
|
|
print(f"\n Religious events: {len(religious_events)}")
|
|
if religious_events:
|
|
event_types = defaultdict(int)
|
|
for event in religious_events:
|
|
event_types[event.get("type", "unknown")] += 1
|
|
for event_type, count in sorted(event_types.items(), key=lambda x: -x[1])[:5]:
|
|
print(f" - {event_type}: {count}")
|
|
|
|
print(f"\n Diplomatic events: {len(diplomatic_events)}")
|
|
if diplomatic_events:
|
|
event_types = defaultdict(int)
|
|
for event in diplomatic_events:
|
|
event_types[event.get("type", "unknown")] += 1
|
|
for event_type, count in sorted(event_types.items(), key=lambda x: -x[1])[:5]:
|
|
print(f" - {event_type}: {count}")
|
|
|
|
# Check world state
|
|
stats = engine.world.get_statistics()
|
|
print(f"\n Total wars declared: {stats.get('total_wars', 0)}")
|
|
print(f" Total peace treaties: {stats.get('total_peace_treaties', 0)}")
|
|
print(f" Active wars: {stats.get('active_wars', [])}")
|
|
|
|
# Final religion/faction distribution
|
|
print("\n📊 Final Religion Distribution:")
|
|
final_religions = defaultdict(int)
|
|
for agent in living_agents:
|
|
final_religions[agent.religion.religion.value] += 1
|
|
|
|
for religion, count in sorted(final_religions.items(), key=lambda x: -x[1]):
|
|
pct = count / len(living_agents) * 100 if living_agents else 0
|
|
print(f" {religion:12s}: {count:3d} ({pct:5.1f}%)")
|
|
|
|
# Return metrics for optimization
|
|
return {
|
|
"initial_atheist_pct": atheist_pct,
|
|
"initial_neutral_pct": neutral_pct,
|
|
"religion_diversity": len(religion_counts),
|
|
"faction_diversity": len(faction_counts),
|
|
"avg_initial_faith": avg_faith,
|
|
"avg_final_faith": avg_final_faith,
|
|
"religious_events": len(religious_events),
|
|
"diplomatic_events": len(diplomatic_events),
|
|
"survival_rate": len(living_agents) / len(agents) if agents else 0,
|
|
}
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Test Religion & Diplomacy systems")
|
|
parser.add_argument("--agents", "-a", type=int, default=50, help="Number of agents")
|
|
parser.add_argument("--steps", "-s", type=int, default=100, help="Simulation steps")
|
|
|
|
args = parser.parse_args()
|
|
|
|
metrics = test_agent_diversity(args.agents, args.steps)
|
|
|
|
print("\n" + "=" * 70)
|
|
print(" TEST COMPLETE")
|
|
print("=" * 70)
|
|
|
|
# Final verdict
|
|
score = 0
|
|
max_score = 6
|
|
|
|
if metrics["initial_atheist_pct"] < 30:
|
|
score += 1
|
|
print("✅ Atheist percentage is reasonable")
|
|
else:
|
|
print(f"❌ Too many atheists: {metrics['initial_atheist_pct']:.1f}%")
|
|
|
|
if metrics["initial_neutral_pct"] < 20:
|
|
score += 1
|
|
print("✅ Neutral faction percentage is reasonable")
|
|
else:
|
|
print(f"❌ Too many neutrals: {metrics['initial_neutral_pct']:.1f}%")
|
|
|
|
if metrics["religion_diversity"] >= 4:
|
|
score += 1
|
|
print(f"✅ Good religion diversity: {metrics['religion_diversity']} religions")
|
|
else:
|
|
print(f"❌ Low religion diversity: {metrics['religion_diversity']} religions")
|
|
|
|
if metrics["faction_diversity"] >= 4:
|
|
score += 1
|
|
print(f"✅ Good faction diversity: {metrics['faction_diversity']} factions")
|
|
else:
|
|
print(f"❌ Low faction diversity: {metrics['faction_diversity']} factions")
|
|
|
|
if metrics["religious_events"] > 0:
|
|
score += 1
|
|
print(f"✅ Religious events occurring: {metrics['religious_events']}")
|
|
else:
|
|
print("❌ No religious events")
|
|
|
|
if metrics["diplomatic_events"] > 0 or metrics["religious_events"] > 0:
|
|
score += 1
|
|
print(f"✅ Social dynamics active")
|
|
else:
|
|
print("❌ No social dynamics")
|
|
|
|
print(f"\n📊 Score: {score}/{max_score}")
|
|
|
|
if score < max_score:
|
|
print("\n💡 Consider adjusting config.json parameters for better diversity")
|
|
|
|
return score == max_score
|
|
|
|
|
|
if __name__ == "__main__":
|
|
success = main()
|
|
sys.exit(0 if success else 1)
|
|
|