private void Subdivide(District district, int depth, int borderLeft, int borderTop, int borderRight, int borderBottom, Random rand) { int width = district.Width - borderLeft - borderRight; int height = district.Height - borderTop - borderBottom; if (BlockGenerator.WillAnyFit(width, height)) { BlockGenerator gen = BlockGenerator.GetRandom(width, height, rand); if (depth > 3 && rand.Next(width * height) == 0) { district.SetBlock(gen.Generate(district, borderLeft, borderTop, borderRight, borderBottom, rand)); return; } } int nextBorder = depth < 4 ? 3 : depth < 6 ? 2 : 1; int minHorz = 0; double fitHorz = 0.0; int minVert = 0; double fitVert = 0.0; while ((minHorz + nextBorder) * 2 + borderTop + borderBottom <= district.Height && (fitHorz = BlockGenerator.FitnessScore(district.Width - borderLeft - borderRight, minHorz)) == 0.0) ++minHorz; while ((minVert + nextBorder) * 2 + borderLeft + borderRight <= district.Width && (fitVert = BlockGenerator.FitnessScore(minVert, district.Height - borderTop - borderBottom)) == 0.0) ++minVert; bool horz = fitHorz > 0.0 && (fitVert == 0.0 || fitHorz > fitVert || (fitHorz == fitVert && rand.NextDouble() > 0.5)); if (horz) { int min = borderTop + nextBorder + minHorz; int max = district.Height - borderBottom - minHorz - nextBorder; int mid = (min + max) / 2; district.Split(true, rand.Next((min + mid) / 2, (mid + max) / 2)); Subdivide(district.ChildA, depth + 1, borderLeft, borderTop, borderRight, nextBorder, rand); Subdivide(district.ChildB, depth + 1, borderLeft, nextBorder, borderRight, borderBottom, rand); } else if (fitVert > 0.0) { int min = minVert + borderLeft + nextBorder; int max = district.Width - borderRight - minVert - nextBorder; int mid = (min + max) / 2; district.Split(false, rand.Next((min + mid) / 2, (mid + max) / 2)); Subdivide(district.ChildA, depth + 1, borderLeft, borderTop, nextBorder, borderBottom, rand); Subdivide(district.ChildB, depth + 1, nextBorder, borderTop, borderRight, borderBottom, rand); } else { BlockGenerator gen = BlockGenerator.GetRandom(width, height, rand); district.SetBlock(gen.Generate(district, borderLeft, borderTop, borderRight, borderBottom, rand)); } }