using System; using System.Collections.Generic; using System.Linq; using ActiveProtect.Models; namespace ActiveProtect.SimulationEnvironment { /// /// 仿真管理器接口,定义了仿真管理器的基本功能 /// public interface ISimulationManager { /// /// 当前仿真时间 /// double CurrentTime { get; } /// /// 添加仿真元素 /// void AddElement(SimulationElement element); /// /// 根据ID获取仿真实体 /// SimulationElement GetEntityById(string id); /// /// 处理目标被击中事件 /// void HandleTargetHit(string targetId, string missileId); /// /// 发布仿真事件 /// void PublishEvent(SimulationEvent evt); /// /// 订阅仿真事件 /// void SubscribeToEvent(Action handler) where T : SimulationEvent; /// /// 取消订阅仿真事件 /// void UnsubscribeFromEvent(Action handler) where T : SimulationEvent; /// /// 取消所有事件订阅 /// void UnsubscribeAllEvents(SimulationElement element); } /// /// 仿真管理器类,负责管理整个仿真过程 /// public class SimulationManager : ISimulationManager { /// /// 仿真元素列表 /// public List Elements { get; private set; } /// /// 当前仿真时间 /// public double CurrentTime { get; private set; } /// /// 仿真是否结束 /// public bool IsSimulationEnded { get; private set; } private readonly SimulationConfig config; private Dictionary> eventHandlers = new Dictionary>(); private Dictionary> elementSubscriptions = new Dictionary>(); /// /// 构造函数 /// public SimulationManager(SimulationConfig config) { this.config = config; Elements = []; CurrentTime = 0; IsSimulationEnded = false; InitializeSimulation(); } /// /// 初始化仿真 /// private void InitializeSimulation() { // 创建坦克 for (int i = 0; i < config.TankConfigs.Count; i++) { var tankConfig = config.TankConfigs[i]; var tank = new Tank($"Tank_{i + 1}", tankConfig, this); Elements.Add(tank); // 为坦克创建激光告警器 if (tankConfig.HasLaserWarner) { var laserWarner = new LaserWarner( $"LaserWarner_{tank.Id}", tank.Position, tank.Orientation, this, tank.Id, config.LaserWarnerConfig ); Elements.Add(laserWarner); } // 为坦克创建激光干扰机 if (tankConfig.HasLaserJammer) { var laserJammer = new LaserJammer( $"LaserJammer_{tank.Id}", tank.Position, tank.Orientation, this, tank.Id, config.LaserJammerConfig ); Elements.Add(laserJammer); } } // 创建导弹 for (int i = 0; i < config.MissileConfigs.Count; i++) { var missileConfig = config.MissileConfigs[i]; // 确保 MaxFlightTime 设置合理 if (missileConfig.MaxFlightTime <= 0) { missileConfig.MaxFlightTime = 300; // 设置一个默认值,比如 300 秒 Console.WriteLine($"警告:导弹配置 {i} 的 MaxFlightTime 无效,已设置为默认值 300 秒"); } Missile missile = missileConfig.Type switch { MissileType.LaserSemiActiveGuidance => new LaserSemiActiveGuidedMissile( $"LSGM_{i + 1}", missileConfig, this ), _ => new Missile( $"NM_{i + 1}", missileConfig, this ), }; Elements.Add(missile); } // 创建激光目标指示器 for (int i = 0; i < config.LaserDesignatorConfigs.Count; i++) { var laserDesignatorConfig = config.LaserDesignatorConfigs[i]; var laserDesignator = new LaserDesignator($"LD_{i + 1}", "Tank_1", "LSGM_4",laserDesignatorConfig, this); Elements.Add(laserDesignator); laserDesignator.ActivateLaser(); // 激活激光目标指示器 } } /// /// 发布仿真事件 /// public void PublishEvent(SimulationEvent evt) { var eventType = evt.GetType(); if (eventHandlers.TryGetValue(eventType, out var handlers)) { foreach (var handler in handlers) { handler.DynamicInvoke(evt); } } } /// /// 订阅仿真事件 /// public void SubscribeToEvent(Action handler) where T : SimulationEvent { var eventType = typeof(T); if (!eventHandlers.TryGetValue(eventType, out List? value)) { value = []; eventHandlers[eventType] = value; } value.Add(handler); // 记录订阅关系 var element = Elements.FirstOrDefault(e => e.GetType().GetMethods().Any(m => m.Name == handler.Method.Name)); if (element != null) { if (!elementSubscriptions.TryGetValue(element, out List<(Type, Delegate)>? subscriptions)) { subscriptions = []; elementSubscriptions[element] = subscriptions; } subscriptions.Add((eventType, handler as Delegate)); } } /// /// 取消订阅仿真事件 /// public void UnsubscribeFromEvent(Action handler) where T : SimulationEvent { var eventType = typeof(T); if (eventHandlers.TryGetValue(eventType, out List? value)) { value.Remove(handler); } // 移除订阅关系记录 var element = Elements.FirstOrDefault(e => e.GetType().GetMethods().Any(m => m.Name == handler.Method.Name)); if (element != null && elementSubscriptions.TryGetValue(element, out List<(Type, Delegate)>? subscriptions)) { subscriptions.RemoveAll(s => Delegate.Equals(s.Item2, handler)); } } /// /// 取消所有事件订阅 /// public void UnsubscribeAllEvents(SimulationElement element) { if (elementSubscriptions.ContainsKey(element)) { foreach (var subscription in elementSubscriptions[element]) { if (eventHandlers.TryGetValue(subscription.Item1, out List? value)) { value.Remove(subscription.Item2); } } elementSubscriptions.Remove(element); } } /// /// 更新仿真状态 /// public void Update() { if (IsSimulationEnded) return; CurrentTime += config.SimulationTimeStep; foreach (var element in Elements.ToList()) { if (element.IsActive) { element.Update(config.SimulationTimeStep); } else { UnsubscribeAllEvents(element); } } // 移除不活跃的元素 Elements.RemoveAll(e => !e.IsActive); // 检查是否所有导弹都结束飞行 if (!Elements.Any(e => e is Missile && e.IsActive)) { EndSimulation(); } } /// /// 打印仿真状态 /// public void PrintStatus() { Console.WriteLine($"仿真时间: {CurrentTime:F2}"); foreach (var element in Elements) { Console.WriteLine(element.GetStatus()); } Console.WriteLine(); } /// /// 结束仿真 /// private void EndSimulation() { IsSimulationEnded = true; Console.WriteLine("仿真结束"); Console.WriteLine($"总仿真时间: {CurrentTime:F2} 秒"); Console.WriteLine($"剩余坦克数量: {Elements.Count(e => e is Tank)}"); } /// /// 根据ID获取仿真实体 /// public SimulationElement GetEntityById(string id) { return Elements.FirstOrDefault(e => e.Id == id) ?? throw new InvalidOperationException($"Entity with id {id} not found"); } /// /// 处理目标被击中事件 /// public void HandleTargetHit(string targetId, string missileId) { if (GetEntityById(targetId) is Tank tank && GetEntityById(missileId) is Missile missile) { // 计算导弹造成的伤害 double damage = CalculateMissileDamage(missile); // 对坦克造成伤害 tank.TakeDamage(damage, true); // 记录击中事件 LogHitEvent(targetId, missileId, damage); } } /// /// 计算导弹造成的伤害 /// private double CalculateMissileDamage(Missile missile) { // 这里可以根据导弹类型、速度等因素计算伤害 // 现在我们简单地返回一个固定值 return 50; } /// /// 记录击中事件 /// private static void LogHitEvent(string targetId, string missileId, double damage) { Console.WriteLine($"目标 {targetId} 被导弹 {missileId} 击中,造成 {damage} 点伤害"); } /// /// 添加仿真元素 /// public void AddElement(SimulationElement element) { Elements.Add(element); } } }