psyche-core 0.2.19

Core module for Psyche AI Toolset
Documentation
use crate::brain::BrainID;
use crate::id::ID;
use crate::Scalar;
use serde::{Deserialize, Serialize};

pub type NeuronID = ID<Neuron>;

#[derive(Debug, Default, Copy, Clone, PartialEq, Serialize, Deserialize)]
#[repr(C)]
pub struct Impulse {
    pub potential: Scalar,
    pub timeout: Scalar,
}

#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
pub(crate) struct Synapse {
    pub source: NeuronID,
    pub target: NeuronID,
    pub distance: Scalar,
    pub receptors: Scalar,
    pub impulses: Vec<Impulse>,
    pub inactivity: Scalar,
}

#[derive(Debug, Default, Copy, Clone, PartialEq, Serialize, Deserialize)]
#[repr(C)]
pub struct Position {
    pub x: Scalar,
    pub y: Scalar,
    pub z: Scalar,
}

impl Position {
    #[inline]
    pub fn magnitude_sqr(&self) -> Scalar {
        self.x * self.x + self.y * self.y + self.z * self.z
    }

    #[inline]
    pub fn magnitude(&self) -> Scalar {
        self.magnitude_sqr().sqrt()
    }

    pub fn distance_sqr(&self, other: Self) -> Scalar {
        let dx = self.x - other.x;
        let dy = self.y - other.y;
        let dz = self.z - other.z;
        dx * dx + dy * dy + dz * dz
    }

    #[inline]
    pub fn distance(&self, other: Self) -> Scalar {
        self.distance_sqr(other).sqrt()
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[repr(C)]
pub struct Neuron {
    id: NeuronID,
    owner_id: BrainID,
    position: Position,
    potential: Scalar,
}

impl Neuron {
    pub(crate) fn new(owner_id: BrainID, position: Position) -> Self {
        Self {
            id: Default::default(),
            owner_id,
            position,
            potential: 0.0,
        }
    }

    pub(crate) fn with_id(id: NeuronID, owner_id: BrainID, position: Position) -> Self {
        Self {
            id,
            owner_id,
            position,
            potential: 0.0,
        }
    }

    #[inline]
    pub fn id(&self) -> NeuronID {
        self.id
    }

    #[inline]
    pub fn owner_id(&self) -> BrainID {
        self.owner_id
    }

    #[inline]
    pub fn position(&self) -> Position {
        self.position
    }

    #[inline]
    pub fn potential(&self) -> Scalar {
        self.potential
    }

    #[inline]
    pub(crate) fn push_potential(&mut self, value: Scalar) {
        self.potential += value;
    }

    #[inline]
    pub(crate) fn process_potential(&mut self, delta_time_times_decay: Scalar) {
        if self.potential < -delta_time_times_decay {
            self.potential = (self.potential + delta_time_times_decay).min(0.0);
        } else if self.potential > delta_time_times_decay {
            self.potential = (self.potential - delta_time_times_decay).max(0.0);
        } else {
            self.potential = 0.0;
        }
    }

    #[inline]
    pub(crate) fn fire(&mut self) {
        self.potential = 0.0;
    }
}