private void UpdateBoundariesEnergy(Scope baseScope, Scope energyScope) { for (int i = 2; i < baseScope.Width - 2; i++) { for (int j = 2; j < baseScope.Height - 2; j++) { if (((baseScope.StructureArray[i, j].Id != baseScope.StructureArray[i + 1, j].Id && !StructureHelpers.IsIdSpecial(baseScope.StructureArray[i + 1, j].Id)) || (baseScope.StructureArray[i, j].Id != baseScope.StructureArray[i - 1, j].Id && !StructureHelpers.IsIdSpecial(baseScope.StructureArray[i - 1, j].Id))) && !StructureHelpers.IsIdSpecial(baseScope.StructureArray[i, j].Id)) { energyScope.StructureArray[i, j].Color = ChooseColor(properties.BoundaryEnergy.Value); energyScope.StructureArray[i, j].Energy = properties.BoundaryEnergy.Value; } if (((baseScope.StructureArray[i, j].Id != baseScope.StructureArray[i, j + 1].Id && !StructureHelpers.IsIdSpecial(baseScope.StructureArray[i, j + 1].Id)) || (baseScope.StructureArray[i, j].Id != baseScope.StructureArray[i, j - 1].Id && !StructureHelpers.IsIdSpecial(baseScope.StructureArray[i, j - 1].Id))) && !StructureHelpers.IsIdSpecial(baseScope.StructureArray[i, j].Id)) { energyScope.StructureArray[i, j].Color = ChooseColor(properties.BoundaryEnergy.Value); energyScope.StructureArray[i, j].Energy = properties.BoundaryEnergy.Value; } } } }
private bool CanGrainChangeState(int i, int j, Grain[,] structureArray, List <int> remainingIds) { var neighbourhood = StructureHelpers.TakeMooreNeighbourhood(i, j, structureArray); IEnumerable <IGrouping <int, Grain> > groups = null; if (remainingIds != null && remainingIds.Count() > 0) { groups = neighbourhood .Where(g => (!StructureHelpers.IsIdSpecial(g.Id)) && !remainingIds.Any(id => id.Equals(g.Id) && g.Id == structureArray[i, j].Id)) .GroupBy(g => g.Id); } else { groups = neighbourhood.Where(g => (!StructureHelpers.IsIdSpecial(g.Id) && g.Id == structureArray[i, j].Id)).GroupBy(g => g.Id); } if (groups.Any()) { var dictionary = new Dictionary <Grain, int>(); foreach (var group in groups) { var number = group.Key; var total = group.Count(); dictionary.Add(group.FirstOrDefault(), total); } var orderedNeighbourhood = dictionary.OrderByDescending(x => x.Value); if (orderedNeighbourhood.First().Value < 5) { return(true); } return(false); } else { return(true); } }
public Scope Grow(Scope previousStructure, NeighbourhoodType neighbourhoodType, int?growthProbability, List <int> remainingIds = null) { var currentStructure = new Scope(previousStructure.Width, previousStructure.Height); StructureHelpers.AddBlackBorder(currentStructure); var isFull = true; var isGrowthExtended = neighbourhoodType == NeighbourhoodType.ExtendedMoore ? true : false; List <Grain> neighbourhood = new List <Grain>(); for (int i = 1; i < previousStructure.Width - 1; i++) { for (int j = 1; j < previousStructure.Height - 1; j++) { if (previousStructure.StructureArray[i, j].Id != 0) { currentStructure.StructureArray[i, j] = previousStructure.StructureArray[i, j]; } else if (previousStructure.StructureArray[i, j].Id == 0) { if (!isGrowthExtended) { switch (neighbourhoodType) { case NeighbourhoodType.Moore: neighbourhood = TakeMooreNeighbourhood(i, j, previousStructure.StructureArray); break; case NeighbourhoodType.Neumann: neighbourhood = TakeNeumannNeighbourhood(i, j, previousStructure.StructureArray); break; } IEnumerable <IGrouping <int, Grain> > groups = null; if (remainingIds != null && remainingIds.Count() > 0) { groups = neighbourhood .Where(g => (!StructureHelpers.IsIdSpecial(g.Id)) && !remainingIds.Any(id => id.Equals(g.Id))) .GroupBy(g => g.Id); } else { groups = neighbourhood .Where(g => (!StructureHelpers.IsIdSpecial(g.Id))).GroupBy(g => g.Id); } if (groups.Any()) { var dictionary = new Dictionary <Grain, int>(); foreach (var group in groups) { var number = group.Key; var total = group.Count(); dictionary.Add(group.FirstOrDefault(), total); } var orderedNeighbourhood = dictionary.OrderByDescending(x => x.Value); currentStructure.StructureArray[i, j] = orderedNeighbourhood.First().Key; } else { currentStructure.StructureArray[i, j] = new Grain() { Id = 0, Color = Color.White }; } } else { var grainGrowth = false; var dictionary = new Dictionary <Grain, int>(); // rule 1 neighbourhood = TakeMooreNeighbourhood(i, j, previousStructure.StructureArray); IEnumerable <IGrouping <int, Grain> > groups = null; if (remainingIds != null && remainingIds.Count() > 0) { groups = neighbourhood .Where(g => (!StructureHelpers.IsIdSpecial(g.Id)) && !remainingIds.Any(id => id.Equals(g.Id))) .GroupBy(g => g.Id); } else { groups = neighbourhood .Where(g => (!StructureHelpers.IsIdSpecial(g.Id))).GroupBy(g => g.Id); } if (groups.Any()) { foreach (var group in groups) { var number = group.Key; var total = group.Count(); dictionary.Add(group.FirstOrDefault(), total); } var orderedNeighbourhood = dictionary.OrderByDescending(x => x.Value); if (orderedNeighbourhood.First().Value >= 5) { currentStructure.StructureArray[i, j] = orderedNeighbourhood.First().Key; grainGrowth = true; } else { // rule 2 neighbourhood = TakeNearestMooreNeighbourhood(i, j, previousStructure.StructureArray); if (remainingIds != null && remainingIds.Count() > 0) { groups = neighbourhood .Where(g => (!StructureHelpers.IsIdSpecial(g.Id)) && !remainingIds.Any(id => id.Equals(g.Id))) .GroupBy(g => g.Id); } else { groups = neighbourhood .Where(g => (!StructureHelpers.IsIdSpecial(g.Id))).GroupBy(g => g.Id); } if (groups.Any()) { orderedNeighbourhood = dictionary.OrderByDescending(x => x.Value); if (orderedNeighbourhood.First().Value >= 3) { currentStructure.StructureArray[i, j] = orderedNeighbourhood.First().Key; grainGrowth = true; } } if (!grainGrowth) { // rule 3 neighbourhood = TakeFurtherMooreNeighbourhood(i, j, previousStructure.StructureArray); if (remainingIds != null && remainingIds.Count() > 0) { groups = neighbourhood .Where(g => (!StructureHelpers.IsIdSpecial(g.Id)) && !remainingIds.Any(id => id.Equals(g.Id))) .GroupBy(g => g.Id); } else { groups = neighbourhood .Where(g => (!StructureHelpers.IsIdSpecial(g.Id))).GroupBy(g => g.Id); } if (groups.Any()) { orderedNeighbourhood = dictionary.OrderByDescending(x => x.Value); if (orderedNeighbourhood.First().Value >= 3) { currentStructure.StructureArray[i, j] = orderedNeighbourhood.First().Key; grainGrowth = true; } } } if (!grainGrowth) { // rule 4 - Moore with probability neighbourhood = TakeMooreNeighbourhood(i, j, previousStructure.StructureArray); if (remainingIds != null && remainingIds.Count() > 0) { groups = neighbourhood .Where(g => (!StructureHelpers.IsIdSpecial(g.Id)) && !remainingIds.Any(id => id.Equals(g.Id))) .GroupBy(g => g.Id); } else { groups = neighbourhood .Where(g => (!StructureHelpers.IsIdSpecial(g.Id))).GroupBy(g => g.Id); } var randomProbability = random.Next(0, 100); if (groups.Any() && (randomProbability <= growthProbability)) { orderedNeighbourhood = dictionary.OrderByDescending(x => x.Value); currentStructure.StructureArray[i, j] = orderedNeighbourhood.First().Key; grainGrowth = true; } } } } if (!grainGrowth) { // no grain yet currentStructure.StructureArray[i, j] = new Grain() { Id = 0, Color = Color.White }; } } } if (currentStructure.StructureArray[i, j].Id == 0) { isFull = false; } } } currentStructure.IsFull = isFull; StructureHelpers.UpdateBitmap(currentStructure); return(currentStructure); }