Clustering working

This commit is contained in:
Daniel Lovell
2024-09-12 15:44:55 -07:00
parent e42f9e094c
commit 4acc2fd32c
16 changed files with 819 additions and 161 deletions

View File

@@ -3,7 +3,7 @@ using System.Collections.Generic;
using UnityEngine;
// The assignment class is an interface for assigning a target to each missile.
public abstract class Assignment
public interface IAssignment
{
// Assignment item type.
// The first element corresponds to the missile index, and the second element
@@ -21,13 +21,9 @@ public abstract class Assignment
}
// A list containing the missile-target assignments.
protected LinkedList<AssignmentItem> missileToTargetAssignments = new LinkedList<AssignmentItem>();
// Return the missile-target assignments.
public IEnumerable<AssignmentItem> Assignments => missileToTargetAssignments;
// Assign a target to each missile that has not been assigned a target yet.
public abstract void Assign(List<Agent> missiles, List<Agent> targets);
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)

View File

@@ -5,24 +5,25 @@ using UnityEngine;
// The round-robin assignment class assigns missiles to the targets in a
// round-robin order.
public class RoundRobinAssignment : Assignment
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 override void Assign(List<Agent> missiles, List<Agent> targets)
public IEnumerable<IAssignment.AssignmentItem> Assign(List<Agent> missiles, List<Agent> targets)
{
List<int> assignableMissileIndices = GetAssignableMissileIndices(missiles);
List<IAssignment.AssignmentItem> assignments = new List<IAssignment.AssignmentItem>();
List<int> assignableMissileIndices = IAssignment.GetAssignableMissileIndices(missiles);
if (assignableMissileIndices.Count == 0)
{
return;
return assignments;
}
List<int> activeTargetIndices = GetActiveTargetIndices(targets);
List<int> activeTargetIndices = IAssignment.GetActiveTargetIndices(targets);
if (activeTargetIndices.Count == 0)
{
return;
return assignments;
}
foreach (int missileIndex in assignableMissileIndices)
@@ -36,8 +37,10 @@ public class RoundRobinAssignment : Assignment
}
int nextTargetIndex = activeTargetIndices[nextActiveTargetIndex];
missileToTargetAssignments.AddFirst(new AssignmentItem(missileIndex, nextTargetIndex));
assignments.Add(new IAssignment.AssignmentItem(missileIndex, nextTargetIndex));
prevTargetIndex = nextTargetIndex;
}
return assignments;
}
}

View File

@@ -1,44 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Unity.VisualScripting;
using UnityEngine;
// The threat assignment class assigns missiles to the targets based
// on the threat level of the targets.
public class ThreatAssignment : Assignment
public class ThreatAssignment : IAssignment
{
// Assign a target to each missile that has not been assigned a target yet.
public override void Assign(List<Agent> missiles, List<Agent> targets)
public IEnumerable<IAssignment.AssignmentItem> Assign(List<Agent> missiles, List<Agent> targets)
{
List<int> assignableMissileIndices = GetAssignableMissileIndices(missiles);
List<IAssignment.AssignmentItem> assignments = new List<IAssignment.AssignmentItem>();
List<int> assignableMissileIndices = IAssignment.GetAssignableMissileIndices(missiles);
if (assignableMissileIndices.Count == 0)
{
return;
return assignments;
}
List<int> activeTargetIndices = GetActiveTargetIndices(targets);
List<int> activeTargetIndices = IAssignment.GetActiveTargetIndices(targets);
if (activeTargetIndices.Count == 0)
{
return;
return assignments;
}
Vector3 missilesMeanPosition = CalculateMeanPosition(missiles);
List<ThreatInfo> threatInfos = CalculateThreatLevels(targets, activeTargetIndices, missilesMeanPosition);
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;
ThreatInfo highestThreat = threatInfos[0];
missileToTargetAssignments.AddFirst(new AssignmentItem(missileIndex, highestThreat.TargetIndex));
assignments.Add(new IAssignment.AssignmentItem(missileIndex, highestThreat.TargetIndex));
threatInfos.RemoveAt(0);
}
return assignments;
}
private Vector3 CalculateMeanPosition(List<Agent> agents)
{
return agents.Aggregate(Vector3.zero, (sum, agent) => sum + agent.transform.position) / agents.Count;
}
private List<ThreatInfo> CalculateThreatLevels(List<Agent> targets, List<int> activeTargetIndices, Vector3 missilesMeanPosition)
{