Example #1
0
        /// <summary>
        /// The return type is a bit conf
        /// </summary>
        /// <param name="column"></param>
        private static bool ApplyGravity(SandColumn column)
        {
            var sandMoved = false;
            var noPressureLowerNeighbours = new Queue <SandColumn>();

            Shuffle(column.Neighbours);
            foreach (var neighbour in column.Neighbours)
            {
                noPressureLowerNeighbours.Enqueue(neighbour);
            }

            while (noPressureLowerNeighbours.Count > 0)
            {
                var neighbour = noPressureLowerNeighbours.Dequeue();

                if (neighbour.Height + 1 < column.Height && neighbour.NumExcessRoom > 0)
                {
                    MoveSand(column, neighbour);
                    sandMoved = true;
                    if (neighbour.Height + 1 < column.Height && neighbour.NumExcessRoom > 0)
                    {
                        noPressureLowerNeighbours.Enqueue(neighbour);
                    }
                }
            }

            return(sandMoved);
        }
Example #2
0
        public static SandColumn[,] CreateSandTable(int height, int width, int defaultSandHeight, int defaultHeightLimit = int.MaxValue)
        {
            var sand = new SandColumn[width, height];

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    sand[x, y] = new SandColumn
                    {
                        HeightLimit = defaultHeightLimit,
                        Height      = defaultSandHeight,
                        Location    = new Point {
                            X = x, Y = y
                        }
                    };
                }
            }

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    sand[x, y].Neighbours = GetNeighbours(sand, new Point {
                        X = x, Y = y
                    });
                    Shuffle(sand[x, y].Neighbours);
                }
            }

            return(sand);
        }
Example #3
0
        private static bool SettleColumn(SandColumn column)
        {
            var columnChangedOnce = false;  //if the column changed at all

            bool columnChanged;             //if the column changed in this iteration

            do
            {
                columnChanged = false;

                var lowerPressureNeighbours            = new List <SandColumn>();
                var equalPressureLowerHeightNeighbours = new List <SandColumn>();

                foreach (var neighbour in column.Neighbours)
                {
                    if (column.Pressure > 0 && column.DecreasedPressure >= neighbour.IncreasedPressure)
                    {
                        lowerPressureNeighbours.Add(neighbour);
                    }
                    else if (column.Pressure <= 0 && neighbour.Pressure <= 0 && column.DecreasedHeight >= neighbour.IncreasedHeight)
                    {
                        equalPressureLowerHeightNeighbours.Add(neighbour);
                    }
                }

                if (lowerPressureNeighbours.Count > 0)
                {
                    var lowestPressure = lowerPressureNeighbours.Min(n => n.IncreasedPressure);
                    lowerPressureNeighbours.RemoveAll(n => n.Pressure > lowestPressure);

                    SandColumn chosenNeighbour = lowerPressureNeighbours[Rnd.Next(lowerPressureNeighbours.Count)];

                    MoveSand(column, chosenNeighbour);
                    columnChanged = true;
                }
                else if (equalPressureLowerHeightNeighbours.Count > 0)
                {
                    MoveSand(column, equalPressureLowerHeightNeighbours[Rnd.Next(equalPressureLowerHeightNeighbours.Count)]);
                    columnChanged = true;
                }

                columnChangedOnce = columnChanged || columnChangedOnce;
            } while (columnChanged);

            return(columnChangedOnce);
        }
Example #4
0
        private static bool SettlePressuredSand(SandColumn column)
        {
            //This is a basic breadth first search using a queue
            if (column.Pressure <= 0)
            {
                return(false);
            }

            var sandMoved         = false;
            var neighbourQueue    = new Queue <SandColumn>();
            var visitedNeighbours = new HashSet <SandColumn>();

            neighbourQueue.Enqueue(column);
            while (column.Pressure > 0)
            {
                var currentNeighbour = neighbourQueue.Dequeue();

                visitedNeighbours.Add(currentNeighbour);
                var emptySpace = currentNeighbour.NumExcessRoom;
                if (emptySpace > 0)
                {
                    MoveSand(column, currentNeighbour, Math.Min(column.NumExcessSand, emptySpace));
                    sandMoved = true;
                }

                foreach (var currentNeighbourNeighbour in currentNeighbour.Neighbours)
                {
                    if (!visitedNeighbours.Contains(currentNeighbourNeighbour))
                    {
                        neighbourQueue.Enqueue(currentNeighbourNeighbour);
                    }
                }
            }

            return(sandMoved);
        }
Example #5
0
 private static void MoveSand(SandColumn source, SandColumn dest, int amount = 1)
 {
     source.Height -= amount;
     dest.Height   += amount;
 }