Format all files

This commit is contained in:
Titan Yuan
2024-09-13 22:45:25 -07:00
parent df4c8dfbfe
commit 9be43821ef
21 changed files with 1197 additions and 1415 deletions

View File

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

View File

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

View File

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