MazeAgent.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. using System;
  2. using System.Collections.Generic;
  3. namespace MazeGen
  4. {
  5. /// <summary>
  6. /// Tracks one agent's progress through the maze: current room, ordered path history
  7. /// (for visualization/backtracking), and O(1) sets for "have I been here" / "have I
  8. /// used this exit" checks. Plain C# class - no MonoBehaviour/scene dependency, so it's
  9. /// cheap to run many of these (e.g. for future autonomous multi-agent scenarios).
  10. ///
  11. /// Also tracks the agent's combat state (character sheet, health, equipment).
  12. /// </summary>
  13. public class MazeAgent
  14. {
  15. public readonly string Name;
  16. public Room CurrentRoom { get; private set; }
  17. public int NewRoomsVisited { get; private set; }
  18. public bool IsFinished { get; private set; }
  19. /// <summary>The exit the agent walked through to reach CurrentRoom, if any (null for the starting room). Used by AutonomousAgentBrain to avoid immediately reversing.</summary>
  20. public Exit LastUsedExit { get; private set; }
  21. /// <summary>This agent's character sheet (stats, equipment, inventory).</summary>
  22. public CharacterSheet CharacterSheet { get; private set; }
  23. /// <summary>Track if this agent died (different from IsFinished, which means reached the exit).</summary>
  24. public bool IsDead => !CharacterSheet.Stats.IsAlive;
  25. private readonly List<Room> _path = new List<Room>();
  26. private readonly HashSet<int> _visitedRoomIds = new HashSet<int>();
  27. private readonly HashSet<int> _usedExitIds = new HashSet<int>();
  28. private readonly Dictionary<int, int> _visitCounts = new Dictionary<int, int>();
  29. public IReadOnlyList<Room> PathHistory => _path;
  30. public event Action<Room> RoomEntered;
  31. public event Action<Room> ReachedExitRoom;
  32. public event Action Died;
  33. public MazeAgent(string name, Room startRoom, CharacterSheet characterSheet = null)
  34. {
  35. Name = name;
  36. CharacterSheet = characterSheet ?? new CharacterSheet(new CharacterStats());
  37. EnterRoom(startRoom, null);
  38. }
  39. public bool HasVisited(int roomId) => _visitedRoomIds.Contains(roomId);
  40. public bool HasUsedExit(Exit exit) => _usedExitIds.Contains(exit.Id);
  41. /// <summary>How many times this agent has personally entered the given room (0 if never).</summary>
  42. public int VisitCount(int roomId) => _visitCounts.TryGetValue(roomId, out var count) ? count : 0;
  43. public void EnterRoom(Room room, Exit viaExit)
  44. {
  45. // Check if agent is already dead before entering
  46. if (IsDead)
  47. return;
  48. if (viaExit != null)
  49. _usedExitIds.Add(viaExit.Id);
  50. if (_visitedRoomIds.Add(room.Id))
  51. NewRoomsVisited++;
  52. _visitCounts[room.Id] = VisitCount(room.Id) + 1;
  53. CurrentRoom = room;
  54. LastUsedExit = viaExit;
  55. _path.Add(room);
  56. RoomEntered?.Invoke(room);
  57. if (room.Kind == RoomKind.Exit)
  58. {
  59. IsFinished = true;
  60. ReachedExitRoom?.Invoke(room);
  61. }
  62. }
  63. /// <summary>Called when the agent dies (defeated in combat or other hazard). Stops them from moving.</summary>
  64. public void Die()
  65. {
  66. if (IsDead) return;
  67. CharacterSheet.Stats.CurrentHealth = 0;
  68. Died?.Invoke();
  69. }
  70. }
  71. }