/// <summary>
        /// Сombine this object with its neighbor. All inland relations from neighbor will be removed.
        /// </summary>
        public void MergeFromInlandNeighbor(IslandPart neighbor)
        {
            // raise height of result island to max from height of two island
            // calculate volume water that will be stored after raise
            if (neighbor.Height > Height)
            {
                VolumeStoreWater += (neighbor.Height - Height) * Square;
                Height            = neighbor.Height;
            }
            else if (neighbor.Height < Height)
            {
                VolumeStoreWater += (Height - neighbor.Height) * neighbor.Square;
            }

            // merge squares
            Square += neighbor.Square;

            // merge outermost neighbors
            if (neighbor.HasOutermostNeighbor)
            {
                AddOutermostNeighbor(neighbor.OutermostNeighborMinHeight);
            }

            // merge inland neighbors
            foreach (var newInlandNeighbor in neighbor.InlandNeighbors)
            {
                if (newInlandNeighbor == this)
                {
                    continue;
                }

                AddInlandNeighbor(newInlandNeighbor);
            }


            while (true)
            {
                var newInlandNeighbor = neighbor.InlandNeighbors.FirstOrDefault();
                if (newInlandNeighbor == null)
                {
                    break;
                }

                // we remove all inland relations from neighbor that we merge from
                // we are tranfer its relations to new merged (combined) object
                // so objects that we merged from will have no inland relations (and other inland parts will not link to it)
                neighbor.RemoveInlandNeighbor(newInlandNeighbor);

                if (newInlandNeighbor == this)
                {
                    continue;
                }

                AddInlandNeighbor(newInlandNeighbor);
            }
        }
Exemplo n.º 2
0
        private List <IslandPart> GetInlandParts()
        {
            var islandHeight = _islandPartHeights.GetLength(0);
            var islandWidth  = _islandPartHeights.GetLength(1);

            var countInlandIslandParts = _islandPartHeights.Length - 2 * (islandWidth + islandHeight - 2);
            var inlandParts            = new List <IslandPart>(countInlandIslandParts);

            for (var i = 1; i < islandHeight - 1; i++)
            {
                for (int j = 1; j < islandWidth - 1; j++)
                {
                    var islandPart = new IslandPart((i * islandWidth + j), _islandPartHeights[i, j], 1);

                    if (i == 1)
                    {
                        // add outermost neighbor from top
                        islandPart.AddOutermostNeighbor(_islandPartHeights[i - 1, j]);
                    }
                    else
                    {
                        // add inland neighbor from top
                        var aboveIslandPartIndex = (i - 2) * (islandWidth - 2) + (j - 1);
                        islandPart.AddInlandNeighbor(inlandParts[aboveIslandPartIndex]);
                    }
                    if (i == islandHeight - 2)
                    {
                        // add outermost neighbor from bottom
                        islandPart.AddOutermostNeighbor(_islandPartHeights[i + 1, j]);
                    }


                    if (j == 1)
                    {
                        // add outermost neighbor from left
                        islandPart.AddOutermostNeighbor(_islandPartHeights[i, j - 1]);
                    }
                    else
                    {
                        // add inland neighbor from left
                        var leftIslandPartIndex = (i - 1) * (islandWidth - 2) + (j - 2);
                        islandPart.AddInlandNeighbor(inlandParts[leftIslandPartIndex]);
                    }
                    if (j == islandWidth - 2)
                    {
                        // add outermost neighbor from right
                        islandPart.AddOutermostNeighbor(_islandPartHeights[i, j + 1]);
                    }

                    inlandParts.Add(islandPart);
                }
            }

            return(inlandParts);
        }
 /// <summary>
 /// Remove two-way neighbor relations between this object and param object.
 /// </summary>
 public void RemoveInlandNeighbor(IslandPart neighbor)
 {
     _inlandNeighbors.Remove(neighbor);
     neighbor._inlandNeighbors.Remove(this);
 }
 /// <summary>
 /// Add two-way neighbor relations between this object and param object.
 /// </summary>
 public void AddInlandNeighbor(IslandPart neighbor)
 {
     _inlandNeighbors.Add(neighbor);
     neighbor._inlandNeighbors.Add(this);
 }