using System; using System.Collections.Generic; using UnityEngine; namespace MazeGen { /// What kind of decision a thought records - drives its color in the HUD. public enum ThoughtKind { Move, // "moving to room X" Peek, // "looked through a door and saw N monsters" Avoid, // "that room is too dangerous, picking another exit" Fight, // "engaging / joining a fight" Sneak, // "trying to slip past a fight" Combat, // blow-by-blow results the agent was involved in Outcome, // fight won/lost/fled Goal // reached the exit room, died } public readonly struct Thought { public readonly float Time; public readonly ThoughtKind Kind; public readonly string Text; public Thought(float time, ThoughtKind kind, string text) { Time = time; Kind = kind; Text = text; } } /// /// A bounded, newest-wins journal of one agent's decisions, so the observer can follow an /// agent and read *why* it did what it did. Capped so that thousands of decisions over a /// long run can't grow without bound - this is a debugging/observation surface, not history /// the simulation itself ever reads back. /// public class AgentThoughtLog { private readonly List _entries = new List(); private readonly int _capacity; // Generous, because a single big fight's blow-by-blow gets mirrored in here and would // otherwise push out all the exploration reasoning that explains how the agent got there. public AgentThoughtLog(int capacity = 150) { _capacity = Mathf.Max(1, capacity); } /// Oldest first. Iterate backwards for a newest-first display. public IReadOnlyList Entries => _entries; public event Action Added; public void Add(ThoughtKind kind, string text) { if (string.IsNullOrEmpty(text)) return; var thought = new Thought(Time.time, kind, text); _entries.Add(thought); if (_entries.Count > _capacity) _entries.RemoveAt(0); Added?.Invoke(thought); } public static Color ColorFor(ThoughtKind kind) { switch (kind) { case ThoughtKind.Peek: return new Color(0.7f, 0.85f, 1f); case ThoughtKind.Avoid: return new Color(1f, 0.85f, 0.4f); case ThoughtKind.Fight: return new Color(1f, 0.5f, 0.4f); case ThoughtKind.Sneak: return new Color(0.8f, 0.7f, 1f); case ThoughtKind.Combat: return new Color(1f, 0.75f, 0.75f); case ThoughtKind.Outcome: return new Color(0.6f, 1f, 0.7f); case ThoughtKind.Goal: return new Color(0.5f, 1f, 1f); default: return new Color(0.85f, 0.85f, 0.85f); } } } }