예제 #1
0
        /// <summary>
        /// Detects pyramid or hole (if any) at the given coordinates in the <see cref="Grid" />, and randomly switch
        /// between pyramid and hole, based on <see cref="_probabilityP" /> and <see cref="_probabilityQ" /> parameters.
        /// </summary>
        /// <param name="p">
        /// contains the coordinates where the function looks if there is a pyramid or hole in the <see cref="Grid" />.
        /// </param>
        private void RandomlySwitchFourCells(KpzNode[,] grid, KpzCoords p)
        {
            var  neighbours   = GetNeighbours(grid, p);
            var  currentPoint = grid[p.x, p.y];
            bool changedGrid  = false;

            // We check our own {dx,dy} values, and the right neighbour's dx, and bottom neighbour's dx.
            if (
                // If we get the pattern {01, 01} we have a pyramid:
                ((currentPoint.dx && !neighbours.nx.dx) && (currentPoint.dy && !neighbours.ny.dy) &&
                 (_random.NextDouble() < _probabilityP)) ||
                // If we get the pattern {10, 10} we have a hole:
                ((!currentPoint.dx && neighbours.nx.dx) && (!currentPoint.dy && neighbours.ny.dy) &&
                 (_random.NextDouble() < _probabilityQ))
                )
            {
                // We make a hole into a pyramid, and a pyramid into a hole.
                currentPoint.dx  = !currentPoint.dx;
                currentPoint.dy  = !currentPoint.dy;
                neighbours.nx.dx = !neighbours.nx.dx;
                neighbours.ny.dy = !neighbours.ny.dy;
                changedGrid      = true;
            }

            if (_enableStateLogger)
            {
                StateLogger.AddKpzAction("RandomlySwitchFourCells", grid, p, neighbours, changedGrid);
            }
        }
예제 #2
0
        /// <summary>
        /// Runs an iteration of the KPZ algorithm (with <see cref="GridWidth"/> × <see cref="GridHeight"/> steps).
        /// </summary>
        public void DoIteration()
        {
            var numberOfStepsInIteration = GridWidth * GridHeight;

            if (_enableStateLogger)
            {
                StateLogger.NewKpzIteration();
            }

            for (int i = 0; i < numberOfStepsInIteration; i++)
            {
                // We randomly choose a point on the grid.
                // If there is a pyramid or hole, we randomly switch them.
                var randomPoint = new KpzCoords {
                    x = _random.Next(0, GridWidth), y = _random.Next(0, GridHeight)
                };
                RandomlySwitchFourCells(Grid, randomPoint);
            }
        }
예제 #3
0
        /// <summary>
        /// Gets the right and bottom neighbours of the point given with the coordinates <see cref="p" />
        /// in the <see cref="Grid" />.
        /// </summary>
        private KpzNeighbours GetNeighbours(KpzNode[,] grid, KpzCoords p)
        {
            KpzNeighbours toReturn;

            toReturn.nxCoords = new KpzCoords
            {
                x = (p.x < GridWidth - 1) ? p.x + 1 : 0,
                y = p.y
            };

            toReturn.nyCoords = new KpzCoords
            {
                x = p.x,
                y = (p.y < GridHeight - 1) ? p.y + 1 : 0
            };

            toReturn.nx = grid[toReturn.nxCoords.x, toReturn.nxCoords.y];
            toReturn.ny = grid[toReturn.nyCoords.x, toReturn.nyCoords.y];

            return(toReturn);
        }
예제 #4
0
        /// <summary>
        /// Adds a deep copy of the grid into the current <see cref="KpzStateLogger" /> iteration, with cells
        /// to highlight (<see cref="Center" /> and <see cref="Neighbours" />). If the values in the grid were updated,
        /// they are highlighted with a green color, else they are highlighted with a red color, based on the parameter
        /// value of <see cref="ChangedGrid" />.
        /// </summary>
        public void AddKpzAction(string Description, KpzNode[,] Grid, KpzCoords Center,
                                 KpzNeighbours Neighbours, bool ChangedGrid)
        {
            var highlightedCoords = new List <KpzCoords>();

            highlightedCoords.Add(new KpzCoords {
                x = Center.x, y = Center.y
            });
            highlightedCoords.Add(new KpzCoords {
                x = Neighbours.nxCoords.x, y = Neighbours.nxCoords.y
            });
            highlightedCoords.Add(new KpzCoords {
                x = Neighbours.nyCoords.x, y = Neighbours.nyCoords.y
            });

            Iterations[Iterations.Count - 1].Actions.Add(new KpzAction
            {
                Description       = Description,
                Grid              = CopyOfGrid(Grid),
                HeightMap         = new int[0, 0],
                HightlightColor   = (ChangedGrid) ? Color.LightGreen : Color.Salmon, // green or red
                HighlightedCoords = highlightedCoords
            });
        }