예제 #1
0
        private bool IsWaterLevelStableAt(XY waterLocation, WaterStream stream)
        {
            var waterInASameLevel = stream.EnumerateWaterInSameLavel(waterLocation).ToArray();

            if (waterInASameLevel.Any(w => w.IsStable))
            {
                return(true);
            }

            var waterCanFlowFurther = waterInASameLevel.Any(w => HasEmptySpaceAround(w, stream));

            if (waterCanFlowFurther)
            {
                return(false);
            }

            var waterInLowerLevel = waterInASameLevel
                                    .SelectMany(w => w.FurtherFlows)
                                    .Select(w => w.Location)
                                    .Where(l => l.Y < waterLocation.Y)
                                    .ToArray();

            if (waterInLowerLevel.Length == 0)
            {
                return(true);
            }

            return(waterInLowerLevel.All(l => IsWaterLevelStableAt(l, stream)));
        }
예제 #2
0
        public WaterStream GetStream()
        {
            var stream             = new WaterStream(sourceLocation);
            var waterNodesToSpread = stream.Select(w => w.Location).ToHashSet();

            do
            {
                var locationsToContinueSpreadingAt = new HashSet <XY>();

                foreach (var waterLocation in waterNodesToSpread)
                {
                    // Todo Refactor
                    var spreadedWater          = stream.SpreadStreamAtLocation(waterLocation, clayMap);
                    var waterLocationInClayMap = spreadedWater.Select(w => w.Location).Where(l => !clayMap.IsBelowMap(l));

                    locationsToContinueSpreadingAt.AddRange(waterLocationInClayMap);

                    if (spreadedWater.Length == 0 && IsWaterLevelStableAt(waterLocation, stream))
                    {
                        var upperLevelWaterLocations = stream.GetUpperLevelSourceWater(waterLocation).Select(w => w.Location);
                        stream.StabilizeWaterInSameLevel(waterLocation);

                        locationsToContinueSpreadingAt.AddRange(upperLevelWaterLocations);
                    }
                }

                waterNodesToSpread = locationsToContinueSpreadingAt;
            } while (waterNodesToSpread.Count > 0);

            return(stream);
        }
예제 #3
0
 private bool IsLocationEmpty(XY location, WaterStream stream)
 {
     return(!clayMap.IsClayAtLocation(location) && !stream.HasWaterAtLocation(location));
 }
예제 #4
0
 private bool HasEmptySpaceAround(Water water, WaterStream stream)
 {
     return(Water.GetPossibleFlowDirections()
            .Select(d => water.Location + d)
            .Any(l => IsLocationEmpty(l, stream)));
 }