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);
}
}
}
}