123 lines
5.5 KiB
C#
123 lines
5.5 KiB
C#
using UnityEngine;
|
|
|
|
namespace NanoBrain {
|
|
|
|
/// <summary>
|
|
/// A Receptor is a Nucleus which can receive input (called Stimulus) from outside the the cluster/brain
|
|
/// </summary>
|
|
/// It has the ability to distinguish stimuli from different things using an array of Nuclei
|
|
public interface IReceptor {
|
|
/// <summary>
|
|
/// Get the name of the receptor
|
|
/// </summary>
|
|
/// <returns>The name of the receptor</returns>
|
|
public string GetName();
|
|
|
|
/// <summary>
|
|
/// The array of nuclei used to track multiple things sending stimuli
|
|
/// </summary>
|
|
/// The size of the array determines the maximum number of things which can be distinguished
|
|
public Nucleus[] nucleiArray { get; set; }
|
|
|
|
/// <summary>
|
|
/// Extends the nucleiArray with an additional element
|
|
/// </summary>
|
|
/// <param name="prefab">A prefab of the nucleus to add?</param>
|
|
public void AddReceptorElement(ClusterPrefab prefab);
|
|
/// <summary>
|
|
/// Removes the last element from the nucleiArray
|
|
/// </summary>
|
|
public void RemoveReceptorElement();
|
|
|
|
/// <summary>
|
|
/// Add a receiver for this receptor array
|
|
/// </summary>
|
|
/// <param name="receiverToAdd">The receiving Nucleus</param>
|
|
/// <param name="weight">The initial weight to use for the synapses</param>
|
|
/// This function will add a synapse to the receiver for each element in the nucleiArray.
|
|
public void AddArrayReceiver(Nucleus receiverToAdd, float weight = 1);
|
|
|
|
/// <summary>
|
|
/// Process an external stimulus
|
|
/// </summary>
|
|
/// <param name="inputValue">The value of the stimulus</param>
|
|
/// <param name="thingId">The id of the thing causing the stimulus</param>
|
|
/// <param name="thingName">The name of the thing causing the stimulus</param>
|
|
public void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null);
|
|
}
|
|
|
|
public static class IReceptorHelpers {
|
|
|
|
/// <summary>
|
|
/// Implementation for the NanoBrain::IReceptor::AddReceptorElement which can be used for all implementations of IReceptor
|
|
/// </summary>
|
|
/// <param name="receptor">The IReceptor which needs to extend its nucleiArray</param>
|
|
/// <param name="prefab">A prefab of the nucleus to add?</param>
|
|
public static void AddReceptorElement(IReceptor receptor, ClusterPrefab prefab) {
|
|
if (receptor.nucleiArray.Length == 0) {
|
|
Debug.LogError("Empty perceptoid array, cannot add");
|
|
}
|
|
int newLength = receptor.nucleiArray.Length + 1;
|
|
Nucleus[] newArray = new Nucleus[newLength];
|
|
|
|
string baseName = receptor.GetName();
|
|
int colonPos = baseName.IndexOf(":");
|
|
if (colonPos > 0)
|
|
baseName = baseName[..colonPos];
|
|
|
|
for (int i = 0; i < receptor.nucleiArray.Length; i++)
|
|
newArray[i] = receptor.nucleiArray[i];
|
|
if (receptor.nucleiArray[0] is Nucleus nucleus) {
|
|
newArray[newLength - 1] = nucleus.Clone(prefab);
|
|
newArray[newLength - 1].name = $"{baseName}: {newLength - 1}";
|
|
}
|
|
|
|
foreach (Nucleus element in receptor.nucleiArray) {
|
|
if (element is IReceptor receptorElement) {
|
|
receptorElement.nucleiArray = newArray;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Implementation for the NanoBrain::IReceptor::RemoteReceptorElement which can be used for all implementations of IReceptor
|
|
/// </summary>
|
|
/// <param name="receptor">The IReceptor which needs to shorten its nucleiArray</param>
|
|
public static void RemoveReceptorElement(IReceptor receptor) {
|
|
int newLength = receptor.nucleiArray.Length - 1;
|
|
if (newLength == 0) {
|
|
Debug.LogWarning("Perceptoid array cannot be empty");
|
|
}
|
|
Nucleus[] newArray = new Nucleus[newLength];
|
|
for (int i = 0; i < newLength; i++)
|
|
newArray[i] = receptor.nucleiArray[i];
|
|
// Delete the last perception
|
|
if (receptor.nucleiArray[newLength] is Nucleus nucleus)
|
|
Neuron.Delete(nucleus);
|
|
|
|
foreach (Nucleus element in receptor.nucleiArray) {
|
|
if (element is IReceptor receptorElement) {
|
|
receptorElement.nucleiArray = newArray;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Implementation for the NanoBreain::IRceptor::AddArrayReceiver which can be used for all implementations of IReceptor
|
|
/// </summary>
|
|
/// <param name="receptor">The IReceptor for which a receiving nuclues needs to be added</param>
|
|
/// <param name="receiverToAdd">The nucleus to receive input from the receptor</param>
|
|
/// <param name="weight">The initial weight for the synapses</param>
|
|
public static void AddArrayReceiver(IReceptor receptor, Nucleus receiverToAdd, float weight = 1) {
|
|
foreach (Nucleus element in receptor.nucleiArray) {
|
|
if (element is Cluster cluster)
|
|
cluster.defaultOutput.AddReceiver(receiverToAdd, weight);
|
|
if (element is Neuron neuron)
|
|
neuron.AddReceiver(receiverToAdd, weight);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
} |