5Y5T3M/Assets/Scripts/Node.cs

170 lines
4.6 KiB
C#
Raw Normal View History

2025-09-17 17:26:16 +02:00
using System;
using System.Collections.Generic;
using System.Linq;
2025-09-15 23:01:07 +02:00
using UnityEngine;
2025-09-17 21:48:38 +02:00
using TMPro;
2025-09-15 23:01:07 +02:00
2025-09-16 00:08:50 +02:00
[ExecuteAlways]
2025-09-15 23:01:07 +02:00
public class Node : MonoBehaviour
{
2025-09-16 14:20:19 +02:00
[Range(-1, 1)]
[SerializeField]
2025-09-17 10:12:15 +02:00
public int Owner = -1;
2025-09-17 21:48:38 +02:00
public int Units;
2025-09-17 23:38:11 +02:00
public int id;
2025-09-17 21:48:38 +02:00
public TMP_Text unitText;
2025-09-17 17:26:16 +02:00
public Material materialOwnerSelf, materialOwnerOther, materialOwnerNone, materialHover;
2025-09-17 17:26:16 +02:00
public List<Node> connected;
public bool hovered;
2025-09-18 00:39:27 +02:00
private int Nachos = 0;
void Awake()
{
UpdateColor();
}
2025-09-16 14:20:19 +02:00
2025-09-15 23:01:07 +02:00
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
2025-09-18 00:39:27 +02:00
private void FixedUpdate()
{
CalculateNachos();
}
void CalculateNachos()
{
Nachos = CycleFinder.FindLargestCycleAmongNeighbors(this).Count;
}
2025-09-15 23:01:07 +02:00
// Update is called once per frame
void Update()
{
2025-09-17 21:48:38 +02:00
unitText.enabled = hovered;
2025-09-18 17:37:35 +02:00
unitText.text = Units.ToString();
2025-09-17 21:48:38 +02:00
unitText.transform.forward = Camera.main.transform.forward;
2025-09-17 17:26:16 +02:00
UpdateColor();
UpdateTransform();
}
private void OnValidate()
{
UpdateColor();
UpdateTransform();
}
2025-09-17 17:05:48 +02:00
private void OnDestroy()
{
GameManager gm = FindFirstObjectByType<GameManager>();
2025-09-17 17:26:16 +02:00
2025-09-17 21:48:38 +02:00
if (gm == null || Application.isPlaying)
return;
2025-09-17 23:38:11 +02:00
List<Connection> looseConnections = gm.GetConnections().FindAll(c => c.nodeA == this || c.nodeB == this) ?? new();
2025-09-17 17:05:48 +02:00
2025-09-17 23:38:11 +02:00
foreach (Connection c in looseConnections)
2025-09-17 17:05:48 +02:00
{
2025-09-17 17:41:23 +02:00
if (c.lineRenderer != null)
DestroyImmediate(c.lineRenderer.gameObject);
2025-09-17 17:05:48 +02:00
}
}
public void UpdateTransform()
{
transform.localPosition = transform.localPosition.normalized * 20f;
2025-09-17 17:26:16 +02:00
if (transform.position != Vector3.zero)
2025-09-17 17:05:48 +02:00
transform.forward = transform.position;
}
public void UpdateColor()
{
2025-09-17 21:48:38 +02:00
Material material = null;
int currentPlayer = GameManager.Instance ? GameManager.Instance.currentPlayer : -1;
2025-09-17 17:26:16 +02:00
if (hovered)
2025-09-17 21:48:38 +02:00
material = materialHover;
else if (Owner == -1 || currentPlayer == -1)
material = materialOwnerNone;
else if (Owner == currentPlayer)
material = materialOwnerSelf;
2025-09-17 17:26:16 +02:00
else
2025-09-17 21:48:38 +02:00
material = materialOwnerOther;
transform.GetChild(0).GetComponent<Renderer>().sharedMaterial = material;
2025-09-17 17:26:16 +02:00
hovered = false;
}
}
public class CycleFinder
{
private HashSet<Node> allowedNodes;
private List<Node> bestCycle;
private Node centerNode;
2025-09-18 00:39:27 +02:00
private int Owner;
2025-09-17 17:26:16 +02:00
2025-09-18 00:39:27 +02:00
public CycleFinder(Node center, int owner)
2025-09-17 17:26:16 +02:00
{
centerNode = center;
2025-09-18 00:39:27 +02:00
allowedNodes = new HashSet<Node>(center.connected.Where(obj => obj.Owner == owner));
2025-09-17 17:26:16 +02:00
bestCycle = new List<Node>();
2025-09-18 00:39:27 +02:00
Owner = owner;
2025-09-17 17:26:16 +02:00
}
public static List<Node> FindLargestCycleAmongNeighbors(Node center)
{
2025-09-18 00:39:27 +02:00
var finder = new CycleFinder(center, center.Owner);
2025-09-17 17:26:16 +02:00
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;
}
2025-09-16 17:40:34 +02:00
2025-09-17 17:26:16 +02:00
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));
}
}
}
}