169 lines
4.6 KiB
C#
169 lines
4.6 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
[System.Serializable]
|
|
public class Nucleus {
|
|
|
|
public int id; // hash code
|
|
|
|
[SerializeField]
|
|
protected string _name;
|
|
public virtual string name {
|
|
get => _name;
|
|
set => _name = value;
|
|
}
|
|
|
|
//public readonly Dictionary<Nucleus, float> synapses = new();
|
|
[SerializeField]
|
|
public List<Synapse> synapses = new();
|
|
//public HashSet<Nucleus> receivers = new();
|
|
[SerializeField]
|
|
public List<Receiver> receivers = new();
|
|
|
|
#region Serialization
|
|
|
|
public void Rebuild(NanoBrainObj brain) {
|
|
if (this.synapses != null) {
|
|
foreach (Synapse synapse in synapses)
|
|
synapse.Rebuild(brain);
|
|
}
|
|
if (this.receivers == null)
|
|
this.receivers = new();
|
|
else
|
|
foreach (Receiver receiver in receivers)
|
|
receiver.Rebuild(brain);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Runtime state (not serialized)
|
|
|
|
// public NanoBrain brain { get; protected set; }
|
|
public NanoBrainObj newBrain { get; protected set; }
|
|
|
|
public virtual Vector3 outputValue { get; set; }
|
|
|
|
[System.NonSerialized]
|
|
public int stale = 0;
|
|
[System.NonSerialized]
|
|
public int layerIx;
|
|
|
|
#endregion Runtime state
|
|
|
|
public Nucleus(NanoBrainObj brain, string name) {
|
|
this.newBrain = brain;
|
|
if (this.newBrain != null)
|
|
this.newBrain.nuclei.Add(this);
|
|
else
|
|
Debug.LogError("No neuroid network");
|
|
|
|
this._name = name;
|
|
this.id = this.GetHashCode();
|
|
}
|
|
|
|
public virtual void AddReceiver(Nucleus receiver) {
|
|
this.receivers.Add(new Receiver(receiver));
|
|
//receiver.synapses[this] = 1.0f; // new(this);
|
|
receiver.SetWeight(this, 1.0f);
|
|
//Debug.Log($"receiver # {this.receivers.Count} synapse count {receiver.synapses.Count}");
|
|
}
|
|
|
|
public static void Delete(Nucleus nucleus) {
|
|
foreach (Synapse synapse in nucleus.synapses) {
|
|
if (synapse.nucleus.receivers.Count > 1) {
|
|
// there is another nucleus feeding into this input nucleus
|
|
synapse.nucleus.receivers.RemoveAll(r => r.nucleus == nucleus);
|
|
} else {
|
|
// No other links, delete it.
|
|
Nucleus.Delete(synapse.nucleus);
|
|
}
|
|
}
|
|
foreach (Receiver receiver in nucleus.receivers)
|
|
receiver.nucleus.synapses.RemoveAll(s => s.nucleus == nucleus);
|
|
|
|
nucleus.newBrain.nuclei.RemoveAll(n => n == nucleus);
|
|
}
|
|
|
|
public void GetInputFrom(Nucleus input, float weight = 1.0f) {
|
|
input.AddReceiver(this);
|
|
this.SetWeight(input, weight);
|
|
}
|
|
|
|
public bool isSleeping {
|
|
get {
|
|
return this.stale > 2;
|
|
}
|
|
}
|
|
|
|
public bool SynapseExists(Nucleus nucleus) {
|
|
foreach (Synapse synapse in synapses) {
|
|
if (synapse.nucleus == nucleus)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public void SetWeight(Nucleus nucleus, float weight) {
|
|
foreach (Synapse synapse in synapses) {
|
|
if (synapse.nucleus == nucleus) {
|
|
synapse.weight = weight;
|
|
return;
|
|
}
|
|
}
|
|
Synapse newSynapse = new(nucleus, weight);
|
|
synapses.Add(newSynapse);
|
|
}
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class Synapse {
|
|
[System.NonSerialized]
|
|
public Nucleus nucleus;
|
|
public int nucleusId;
|
|
public float weight;
|
|
|
|
public Synapse(Nucleus nucleus, float weight) {
|
|
this.nucleus = nucleus;
|
|
this.nucleusId = nucleus.id;
|
|
this.weight = weight;
|
|
}
|
|
|
|
public void Rebuild(NanoBrainObj brain) {
|
|
if (brain == null) {
|
|
return;
|
|
}
|
|
|
|
foreach (Nucleus nucleus in brain.nuclei) {
|
|
if (nucleus.id == this.nucleusId) {
|
|
this.nucleus = nucleus;
|
|
return;
|
|
}
|
|
}
|
|
Debug.LogError($"Synapse deserialization error: could not find nucleus with id {this.nucleusId}");
|
|
}
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class Receiver {
|
|
[System.NonSerialized]
|
|
public Nucleus nucleus;
|
|
public int nucleusId;
|
|
|
|
public Receiver(Nucleus nucleus) {
|
|
this.nucleus = nucleus;
|
|
this.nucleusId = nucleus.id;
|
|
}
|
|
|
|
public void Rebuild(NanoBrainObj brain) {
|
|
if (brain == null)
|
|
return;
|
|
|
|
foreach (Nucleus nucleus in brain.nuclei) {
|
|
if (nucleus.id == this.nucleusId) {
|
|
this.nucleus = nucleus;
|
|
return;
|
|
}
|
|
}
|
|
Debug.LogError($"Synapse deserialization error: could not find nucleus with id {this.nucleusId}");
|
|
}
|
|
} |