/// <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); } }
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); }