Пример #1
0
        /// <summary>
        /// The StartFireAtPoint method is called to start a fire at a specific point in the forest.
        /// </summary>
        /// <param name="point"></param>
        /// <param name="forestWidthPixels"></param>
        /// <param name="forestHeightPixels"></param>
        public void StartFireAtPoint(Point point, double forestWidthPixels, double forestHeightPixels)
        {
            try
            {
                if (point != null && forestWidthPixels > 0 && forestHeightPixels > 0)
                {
                    // Retrieve the x/y coordinates in pixels.
                    double xPositionPixels = point.X;
                    double yPositionPixels = point.Y;

                    // Convert the x/y coordinates from pixels to cells.
                    int xPosition = (int)((xPositionPixels / forestWidthPixels) * Constants.ForestWidth);
                    int yPosition = (int)((yPositionPixels / forestHeightPixels) * Constants.ForestHeight);

                    // Determine the cell index from the x/y coordinates.
                    int cellIndex = xPosition + (yPosition * Constants.ForestWidth);

                    // Retrieve the forest cell and set it to burning.
                    if (IsCellIndexValid(cellIndex))
                    {
                        ForestCell forestCell = _forestCells.ElementAt(cellIndex);
                        if (forestCell.CellState == CellState.Tree)
                        {
                            forestCell.CellState = CellState.Burning;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Forest.StartFireAtPoint(Point point, double forestWidthPixels, double forestHeightPixels): " + ex.ToString());
            }
        }
Пример #2
0
        /// <summary>
        /// Create a forest cell from an existing forest cell.
        /// </summary>
        /// <param name="forestCell"></param>
        public ForestCell(ForestCell forestCell)
        {
            try
            {
                if (forestCell == null)
                {
                    throw new Exception("forestCell can not be null");
                }

                _cellState = forestCell.CellState;
            }
            catch (Exception ex)
            {
                throw new Exception("ForestCell(ForestCell forestCell): " + ex.ToString());
            }
        }
Пример #3
0
        /// <summary>
        /// The UpdateForest method is called to update the forest.
        /// An empty cell may become a tree cell, as per the regrowth probability.
        /// A burning cell becomes an empty cell.
        /// A tree cell becomes a burning cell, if any of its neighbours are burning.
        /// A tree cell may become a burning cell, even with no burning neighbours, as per the lightning probability.
        /// </summary>
        private async Task UpdateForest()
        {
            try
            {
                await Task.Run(() =>
                {
                    lock (_updateLock)
                    {
                        ObservableCollection <ForestCell> updatedForest = new ObservableCollection <ForestCell>();    // The updated forest.

                        // Update the forest cells, one cell at a time.
                        foreach (ForestCell forestCell in _forestCells)
                        {
                            ForestCell updatedForestCell = new ForestCell(forestCell);  // Make a copy of the current forest cell.

                            // Update the forest cell.
                            if (forestCell.CellState == CellState.Empty)
                            {
                                // If the cell is empty, apply regrowth.
                                updatedForestCell.CellState = ApplyRegrowth() ? CellState.Tree : updatedForestCell.CellState;
                            }
                            else if (forestCell.CellState == CellState.Tree)
                            {
                                // If the cell is a tree, check for any burning neighbours.

                                int cellIndex = _forestCells.IndexOf(forestCell);   // Retrieve the index of the tree cell.

                                // Determine the indexes for all of the neighbours.
                                int topNeighbourIndex         = cellIndex - Constants.ForestWidth;
                                int topRightNeighbourIndex    = cellIndex - Constants.ForestWidth + 1;
                                int rightNeighbourIndex       = cellIndex + 1;
                                int bottomRightNeighbourIndex = cellIndex + Constants.ForestWidth + 1;
                                int bottomNeighbourIndex      = cellIndex + Constants.ForestWidth;
                                int bottomLeftNeighbourIndex  = cellIndex + Constants.ForestWidth - 1;
                                int leftNeighbourIndex        = cellIndex - 1;
                                int topLeftNeighbourIndex     = cellIndex - Constants.ForestWidth - 1;

                                // Determine if the cell is on the top/right/bottom/left edge of the forest - certain neighbours must be ignored if a cell is on an edge.
                                bool topEdge    = cellIndex < Constants.ForestWidth ? true : false;
                                bool rightEdge  = ((cellIndex + 1) % Constants.ForestWidth) == 0 ? true : false;
                                bool leftEdge   = (cellIndex % Constants.ForestWidth) == 0 ? true : false;
                                bool bottomEdge = (cellIndex + Constants.ForestWidth) >= (Constants.ForestWidth *Constants.ForestHeight) ? true : false;

                                // Check each neighbour.
                                if (!topEdge && updatedForestCell.CellState != CellState.Burning && IsCellBurning(topNeighbourIndex))
                                {
                                    updatedForestCell.CellState = CellState.Burning;
                                }
                                if (!rightEdge && updatedForestCell.CellState != CellState.Burning && IsCellBurning(topRightNeighbourIndex))
                                {
                                    updatedForestCell.CellState = CellState.Burning;
                                }
                                if (!rightEdge && updatedForestCell.CellState != CellState.Burning && IsCellBurning(rightNeighbourIndex))
                                {
                                    updatedForestCell.CellState = CellState.Burning;
                                }
                                if (!rightEdge && updatedForestCell.CellState != CellState.Burning && IsCellBurning(bottomRightNeighbourIndex))
                                {
                                    updatedForestCell.CellState = CellState.Burning;
                                }
                                if (!bottomEdge && updatedForestCell.CellState != CellState.Burning && IsCellBurning(bottomNeighbourIndex))
                                {
                                    updatedForestCell.CellState = CellState.Burning;
                                }
                                if (!leftEdge && updatedForestCell.CellState != CellState.Burning && IsCellBurning(bottomLeftNeighbourIndex))
                                {
                                    updatedForestCell.CellState = CellState.Burning;
                                }
                                if (!leftEdge && updatedForestCell.CellState != CellState.Burning && IsCellBurning(leftNeighbourIndex))
                                {
                                    updatedForestCell.CellState = CellState.Burning;
                                }
                                if (!leftEdge && updatedForestCell.CellState != CellState.Burning && IsCellBurning(topLeftNeighbourIndex))
                                {
                                    updatedForestCell.CellState = CellState.Burning;
                                }

                                // If the cell is still a tree, apply a lighting strike.
                                if (updatedForestCell.CellState == CellState.Tree)
                                {
                                    updatedForestCell.CellState = ApplyLightningStrike() ? CellState.Burning : updatedForestCell.CellState;
                                }
                            }
                            else if (forestCell.CellState == CellState.Burning)
                            {
                                // If the cell is burning, it becomes an empty cell.
                                updatedForestCell.CellState = CellState.Empty;
                            }

                            updatedForest.Add(updatedForestCell);   // Add the updated forest cell to the updated forest.
                        }

                        // Update the forest.
                        if (updatedForest.Count == _forestCells.Count)
                        {
                            foreach (ForestCell forestCell in _forestCells)
                            {
                                CellState updatedCellState = updatedForest.ElementAt(_forestCells.IndexOf(forestCell)).CellState;
                                if (updatedCellState != forestCell.CellState)
                                {
                                    forestCell.CellState = updatedCellState;
                                }
                            }
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                throw new Exception("Forest.UpdateForest(): " + ex.ToString());
            }
        }