@page "/simulation" @inject GameSimulationService SimService Ecology Simulation

Ecology Simulation

@if (!SimService.Data.IsInitialized) {

Simulate 20 turns of predator, prey, and flora ecology across the valley.

} else {
Turn @SimService.Data.CurrentTurn / 20
@CurrentEvent?.MeepleType Ecology in @string.Join(", ", CurrentEvent?.RegionTypes ?? new())
@{ var currentRegions = SimService.GetCurrentState(); var activatedRegionNames = new HashSet(); if (CurrentEvent != null) { activatedRegionNames = currentRegions .Where(r => CurrentEvent.RegionTypes.Contains(r.Terrain)) .Select(r => r.Name) .ToHashSet(); } } @foreach (var line in GetConnectionLines(currentRegions)) { } @foreach (var region in currentRegions) { var isActivated = activatedRegionNames.Contains(region.Name); var terrainColor = GetTerrainColor(region.Terrain); var labelX = region.X + 24; @region.Name P:@region.PredatorMeeples R:@region.PreyMeeples F:@region.FloraMeeples }
@if (CurrentEvent != null && CurrentEvent.Details.Count > 0) {
Turn @CurrentEvent.TurnNumber Details
@foreach (var detail in CurrentEvent.Details) {
@detail
}
}
@{ var totals = SimService.GetCurrentState(); }
Predators: @totals.Sum(r => r.PredatorMeeples)
Prey: @totals.Sum(r => r.PreyMeeples)
Flora: @totals.Sum(r => r.FloraMeeples)
} @code { private TurnEvent? CurrentEvent => SimService.Data.CurrentTurn > 0 && SimService.Data.CurrentTurn <= SimService.Data.Events.Count ? SimService.Data.Events[SimService.Data.CurrentTurn - 1] : null; private string EventBadgeClass => CurrentEvent?.MeepleType switch { "Predator" => "danger", "Prey" => "warning", "Flora" => "success", _ => "secondary" }; protected override void OnInitialized() { SimService.RunSimulation(); } private void StartSimulation() { SimService.RunSimulation(); } private void PrevTurn() { if (SimService.Data.CurrentTurn > 1) SimService.Data.CurrentTurn--; } private void NextTurn() { if (SimService.Data.CurrentTurn < 20) SimService.Data.CurrentTurn++; } private void RandomizeEvents() { SimService.RandomizeEvents(); } private static string GetTerrainColor(string terrain) { return terrain switch { "Grass" => "#4caf50", "Forest" => "#2e7d32", "Mountain" => "#78909c", "Water" => "#42a5f5", "Wasteland" => "#8d6e63", _ => "#888" }; } private record ConnectionLine(int X1, int Y1, int X2, int Y2); private List GetConnectionLines(List regions) { var lookup = regions.ToDictionary(r => r.Name); var lines = new List(); var drawn = new HashSet(); foreach (var region in regions) { foreach (var conn in region.Connections) { var key = string.Compare(region.Name, conn, StringComparison.OrdinalIgnoreCase) < 0 ? $"{region.Name}|{conn}" : $"{conn}|{region.Name}"; if (!drawn.Add(key)) continue; if (!lookup.TryGetValue(conn, out var target)) continue; lines.Add(new ConnectionLine(region.X, region.Y, target.X, target.Y)); } } return lines; } }