2024-09-12 10:36:45 -07:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
2024-09-12 15:44:55 -07:00
|
|
|
using Unity.VisualScripting;
|
2024-09-12 10:36:45 -07:00
|
|
|
using UnityEngine;
|
2024-09-29 23:18:40 -07:00
|
|
|
using System.Diagnostics.Contracts;
|
|
|
|
// The threat assignment class assigns interceptors to the targets based
|
2024-09-12 10:36:45 -07:00
|
|
|
// on the threat level of the targets.
|
2024-09-13 22:45:25 -07:00
|
|
|
public class ThreatAssignment : IAssignment {
|
2024-09-24 19:59:25 -07:00
|
|
|
// Assign a target to each interceptor that has not been assigned a target yet.
|
2024-09-29 23:18:40 -07:00
|
|
|
[Pure]
|
|
|
|
public IEnumerable<IAssignment.AssignmentItem> Assign(in IReadOnlyList<Interceptor> interceptors, in IReadOnlyList<ThreatData> targets) {
|
2024-09-13 22:45:25 -07:00
|
|
|
List<IAssignment.AssignmentItem> assignments = new List<IAssignment.AssignmentItem>();
|
|
|
|
|
2024-09-29 23:18:40 -07:00
|
|
|
List<Interceptor> assignableInterceptors = IAssignment.GetAssignableInterceptors(interceptors);
|
|
|
|
if (assignableInterceptors.Count == 0) {
|
|
|
|
Debug.LogWarning("No assignable interceptors found");
|
2024-09-13 22:45:25 -07:00
|
|
|
return assignments;
|
|
|
|
}
|
2024-09-12 10:36:45 -07:00
|
|
|
|
2024-09-29 23:18:40 -07:00
|
|
|
List<ThreatData> activeThreats = IAssignment.GetActiveThreats(targets);
|
|
|
|
if (activeThreats.Count == 0) {
|
|
|
|
Debug.LogWarning("No active threats found");
|
2024-09-13 22:45:25 -07:00
|
|
|
return assignments;
|
2024-09-12 10:36:45 -07:00
|
|
|
}
|
|
|
|
|
2024-09-13 22:45:25 -07:00
|
|
|
Vector3 positionToDefend = Vector3.zero;
|
|
|
|
List<ThreatInfo> threatInfos =
|
2024-09-29 23:18:40 -07:00
|
|
|
CalculateThreatLevels(activeThreats, positionToDefend);
|
|
|
|
|
|
|
|
// Sort ThreatInfo first by ThreatData.Status (UNASSIGNED first, then ASSIGNED)
|
|
|
|
// Within each group, order by ThreatLevel descending
|
|
|
|
threatInfos = threatInfos.OrderByDescending(t => t.ThreatData.Status == ThreatStatus.UNASSIGNED)
|
|
|
|
.ThenByDescending(t => t.ThreatLevel)
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
var assignableInterceptorsEnumerator = assignableInterceptors.GetEnumerator();
|
|
|
|
if (assignableInterceptorsEnumerator.MoveNext()) // Move to the first element
|
|
|
|
{
|
|
|
|
foreach (ThreatInfo threatInfo in threatInfos) {
|
|
|
|
assignments.Add(new IAssignment.AssignmentItem(assignableInterceptorsEnumerator.Current, threatInfo.ThreatData.Threat));
|
|
|
|
if (!assignableInterceptorsEnumerator.MoveNext()) {
|
|
|
|
break;
|
2024-09-12 10:36:45 -07:00
|
|
|
}
|
2024-09-13 22:45:25 -07:00
|
|
|
}
|
2024-09-12 10:36:45 -07:00
|
|
|
}
|
2024-09-13 22:45:25 -07:00
|
|
|
return assignments;
|
|
|
|
}
|
2024-09-12 10:36:45 -07:00
|
|
|
|
2024-09-29 23:18:40 -07:00
|
|
|
|
|
|
|
private List<ThreatInfo> CalculateThreatLevels(List<ThreatData> threatTable,
|
|
|
|
Vector3 defensePosition) {
|
2024-09-13 22:45:25 -07:00
|
|
|
List<ThreatInfo> threatInfos = new List<ThreatInfo>();
|
2024-09-12 10:36:45 -07:00
|
|
|
|
2024-09-29 23:18:40 -07:00
|
|
|
foreach (ThreatData threatData in threatTable) {
|
|
|
|
Threat threat = threatData.Threat;
|
|
|
|
float distanceToMean = Vector3.Distance(threat.transform.position, defensePosition);
|
|
|
|
float velocityMagnitude = threat.GetVelocity().magnitude;
|
2024-09-13 22:45:25 -07:00
|
|
|
|
|
|
|
// Calculate threat level based on proximity and velocity
|
|
|
|
float threatLevel = (1 / distanceToMean) * velocityMagnitude;
|
|
|
|
|
2024-09-29 23:18:40 -07:00
|
|
|
threatInfos.Add(new ThreatInfo(threatData, threatLevel));
|
2024-09-13 22:45:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Sort threats in descending order
|
|
|
|
return threatInfos.OrderByDescending(t => t.ThreatLevel).ToList();
|
|
|
|
}
|
|
|
|
|
|
|
|
private class ThreatInfo {
|
2024-09-29 23:18:40 -07:00
|
|
|
public ThreatData ThreatData { get; }
|
2024-09-13 22:45:25 -07:00
|
|
|
public float ThreatLevel { get; }
|
|
|
|
|
2024-09-29 23:18:40 -07:00
|
|
|
public ThreatInfo(ThreatData threatData, float threatLevel) {
|
|
|
|
ThreatData = threatData;
|
2024-09-13 22:45:25 -07:00
|
|
|
ThreatLevel = threatLevel;
|
2024-09-12 10:36:45 -07:00
|
|
|
}
|
2024-09-13 22:45:25 -07:00
|
|
|
}
|
2024-09-12 10:36:45 -07:00
|
|
|
}
|