private void HandleAdjacentNodesAfterNodeRemoval(List <ElectricNetworkNode> adjacentNodes) { // Check if there is only one network in the involved nodes. If there is more than one, something went horribly wrong. ElectricNetwork[] differentNetworksInvolved = ElectricNetworkUtil.GetDifferentNetworksOf(adjacentNodes.ToArray()); if (differentNetworksInvolved.Length > 1) { Debug.LogError($"ERROR REMOVING NODE: The adjacent nodes of the removed node should all have the same network " + $"(network count = 1), but there are {differentNetworksInvolved.Length} different networks. "); } // Case 1: There are no adjacent nodes on removal if (adjacentNodes == null || adjacentNodes.Count == 0) { return; } // Case 2: There is only one adjacent node on removal; no changes to network if (adjacentNodes.Count == 1) { return; } // Case 3: There are at least two adjacent nodes; what happens with the network is ambiguous --> NetworkResolver HandleNetworkResolving(adjacentNodes); // Case 4: (Special case) There are at least two adjacent nodes and all are connected with each other on removal. // This case is not handled here, because it also gets resolved by the NetworkResolver. }
/* * You should not call this method directly. Instead, call HandleAdjacentNodesAfterNodeRemoval() */ private void HandleNetworkResolving(List <ElectricNetworkNode> nodesToBeResolved) { NetworkResolver networkResolver = new NetworkResolver(); networkResolver.ResolveNetworks(nodesToBeResolved); List <ElectricNetworkSeed> resolvedNetworkSeeds = networkResolver.resolvedNetworkSeeds; // If only one ElectricNetworkSeed gets returned, it means that the network doesn't break up. Just one node gets removed. if (resolvedNetworkSeeds.Count == 1) { return; } // Because all former nodes and edges now are reassigned in resolved network seeds, it is save to wipe all // content from the network before removal (unregister all nodes and edges). ElectricNetwork networkBeforeRemoval = nodesToBeResolved[0].connectedNetwork; ElectricNetworkUtil.RemoveNetworkContent(networkBeforeRemoval); // Reassign the biggest networkSeed to the network before the removal ElectricNetworkUtil.SortBySize(resolvedNetworkSeeds); ElectricNetworkSeed biggestNetworkSeed = resolvedNetworkSeeds[0]; ElectricNetworkUtil.AddNetworkContent(networkBeforeRemoval, biggestNetworkSeed); Debug.Log($"INFO: There are {biggestNetworkSeed.nodes.Count} nodes in the biggest network after removing a node. "); resolvedNetworkSeeds.Remove(biggestNetworkSeed); // For every other networkSeed: Create a new network and populate it with the contents of the networkSeed foreach (ElectricNetworkSeed networkSeed in resolvedNetworkSeeds) { ElectricNetwork electricNetwork = CreateNewElectricNetwork(); networkSeed.nodes.ForEach(node => ElectricNetworkUtil.Register(electricNetwork, node)); networkSeed.edges.ForEach(edge => ElectricNetworkUtil.Register(electricNetwork, edge)); } }
private void HandleCreationOfASingleNewNetwork(ElectricNetworkNode addedNode, List <ElectricNetworkNode> adjacentNodes) { // Check if adjacentNodes all have no network; // If they do, another method about handling addon to network(s) should be called. foreach (ElectricNetworkNode adjacentNode in adjacentNodes) { if (adjacentNode.connectedNetwork != null) { Debug.LogError($"ERROR CREATING NODE: Node {addedNode} should be only one with network, " + $"but Node {adjacentNode} already has network {adjacentNode.connectedNetwork}. "); return; } } ElectricNetwork network = CreateNewElectricNetwork(); ElectricNetworkUtil.Register(network, addedNode); Debug.Log($"INFO CREATING NODE: Node {addedNode} was created with network {network}. "); if (adjacentNodes != null && adjacentNodes.Count > 0) { foreach (ElectricNetworkNode adjacentNode in adjacentNodes) { ElectricNetworkUtil.Register(network, adjacentNode); Debug.Log($"INFO REGISTERING: Node {adjacentNode} was added to network {network}. "); } } SortElectricNetworks(); }
private void HandleAddonToAnExistingNetwork(ElectricNetworkNode addedNode, List <ElectricNetworkNode> adjacentNodes) { ElectricNetwork network = adjacentNodes[0].connectedNetwork; ElectricNetworkUtil.Register(network, addedNode); SortElectricNetworks(); Debug.Log($"INFO: Node {addedNode} was added to network {network}. "); }
/* * This method should not be called each Update, rather only on changes. */ public void AddPreviewNode(ElectricNetworkNode previewNode, List <ElectricNetworkNode> interactedNodes) { foreach (ElectricNetworkNode interactedNode in interactedNodes) { ElectricNetworkUtil.ConnectPreview(previewNode, interactedNode, previewNetwork); } CreateCablesForNetwork(previewNetwork); }
/* * There are actually two lists with traveresed nodes in this NetworkResolver: * 1) traversedNodes represents all nodes that have been passed through the traversal * 2) nodesInThisNetwork represents a subset of all traversed nodes, namely only those that are connected with each other (--> network) */ private ElectricNetworkSeed TraverseNodesInQueueAndResolveAsNetwork(Queue <ElectricNetworkNode> nodeQueue) { List <ElectricNetworkNode> nodesInThisNetwork = new List <ElectricNetworkNode>(); List <ElectricNetworkEdge> edgesInThisNetwork = new List <ElectricNetworkEdge>(); ElectricNetworkSeed resolvedNetworkSeed = new ElectricNetworkSeed(); while (nodeQueue.Count > 0) { ElectricNetworkNode nodeOnTop = nodeQueue.Peek(); // Add each connected node to the network (plus the corresponding edge) foreach (ElectricNetworkNode connectedNode in nodeOnTop.connectedNodes) { // If the resolver already visited this node, continue if (traversedNodes.Contains(connectedNode)) { continue; } // Add connected Node to queue nodeQueue.Enqueue(connectedNode); // Add node to traversed nodes (as soon as they are in queue, they count as traversed/visited) traversedNodes.Add(connectedNode); // Get edge between two nodes ElectricNetworkEdge commonEdge = ElectricNetworkUtil.GetCommonEdge(nodeOnTop, connectedNode); if (commonEdge == null) { Debug.LogError($"ERROR RESOLVING NETWORKS: " + $"There is no common edge between Node 1 {nodeOnTop} and Node 2 {connectedNode}. "); } edgesInThisNetwork.Add(commonEdge); } // Add traversed node to all 1) visited nodes and 2) nodes for network traversedNodes.Add(nodeOnTop); nodesInThisNetwork.Add(nodeOnTop); // Remove top node from queue nodeQueue.Dequeue(); } // Return resolved network resolvedNetworkSeed.nodes = nodesInThisNetwork; resolvedNetworkSeed.edges = edgesInThisNetwork; return(resolvedNetworkSeed); }
public void AddNode(ElectricNetworkNode addedNode, List <ElectricNetworkNode> interactedNodes) { int numberOfInvolvedNetworksInConnectionAttempt = ElectricNetworkUtil.GetDifferentNetworksOf(interactedNodes.ToArray()).Length; // Debug info if (GameManager.Instance.isDebugging) { for (int i = 0; i < interactedNodes.Count(); i++) { Debug.Log($"INFO NETWORK ADDON: Interacted Node {i}: {interactedNodes[i]}. "); } } // Handle addon to network if (numberOfInvolvedNetworksInConnectionAttempt == 0) { // Interacted Nodes are passed as parameter, because there can be a connection attempt with // interacted/adjacent nodes, that have connectedNetwork = null. HandleCreationOfASingleNewNetwork(addedNode, interactedNodes); } else if (numberOfInvolvedNetworksInConnectionAttempt == 1) { HandleAddonToAnExistingNetwork(addedNode, interactedNodes); } else if (numberOfInvolvedNetworksInConnectionAttempt > 1) { HandleAddonToMultipleExistingNetworks(addedNode, interactedNodes); } else { Debug.LogError($"ERROR NETWORK ADDON: There is an illegal number of involved networks " + $"({numberOfInvolvedNetworksInConnectionAttempt}) when trying to add a new node. "); } // Connect nodes with each other and create edges foreach (ElectricNetworkNode interactedNode in interactedNodes) { ElectricNetworkUtil.Connect(addedNode, interactedNode); } // Create cables between power poles, if they are missing CreateAllCables(); }
private void HandleAddonToMultipleExistingNetworks(ElectricNetworkNode addedNode, List <ElectricNetworkNode> adjacentNodes) { ElectricNetwork[] existingNetworks = ElectricNetworkUtil.GetDifferentNetworksOf(adjacentNodes.ToArray()); existingNetworks = ElectricNetwork.SortBySize(existingNetworks); ElectricNetwork biggestNetwork = existingNetworks[0]; // Integrate smaller networks into the biggest one foreach (ElectricNetwork disintegratedNetwork in existingNetworks) { if (disintegratedNetwork == biggestNetwork) { continue; } IntegrateElectricNetworkIntoAnother(biggestNetwork, disintegratedNetwork); } // Register added node into biggest network all other networks get integrated into ElectricNetworkUtil.Register(biggestNetwork, addedNode); SortElectricNetworks(); }
private void IntegrateElectricNetworkIntoAnother(ElectricNetwork targetNetwork, ElectricNetwork disintegratingNetwork) { // Create new lists. Otherwise, elements would be removed while iterating over the list. List <ElectricNetworkNode> movedNodes = new List <ElectricNetworkNode>(disintegratingNetwork.nodes); List <ElectricNetworkEdge> movedEdges = new List <ElectricNetworkEdge>(disintegratingNetwork.edges); // Transfer nodes foreach (ElectricNetworkNode node in movedNodes) { ElectricNetworkUtil.Unregister(disintegratingNetwork, node); ElectricNetworkUtil.Register(targetNetwork, node); } // Transfer edges foreach (ElectricNetworkEdge edge in movedEdges) { ElectricNetworkUtil.Unregister(disintegratingNetwork, edge); ElectricNetworkUtil.Register(targetNetwork, edge); } // "Destroy" (aka unlink) network DestroyElectricNetwork(disintegratingNetwork); }
public void DestroyNode(ElectricNetworkNode node) { ElectricNetwork networkOfDestroyedNode = node.connectedNetwork; // Could throw error, when "node.connectedNodes = null" and then "adjacentNodes[0]"? List <ElectricNetworkNode> adjacentNodes = new List <ElectricNetworkNode>(node.connectedNodes); // Unregister from network ElectricNetworkUtil.Unregister(node.connectedNetwork, node); // If no nodes are connected, destroy the network (the destroyed node was the last one in the network) if (node.connectedNodes.Count() == 0 && node.connectedEdges.Count() == 0) { if (ElectricNetworkUtil.CheckIfNetworkIsEmpty(networkOfDestroyedNode)) { DestroyElectricNetwork(networkOfDestroyedNode); } else { Debug.LogError($"ERROR DELETING NODE: Network {networkOfDestroyedNode} is not empty, but it should be. " + $"On Removal, there were no adjacent nodes, so Node {node} must be the only member. "); } return; } // Destroy cables and disconnect edges List <ElectricNetworkEdge> connectedEdges = new List <ElectricNetworkEdge>(node.connectedEdges); foreach (ElectricNetworkEdge edge in connectedEdges) { Destroy(edge.cable.gameObject); ElectricNetworkUtil.Disconnect(edge); } // Handle adjacent nodes HandleAdjacentNodesAfterNodeRemoval(adjacentNodes); }