Format all files
This commit is contained in:
@@ -3,53 +3,44 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
// The assignment class is an interface for assigning a target to each missile.
|
||||
public interface IAssignment
|
||||
{
|
||||
// Assignment item type.
|
||||
// The first element corresponds to the missile index, and the second element
|
||||
// corresponds to the target index.
|
||||
public struct AssignmentItem
|
||||
{
|
||||
public int MissileIndex;
|
||||
public int TargetIndex;
|
||||
public interface IAssignment {
|
||||
// Assignment item type.
|
||||
// The first element corresponds to the missile index, and the second element
|
||||
// corresponds to the target index.
|
||||
public struct AssignmentItem {
|
||||
public int MissileIndex;
|
||||
public int TargetIndex;
|
||||
|
||||
public AssignmentItem(int missileIndex, int targetIndex)
|
||||
{
|
||||
MissileIndex = missileIndex;
|
||||
TargetIndex = targetIndex;
|
||||
}
|
||||
public AssignmentItem(int missileIndex, int targetIndex) {
|
||||
MissileIndex = missileIndex;
|
||||
TargetIndex = targetIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// A list containing the missile-target assignments.
|
||||
// A list containing the missile-target assignments.
|
||||
|
||||
// Assign a target to each missile that has not been assigned a target yet.
|
||||
public abstract IEnumerable<AssignmentItem> Assign(List<Agent> missiles, List<Agent> targets);
|
||||
// Assign a target to each missile that has not been assigned a target yet.
|
||||
public abstract IEnumerable<AssignmentItem> Assign(List<Agent> missiles, List<Agent> targets);
|
||||
|
||||
// Get the list of assignable missile indices.
|
||||
protected static List<int> GetAssignableMissileIndices(List<Agent> missiles)
|
||||
{
|
||||
List<int> assignableMissileIndices = new List<int>();
|
||||
for (int missileIndex = 0; missileIndex < missiles.Count; missileIndex++)
|
||||
{
|
||||
if (missiles[missileIndex].IsAssignable())
|
||||
{
|
||||
assignableMissileIndices.Add(missileIndex);
|
||||
}
|
||||
}
|
||||
return assignableMissileIndices;
|
||||
// Get the list of assignable missile indices.
|
||||
protected static List<int> GetAssignableMissileIndices(List<Agent> missiles) {
|
||||
List<int> assignableMissileIndices = new List<int>();
|
||||
for (int missileIndex = 0; missileIndex < missiles.Count; missileIndex++) {
|
||||
if (missiles[missileIndex].IsAssignable()) {
|
||||
assignableMissileIndices.Add(missileIndex);
|
||||
}
|
||||
}
|
||||
return assignableMissileIndices;
|
||||
}
|
||||
|
||||
// Get the list of active target indices.
|
||||
protected static List<int> GetActiveTargetIndices(List<Agent> targets)
|
||||
{
|
||||
List<int> activeTargetIndices = new List<int>();
|
||||
for (int targetIndex = 0; targetIndex < targets.Count; targetIndex++)
|
||||
{
|
||||
if (!targets[targetIndex].IsHit())
|
||||
{
|
||||
activeTargetIndices.Add(targetIndex);
|
||||
}
|
||||
}
|
||||
return activeTargetIndices;
|
||||
// Get the list of active target indices.
|
||||
protected static List<int> GetActiveTargetIndices(List<Agent> targets) {
|
||||
List<int> activeTargetIndices = new List<int>();
|
||||
for (int targetIndex = 0; targetIndex < targets.Count; targetIndex++) {
|
||||
if (!targets[targetIndex].IsHit()) {
|
||||
activeTargetIndices.Add(targetIndex);
|
||||
}
|
||||
}
|
||||
return activeTargetIndices;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,42 +5,35 @@ using UnityEngine;
|
||||
|
||||
// The round-robin assignment class assigns missiles to the targets in a
|
||||
// round-robin order.
|
||||
public class RoundRobinAssignment : IAssignment
|
||||
{
|
||||
// Previous target index that was assigned.
|
||||
private int prevTargetIndex = -1;
|
||||
public class RoundRobinAssignment : IAssignment {
|
||||
// Previous target index that was assigned.
|
||||
private int prevTargetIndex = -1;
|
||||
|
||||
// Assign a target to each missile that has not been assigned a target yet.
|
||||
public IEnumerable<IAssignment.AssignmentItem> Assign(List<Agent> missiles, List<Agent> targets)
|
||||
{
|
||||
List<IAssignment.AssignmentItem> assignments = new List<IAssignment.AssignmentItem>();
|
||||
List<int> assignableMissileIndices = IAssignment.GetAssignableMissileIndices(missiles);
|
||||
if (assignableMissileIndices.Count == 0)
|
||||
{
|
||||
return assignments;
|
||||
}
|
||||
|
||||
List<int> activeTargetIndices = IAssignment.GetActiveTargetIndices(targets);
|
||||
if (activeTargetIndices.Count == 0)
|
||||
{
|
||||
return assignments;
|
||||
}
|
||||
|
||||
foreach (int missileIndex in assignableMissileIndices)
|
||||
{
|
||||
int nextActiveTargetIndex = activeTargetIndices
|
||||
.FindIndex(index => index > prevTargetIndex);
|
||||
|
||||
if (nextActiveTargetIndex == -1)
|
||||
{
|
||||
nextActiveTargetIndex = 0;
|
||||
}
|
||||
|
||||
int nextTargetIndex = activeTargetIndices[nextActiveTargetIndex];
|
||||
assignments.Add(new IAssignment.AssignmentItem(missileIndex, nextTargetIndex));
|
||||
prevTargetIndex = nextTargetIndex;
|
||||
}
|
||||
|
||||
return assignments;
|
||||
// Assign a target to each missile that has not been assigned a target yet.
|
||||
public IEnumerable<IAssignment.AssignmentItem> Assign(List<Agent> missiles, List<Agent> targets) {
|
||||
List<IAssignment.AssignmentItem> assignments = new List<IAssignment.AssignmentItem>();
|
||||
List<int> assignableMissileIndices = IAssignment.GetAssignableMissileIndices(missiles);
|
||||
if (assignableMissileIndices.Count == 0) {
|
||||
return assignments;
|
||||
}
|
||||
|
||||
List<int> activeTargetIndices = IAssignment.GetActiveTargetIndices(targets);
|
||||
if (activeTargetIndices.Count == 0) {
|
||||
return assignments;
|
||||
}
|
||||
|
||||
foreach (int missileIndex in assignableMissileIndices) {
|
||||
int nextActiveTargetIndex = activeTargetIndices.FindIndex(index => index > prevTargetIndex);
|
||||
|
||||
if (nextActiveTargetIndex == -1) {
|
||||
nextActiveTargetIndex = 0;
|
||||
}
|
||||
|
||||
int nextTargetIndex = activeTargetIndices[nextActiveTargetIndex];
|
||||
assignments.Add(new IAssignment.AssignmentItem(missileIndex, nextTargetIndex));
|
||||
prevTargetIndex = nextTargetIndex;
|
||||
}
|
||||
|
||||
return assignments;
|
||||
}
|
||||
}
|
||||
@@ -6,89 +6,80 @@ using UnityEngine;
|
||||
|
||||
// The threat assignment class assigns missiles to the targets based
|
||||
// on the threat level of the targets.
|
||||
public class ThreatAssignment : IAssignment
|
||||
{
|
||||
// Assign a target to each missile that has not been assigned a target yet.
|
||||
public IEnumerable<IAssignment.AssignmentItem> Assign(List<Agent> missiles, List<Agent> targets)
|
||||
{
|
||||
public class ThreatAssignment : IAssignment {
|
||||
// Assign a target to each missile that has not been assigned a target yet.
|
||||
public IEnumerable<IAssignment.AssignmentItem> Assign(List<Agent> missiles, List<Agent> targets) {
|
||||
List<IAssignment.AssignmentItem> assignments = new List<IAssignment.AssignmentItem>();
|
||||
|
||||
List<IAssignment.AssignmentItem> assignments = new List<IAssignment.AssignmentItem>();
|
||||
|
||||
List<int> assignableMissileIndices = IAssignment.GetAssignableMissileIndices(missiles);
|
||||
if (assignableMissileIndices.Count == 0)
|
||||
{
|
||||
return assignments;
|
||||
}
|
||||
|
||||
List<int> activeTargetIndices = IAssignment.GetActiveTargetIndices(targets);
|
||||
if (activeTargetIndices.Count == 0)
|
||||
{
|
||||
return assignments;
|
||||
}
|
||||
|
||||
Vector3 positionToDefend = Vector3.zero;
|
||||
List<ThreatInfo> threatInfos = CalculateThreatLevels(targets, activeTargetIndices, positionToDefend);
|
||||
|
||||
foreach (int missileIndex in assignableMissileIndices)
|
||||
{
|
||||
if (missiles[missileIndex].HasAssignedTarget()) continue;
|
||||
if (threatInfos.Count == 0) break;
|
||||
|
||||
// Find the optimal target for this missile based on distance and threat
|
||||
ThreatInfo optimalTarget = null;
|
||||
float optimalScore = float.MinValue;
|
||||
|
||||
foreach (ThreatInfo threat in threatInfos)
|
||||
{
|
||||
float distance = Vector3.Distance(missiles[missileIndex].transform.position, targets[threat.TargetIndex].transform.position);
|
||||
float score = threat.ThreatLevel / distance; // Balance threat level with proximity
|
||||
|
||||
if (score > optimalScore)
|
||||
{
|
||||
optimalScore = score;
|
||||
optimalTarget = threat;
|
||||
}
|
||||
}
|
||||
|
||||
if (optimalTarget != null)
|
||||
{
|
||||
assignments.Add(new IAssignment.AssignmentItem(missileIndex, optimalTarget.TargetIndex));
|
||||
threatInfos.Remove(optimalTarget);
|
||||
}
|
||||
}
|
||||
return assignments;
|
||||
List<int> assignableMissileIndices = IAssignment.GetAssignableMissileIndices(missiles);
|
||||
if (assignableMissileIndices.Count == 0) {
|
||||
return assignments;
|
||||
}
|
||||
|
||||
|
||||
private List<ThreatInfo> CalculateThreatLevels(List<Agent> targets, List<int> activeTargetIndices, Vector3 missilesMeanPosition)
|
||||
{
|
||||
List<ThreatInfo> threatInfos = new List<ThreatInfo>();
|
||||
|
||||
foreach (int targetIndex in activeTargetIndices)
|
||||
{
|
||||
Agent target = targets[targetIndex];
|
||||
float distanceToMean = Vector3.Distance(target.transform.position, missilesMeanPosition);
|
||||
float velocityMagnitude = target.GetVelocity().magnitude;
|
||||
|
||||
// Calculate threat level based on proximity and velocity
|
||||
float threatLevel = (1 / distanceToMean) * velocityMagnitude;
|
||||
|
||||
threatInfos.Add(new ThreatInfo(targetIndex, threatLevel));
|
||||
}
|
||||
|
||||
// Sort threats in descending order
|
||||
return threatInfos.OrderByDescending(t => t.ThreatLevel).ToList();
|
||||
List<int> activeTargetIndices = IAssignment.GetActiveTargetIndices(targets);
|
||||
if (activeTargetIndices.Count == 0) {
|
||||
return assignments;
|
||||
}
|
||||
|
||||
private class ThreatInfo
|
||||
{
|
||||
public int TargetIndex { get; }
|
||||
public float ThreatLevel { get; }
|
||||
Vector3 positionToDefend = Vector3.zero;
|
||||
List<ThreatInfo> threatInfos =
|
||||
CalculateThreatLevels(targets, activeTargetIndices, positionToDefend);
|
||||
|
||||
public ThreatInfo(int targetIndex, float threatLevel)
|
||||
{
|
||||
TargetIndex = targetIndex;
|
||||
ThreatLevel = threatLevel;
|
||||
foreach (int missileIndex in assignableMissileIndices) {
|
||||
if (missiles[missileIndex].HasAssignedTarget())
|
||||
continue;
|
||||
if (threatInfos.Count == 0)
|
||||
break;
|
||||
|
||||
// Find the optimal target for this missile based on distance and threat
|
||||
ThreatInfo optimalTarget = null;
|
||||
float optimalScore = float.MinValue;
|
||||
|
||||
foreach (ThreatInfo threat in threatInfos) {
|
||||
float distance = Vector3.Distance(missiles[missileIndex].transform.position,
|
||||
targets[threat.TargetIndex].transform.position);
|
||||
float score = threat.ThreatLevel / distance; // Balance threat level with proximity
|
||||
|
||||
if (score > optimalScore) {
|
||||
optimalScore = score;
|
||||
optimalTarget = threat;
|
||||
}
|
||||
}
|
||||
|
||||
if (optimalTarget != null) {
|
||||
assignments.Add(new IAssignment.AssignmentItem(missileIndex, optimalTarget.TargetIndex));
|
||||
threatInfos.Remove(optimalTarget);
|
||||
}
|
||||
}
|
||||
return assignments;
|
||||
}
|
||||
|
||||
private List<ThreatInfo> CalculateThreatLevels(List<Agent> targets, List<int> activeTargetIndices,
|
||||
Vector3 missilesMeanPosition) {
|
||||
List<ThreatInfo> threatInfos = new List<ThreatInfo>();
|
||||
|
||||
foreach (int targetIndex in activeTargetIndices) {
|
||||
Agent target = targets[targetIndex];
|
||||
float distanceToMean = Vector3.Distance(target.transform.position, missilesMeanPosition);
|
||||
float velocityMagnitude = target.GetVelocity().magnitude;
|
||||
|
||||
// Calculate threat level based on proximity and velocity
|
||||
float threatLevel = (1 / distanceToMean) * velocityMagnitude;
|
||||
|
||||
threatInfos.Add(new ThreatInfo(targetIndex, threatLevel));
|
||||
}
|
||||
|
||||
// Sort threats in descending order
|
||||
return threatInfos.OrderByDescending(t => t.ThreatLevel).ToList();
|
||||
}
|
||||
|
||||
private class ThreatInfo {
|
||||
public int TargetIndex { get; }
|
||||
public float ThreatLevel { get; }
|
||||
|
||||
public ThreatInfo(int targetIndex, float threatLevel) {
|
||||
TargetIndex = targetIndex;
|
||||
ThreatLevel = threatLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user