166 lines
No EOL
4.6 KiB
C#
166 lines
No EOL
4.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using TMPro;
|
|
|
|
[ExecuteAlways]
|
|
public class Node : MonoBehaviour
|
|
{
|
|
[Range(-1, 1)]
|
|
[SerializeField]
|
|
public int Owner = -1;
|
|
public int Units;
|
|
public int id;
|
|
public TMP_Text unitText;
|
|
public Material materialOwnerSelf, materialOwnerOther, materialOwnerNone, materialHover;
|
|
|
|
public List<Node> connected;
|
|
|
|
public bool hovered;
|
|
|
|
public static Node pressedNode = null;
|
|
|
|
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}");
|
|
}
|
|
|
|
unitText.enabled = hovered;
|
|
unitText.text = Units.ToString();
|
|
unitText.transform.forward = Camera.main.transform.forward;
|
|
UpdateColor();
|
|
UpdateTransform();
|
|
}
|
|
|
|
private void OnValidate()
|
|
{
|
|
UpdateColor();
|
|
UpdateTransform();
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
GameManager gm = FindFirstObjectByType<GameManager>();
|
|
|
|
if (gm == null || Application.isPlaying)
|
|
return;
|
|
|
|
List<Connection> looseConnections = gm.GetConnections().FindAll(c => c.nodeA == this || c.nodeB == this) ?? new();
|
|
|
|
foreach (Connection c in looseConnections)
|
|
{
|
|
if (c.lineRenderer != null)
|
|
DestroyImmediate(c.lineRenderer.gameObject);
|
|
}
|
|
}
|
|
|
|
public void UpdateTransform()
|
|
{
|
|
transform.localPosition = transform.localPosition.normalized * 20f;
|
|
if (transform.position != Vector3.zero)
|
|
transform.forward = transform.position;
|
|
}
|
|
|
|
public void UpdateColor()
|
|
{
|
|
Material material = null;
|
|
int currentPlayer = GameManager.Instance ? GameManager.Instance.currentPlayer : -1;
|
|
|
|
if (hovered)
|
|
material = materialHover;
|
|
else if (Owner == -1 || currentPlayer == -1)
|
|
material = materialOwnerNone;
|
|
else if (Owner == currentPlayer)
|
|
material = materialOwnerSelf;
|
|
else
|
|
material = materialOwnerOther;
|
|
|
|
transform.GetChild(0).GetComponent<Renderer>().sharedMaterial = material;
|
|
|
|
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));
|
|
}
|
|
}
|
|
}
|
|
} |