using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using System.Collections.Generic; [ExecuteAlways] public class Node : MonoBehaviour { [Range(-1, 1)] [SerializeField] public int Owner = -1; public Material materialOwnerSelf, materialOwnerOther, materialOwnerNone, materialHover; public List connected; public bool hovered; void Awake() { UpdateColor(); } // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { } // Update is called once per frame void Update() { if (Input.GetMouseButtonDown(0) && hovered) { var count = CycleFinder.FindLargestCycleAmongNeighbors(this); Debug.Log($"Largest Nacho: {count.Count}"); } UpdateColor(); UpdateTransform(); } private void OnValidate() { UpdateColor(); UpdateTransform(); } private void OnDestroy() { GameManager gm = FindFirstObjectByType(); List looseConnections = gm.connections.FindAll(c => c.nodeA == this || c.nodeB == this); foreach (GameManager.Connection c in looseConnections) { DestroyImmediate(c.lineRenderer.gameObject); gm.connections.Remove(c); } gm.FetchAllNodes(); } public void UpdateTransform() { transform.localPosition = transform.localPosition.normalized * 20f; if (transform.position != Vector3.zero) transform.forward = transform.position; } public void UpdateColor() { if (hovered) { transform.GetChild(0).GetComponent().sharedMaterial = materialHover; } else { switch (Owner) { case -1: transform.GetChild(0).GetComponent().sharedMaterial = materialOwnerNone; break; case 0: transform.GetChild(0).GetComponent().sharedMaterial = materialOwnerSelf; break; case 1: transform.GetChild(0).GetComponent().sharedMaterial = materialOwnerOther; break; } } hovered = false; } } public class CycleFinder { private HashSet allowedNodes; private List bestCycle; private Node centerNode; public CycleFinder(Node center) { centerNode = center; allowedNodes = new HashSet(center.connected); bestCycle = new List(); } public static List FindLargestCycleAmongNeighbors(Node center) { var finder = new CycleFinder(center); return finder.FindBestCycle(); } private List FindBestCycle() { // Versuche von jedem Nachbarknoten aus einen Zyklus zu finden foreach (var startNode in allowedNodes) { var visited = new HashSet(); var currentPath = new List(); SearchForCycles(startNode, startNode, visited, currentPath); } return bestCycle; } private void SearchForCycles(Node startNode, Node currentNode, HashSet visited, List path) { // Aktuellen Knoten zum Pfad hinzufugen path.Add(currentNode); visited.Add(currentNode); // Durchsuche alle Verbindungen des aktuellen Knotens foreach (var neighbor in currentNode.connected) { // Nur Nachbarn des Zentralknotens sind erlaubt if (!allowedNodes.Contains(neighbor)) continue; // Wenn wir zum Startknoten zuruckgekehrt sind und mindestens 3 Knoten im Pfad haben if (neighbor == startNode && path.Count >= 3) { // Geschlossenen Zyklus gefunden - prufe ob er besser ist if (path.Count > bestCycle.Count) { bestCycle = new List(path); } } // Wenn der Knoten noch nicht besucht wurde, setze die Suche fort else if (!visited.Contains(neighbor)) { SearchForCycles(startNode, neighbor, new HashSet(visited), new List(path)); } } } }