Improved foraging
This commit is contained in:
parent
1e2726ecd4
commit
c2dc2720b0
@ -63,7 +63,9 @@ public class ClusterPrefab : ScriptableObject {
|
|||||||
|
|
||||||
public void GarbageCollection() {
|
public void GarbageCollection() {
|
||||||
HashSet<Nucleus> visitedNuclei = new();
|
HashSet<Nucleus> visitedNuclei = new();
|
||||||
MarkNuclei(visitedNuclei, this.output);
|
foreach (Nucleus output in this.outputs)
|
||||||
|
MarkNuclei(visitedNuclei, output);
|
||||||
|
//MarkNuclei(visitedNuclei, this.output);
|
||||||
//Debug.Log($"Garbage collection found {visitedNuclei.Count} Nuclei");
|
//Debug.Log($"Garbage collection found {visitedNuclei.Count} Nuclei");
|
||||||
this.nuclei.RemoveAll(nucleus => nucleus is Nucleus n && visitedNuclei.Contains(n) == false);
|
this.nuclei.RemoveAll(nucleus => nucleus is Nucleus n && visitedNuclei.Contains(n) == false);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -130,7 +130,7 @@ public class ClusterInspector : Editor {
|
|||||||
|
|
||||||
void OnAddClusterOutput() {
|
void OnAddClusterOutput() {
|
||||||
Nucleus newOutput = new Neuron(this.prefab, "New Output");
|
Nucleus newOutput = new Neuron(this.prefab, "New Output");
|
||||||
|
this.prefab.RefreshOutputs();
|
||||||
outputsField.choices = this.prefab.outputs.Select(output => output.name).ToList();
|
outputsField.choices = this.prefab.outputs.Select(output => output.name).ToList();
|
||||||
outputsField.value = newOutput.name;
|
outputsField.value = newOutput.name;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Unity.Mathematics;
|
||||||
|
using static Unity.Mathematics.math;
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public class NucleusArray {
|
public class NucleusArray {
|
||||||
@ -63,25 +65,57 @@ public class NucleusArray {
|
|||||||
public Dictionary<int, Nucleus> thingReceivers = new();
|
public Dictionary<int, Nucleus> thingReceivers = new();
|
||||||
|
|
||||||
|
|
||||||
public virtual void ProcessStimulus(int thingId, Vector3 inputValue, string thingName = null) {
|
private Nucleus FindReceiver(int thingId, float3 inputValue) {
|
||||||
CleanupReceivers();
|
// No existing nucleus for this thing
|
||||||
if (!thingReceivers.TryGetValue(thingId, out Nucleus selectedReceiver)) {
|
float inputMagnitude = length(inputValue);
|
||||||
// Debug.Log($"No receiver found for {thingId}");
|
Nucleus selectedReceiver = null;
|
||||||
foreach (Nucleus receptor in this.nuclei) {
|
float selectedMagnitude = 0;
|
||||||
if (receptor is not Nucleus receiver)
|
foreach (Nucleus receiver in this.nuclei) {
|
||||||
continue;
|
if (thingReceivers.ContainsValue(receiver) == false) {
|
||||||
|
// We found an unusued receiver
|
||||||
if (thingReceivers.ContainsValue(receiver) == false) {
|
thingReceivers.Add(thingId, receiver);
|
||||||
// receiver is not used yet
|
return receiver;
|
||||||
// Debug.Log($"{thingId} -> {receiver.name}");
|
}
|
||||||
thingReceivers.Add(thingId, receiver);
|
else if (receiver.isSleeping) {
|
||||||
|
// A sleeping receiver is not active and can therefore always be used
|
||||||
|
thingReceivers.Add(thingId, receiver);
|
||||||
|
return receiver;
|
||||||
|
}
|
||||||
|
else if (selectedReceiver == null) {
|
||||||
|
// If we haven't found a receiver yet, just start by taking the first
|
||||||
|
selectedReceiver = receiver;
|
||||||
|
selectedMagnitude = length(selectedReceiver.outputValue);
|
||||||
|
}
|
||||||
|
// Look for the receiver with the lowest magnitude
|
||||||
|
else {
|
||||||
|
float magnitude = length(receiver.outputValue);
|
||||||
|
|
||||||
|
if (magnitude < inputMagnitude && length(receiver.outputValue) < selectedMagnitude) {
|
||||||
selectedReceiver = receiver;
|
selectedReceiver = receiver;
|
||||||
break;
|
selectedMagnitude = length(selectedReceiver.outputValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (selectedReceiver != null) {
|
||||||
|
// Replace the receiver
|
||||||
|
// Find the thingId current associated with the receiver
|
||||||
|
int keyToRemove = thingReceivers.FirstOrDefault(r => r.Value.Equals(selectedReceiver)).Key;
|
||||||
|
if (keyToRemove != 0 || thingReceivers.ContainsKey(keyToRemove))
|
||||||
|
thingReceivers.Remove(keyToRemove);
|
||||||
|
// And add the new association
|
||||||
|
thingReceivers.Add(thingId, selectedReceiver);
|
||||||
|
}
|
||||||
|
return selectedReceiver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void ProcessStimulus(int thingId, Vector3 inputValue, string thingName = null) {
|
||||||
|
CleanupReceivers();
|
||||||
|
if (!thingReceivers.TryGetValue(thingId, out Nucleus selectedReceiver)) {
|
||||||
|
// No existing nucleus for this thing
|
||||||
|
selectedReceiver = FindReceiver(thingId, inputValue);
|
||||||
|
}
|
||||||
if (selectedReceiver == null)
|
if (selectedReceiver == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (thingName != null) {
|
if (thingName != null) {
|
||||||
string baseName = selectedReceiver.name;
|
string baseName = selectedReceiver.name;
|
||||||
@ -100,10 +134,8 @@ public class NucleusArray {
|
|||||||
// Remove a thing-receiver connection when the nucleus is inactive
|
// Remove a thing-receiver connection when the nucleus is inactive
|
||||||
List<int> receiversToRemove = new();
|
List<int> receiversToRemove = new();
|
||||||
foreach (KeyValuePair<int, Nucleus> item in thingReceivers) {
|
foreach (KeyValuePair<int, Nucleus> item in thingReceivers) {
|
||||||
if (item.Value.isSleeping) {
|
if (item.Value.isSleeping)
|
||||||
//Nucleus n = item.Value as Nucleus;
|
receiversToRemove.Add(item.Key);
|
||||||
receiversToRemove.Add(item.Key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
foreach (int thingId in receiversToRemove) {
|
foreach (int thingId in receiversToRemove) {
|
||||||
Nucleus selectedReceiver = thingReceivers[thingId];
|
Nucleus selectedReceiver = thingReceivers[thingId];
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user