use super::Evolver;

use crate::boolnet::Boolnet;

impl Evolver {
    /// Changes boolnet architecture.
    pub fn arch(&mut self, height: usize, size: usize, rands: usize, layers: usize, cycles: usize) -> Result<(), String> {
        if height == 0 {
            return Err(String::from("Height of boolon's input tree must be positive"));
        }
        if size == 0 {
            return Err(String::from("Size of layer must be positive"));
        }
        if layers == 0 {
            return Err(String::from("Number of layers must be positive"));
        }
        if cycles == 0 {
            return Err(String::from("Number of cycles must be positive"));
        }

        let bn = & self.population[0];

        if (height != bn.height()) || (size != bn.size()) || (rands != bn.rands()) || (layers != bn.layers()) {
            let n = self.population.len();

            self.population.clear();
            for _ in 0..n {
                self.population.push(Boolnet::new_rand(height, size, rands, layers, cycles));
            }

            self.counters.epoch = 0;
            // Don't evolve, because all boolnets are unscored (score = -inf) and thus "sorted" already
        } else { // change only cycles, do not drop current population (but scores are reset to -∞)
            for bn in &mut self.population {
                bn.set_cycles(cycles);
            }
        }

        Ok(())
    }

}
