diff --git a/ET/Web/Pages/Simulation.razor b/ET/Web/Pages/Simulation.razor index e59b69f..37d771b 100644 --- a/ET/Web/Pages/Simulation.razor +++ b/ET/Web/Pages/Simulation.razor @@ -1,6 +1,5 @@ @page "/simulation" @inject GameSimulationService SimService -@implements IDisposable Ecology Simulation @@ -213,8 +212,5 @@ else return lines; } - - public void Dispose() - { - } } + diff --git a/ET/Web/Services/GameSimulationService.cs b/ET/Web/Services/GameSimulationService.cs index 2dd3473..dc3b473 100644 --- a/ET/Web/Services/GameSimulationService.cs +++ b/ET/Web/Services/GameSimulationService.cs @@ -165,7 +165,7 @@ public class GameSimulationService } else { - var target = FindBestTravelTarget(region, r => r.PreyMeeples > 0); + var target = FindBestTravelTarget(region, r => r.PreyMeeples); if (target != null) { int traveling = region.PredatorMeeples; @@ -190,7 +190,7 @@ public class GameSimulationService } else { - var target = FindBestTravelTarget(region, r => r.FloraMeeples > 0); + var target = FindBestTravelTarget(region, r => r.FloraMeeples); if (target != null) { int traveling = region.PreyMeeples; @@ -201,33 +201,57 @@ public class GameSimulationService } } - private RegionState? FindBestTravelTarget(RegionState region, Func hasResource) + private RegionState? FindBestTravelTarget(RegionState region, Func resourceCount) { var direct = region.Connections .Select(name => Data.Regions.FirstOrDefault(r => r.Name == name)) .OfType() - .Where(r => hasResource(r)) + .Where(r => resourceCount(r) > 0) .ToList(); if (direct.Count > 0) { - return direct.OrderByDescending(r => r.PreyMeeples + r.FloraMeeples).First(); + return direct.OrderByDescending(r => resourceCount(r)).First(); } + // BFS to find nearest region with resource, return first step along path var visited = new HashSet { region.Name }; - var queue = new Queue(region.Connections); + var prev = new Dictionary(); + var queue = new Queue(); + + foreach (var conn in region.Connections) + { + if (!visited.Contains(conn)) + { + visited.Add(conn); + prev[conn] = region.Name; + queue.Enqueue(conn); + } + } + while (queue.Count > 0) { var currentName = queue.Dequeue(); - if (!visited.Add(currentName)) continue; var current = Data.Regions.FirstOrDefault(r => r.Name == currentName); if (current == null) continue; - if (hasResource(current)) - return current; + + if (resourceCount(current) > 0) + { + // Walk back to find the first step from the origin region + var step = currentName; + while (prev[step] != region.Name) + step = prev[step]; + return Data.Regions.FirstOrDefault(r => r.Name == step); + } + foreach (var conn in current.Connections) { if (!visited.Contains(conn)) + { + visited.Add(conn); + prev[conn] = currentName; queue.Enqueue(conn); + } } }