158 lines
No EOL
4.4 KiB
C#
158 lines
No EOL
4.4 KiB
C#
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<Node> 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<GameManager>();
|
|
|
|
List<GameManager.Connection> 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<Renderer>().sharedMaterial = materialHover;
|
|
}
|
|
else
|
|
{
|
|
switch (Owner)
|
|
{
|
|
case -1: transform.GetChild(0).GetComponent<Renderer>().sharedMaterial = materialOwnerNone; break;
|
|
case 0: transform.GetChild(0).GetComponent<Renderer>().sharedMaterial = materialOwnerSelf; break;
|
|
case 1: transform.GetChild(0).GetComponent<Renderer>().sharedMaterial = materialOwnerOther; break;
|
|
}
|
|
}
|
|
|
|
hovered = false;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
public class CycleFinder
|
|
{
|
|
private HashSet<Node> allowedNodes;
|
|
private List<Node> bestCycle;
|
|
private Node centerNode;
|
|
|
|
public CycleFinder(Node center)
|
|
{
|
|
centerNode = center;
|
|
allowedNodes = new HashSet<Node>(center.connected);
|
|
bestCycle = new List<Node>();
|
|
}
|
|
|
|
public static List<Node> FindLargestCycleAmongNeighbors(Node center)
|
|
{
|
|
var finder = new CycleFinder(center);
|
|
return finder.FindBestCycle();
|
|
}
|
|
|
|
private List<Node> FindBestCycle()
|
|
{
|
|
// Versuche von jedem Nachbarknoten aus einen Zyklus zu finden
|
|
foreach (var startNode in allowedNodes)
|
|
{
|
|
var visited = new HashSet<Node>();
|
|
var currentPath = new List<Node>();
|
|
|
|
SearchForCycles(startNode, startNode, visited, currentPath);
|
|
}
|
|
|
|
return bestCycle;
|
|
}
|
|
|
|
private void SearchForCycles(Node startNode, Node currentNode, HashSet<Node> visited, List<Node> 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<Node>(path);
|
|
}
|
|
}
|
|
// Wenn der Knoten noch nicht besucht wurde, setze die Suche fort
|
|
else if (!visited.Contains(neighbor))
|
|
{
|
|
SearchForCycles(startNode, neighbor, new HashSet<Node>(visited), new List<Node>(path));
|
|
}
|
|
}
|
|
}
|
|
} |