2025-12-05 16:41:11 +01:00

101 lines
3.8 KiB
C#

using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Perception : Nucleus {
public SensoryNeuroid[] sensoryNeuroids = new SensoryNeuroid[7];
[System.Serializable]
public class Receiver {
public int thingType = 0;
public Nucleus neuroid;
}
//public HashSet<Receiver> positionReceivers { get; protected set; }
public List<Receiver> positionReceivers;
//public HashSet<Receiver> velocityReceivers { get; protected set; }
public List<Receiver> velocityReceivers;
public Perception(NanoBrainObj brain) : base(brain, "Perception") {
this.positionReceivers = new();
this.velocityReceivers = new();
}
public void SendPositions(Nucleus receivingNeuroid, int thingType = 0, float weight = 1.0f) {
Receiver receiver = new() {
thingType = thingType,
neuroid = receivingNeuroid
};
positionReceivers.Add(receiver);
foreach (SensoryNeuroid neuroid in sensoryNeuroids) {
if (neuroid != null) {
neuroid.AddReceiver(receivingNeuroid);
receivingNeuroid.SetWeight(neuroid, weight);
}
}
}
public void SendVelocities(Nucleus receivingNeuroid, int thingType = 0, float weight = 1.0f) {
Receiver receiver = new() {
thingType = thingType,
neuroid = receivingNeuroid
};
velocityReceivers.Add(receiver);
foreach (SensoryNeuroid neuroid in sensoryNeuroids) {
if (neuroid != null && neuroid.velocityNeuroid != null) {
neuroid.velocityNeuroid.AddReceiver(receivingNeuroid);
receivingNeuroid.SetWeight(neuroid, weight);
}
}
}
public void ProcessStimulus(int thingId, int thingType, Vector3 localPosition, string name = "Sensing") {
int availableIx = -1;
int leastInterestingIx = -1;
for (int i = 0; i < sensoryNeuroids.Length; i++) {
if (sensoryNeuroids[i] == null)
availableIx = i;
else if (sensoryNeuroids[i].receptor.thingId == thingId) {
sensoryNeuroids[i].receptor.position = localPosition;
return;
}
if (availableIx == -1) {
if (sensoryNeuroids[i].isSleeping)
leastInterestingIx = i;
else if (sensoryNeuroids[i] != null) {
if (leastInterestingIx == -1 || sensoryNeuroids[leastInterestingIx].receptor.position.magnitude > sensoryNeuroids[i].receptor.position.magnitude)
leastInterestingIx = i;
}
}
}
if (availableIx == -1)
availableIx = leastInterestingIx;
if (availableIx != -1) {
SensoryNeuroid neuroid;
if (sensoryNeuroids[availableIx] != null) {
Debug.Log($"replace receptor for {thingId} at {availableIx}");
neuroid = sensoryNeuroids[availableIx];
neuroid.Replace(thingId, name);
}
else {
Debug.Log($"new receptor for {thingId} at {availableIx}");
neuroid = new(newBrain, thingId, name);
sensoryNeuroids[availableIx] = neuroid;
}
foreach (Receiver receiver in positionReceivers) {
if (receiver.thingType == 0 || receiver.thingType == thingType) {
Debug.Log("Add position receiver");
receiver.neuroid.GetInputFrom(neuroid);
}
}
foreach (Receiver receiver in velocityReceivers) {
if (receiver.thingType == 0 || receiver.thingType == thingType)
receiver.neuroid.GetInputFrom(neuroid.velocityNeuroid);
}
neuroid.receptor.position = localPosition;
}
}
}