private LandblockGroup DoTrySplit() { var newLandblockGroup = new LandblockGroup(); var remainingLandblocks = new List <Landblock>(landblocks); newLandblockGroup.Add(remainingLandblocks[remainingLandblocks.Count - 1]); remainingLandblocks.RemoveAt(remainingLandblocks.Count - 1); doAnotherPass: bool needsAnotherPass = false; for (int i = remainingLandblocks.Count - 1; i >= 0; i--) { if (newLandblockGroup.BoundaryDistance(remainingLandblocks[i]) < LandblockGroupMinSpacing) { newLandblockGroup.Add(remainingLandblocks[i]); remainingLandblocks.RemoveAt(i); needsAnotherPass = true; } } if (needsAnotherPass) { goto doAnotherPass; } // If they're the same size, there's no split possible if (Count == newLandblockGroup.Count) { return(null); } // Remove the split landblocks. Do this manually, not through the public Remove() function foreach (var landblock in newLandblockGroup) { landblocks.Remove(landblock); } RecalculateBoundaries(); // This can result in returning groups that overlap this ones boundary. // However, that isn't a problem for processing them on separate threads. // In the event a new landblock is added that is within range of both this block and any new block, they will be recombined at that point. return(newLandblockGroup); }