#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Molecule {
CarbonDioxide,
Water,
Glucose,
Oxygen,
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Molecules {
mol: Molecule,
amount: usize,
}
impl Molecules {
pub fn new(mol: Molecule, amount: usize) -> Molecules {
Molecules {
mol,
amount,
}
}
pub fn get_amount(&self) -> &usize {
&self.amount
}
pub fn get_mol(&self) -> &Molecule {
&self.mol
}
}
pub struct Recipe {
consumer: Vec<Molecules>,
producer: Vec<Molecules>,
}
impl Recipe {
pub fn new(consumer: Vec<Molecules>, producer: Vec<Molecules>) -> Recipe {
Recipe {
consumer,
producer,
}
}
pub fn eval(&self, list: &Vec<Molecules>) -> bool {
for it in self.consumer.iter() {
if !list.contains(it) {
return false;
}
}
true
}
pub fn consume(&self, list: &mut Vec<Molecules>) {
if self.eval(&list) {
list.extend(self.producer.iter().cloned());
}
}
}
pub struct MoleculeSet {
pub molecules: Vec<Molecules>,
pub history: Vec<Vec<Molecules>>,
pub recipes: Vec<Recipe>,
}
impl MoleculeSet {
pub fn new(molecules: Vec<Molecules>) -> MoleculeSet {
MoleculeSet {
molecules,
history: Vec::new(),
recipes: default_recipes(),
}
}
pub fn contains(&self, molecule: &Molecules) -> bool {
self.molecules.contains(molecule)
}
pub fn remove(&mut self, molecule: &Molecules) -> Option<Molecules> {
self.molecules.retain(|m: &Molecules | m.get_mol() == molecule.get_mol());
None
}
pub fn synthesize(&mut self) -> std::io::Result<()> {
self.history.push(self.molecules.clone());
for rec in self.recipes.iter() {
if rec.eval(&self.molecules) {
rec.consume(&mut self.molecules);
break;
}
}
Ok(())
}
}
pub fn synthesize(molecules: Vec<Molecules>) -> MoleculeSet {
let mut set = MoleculeSet::new(molecules);
let _ = set.synthesize();
set
}
pub fn default_recipes() -> Vec<Recipe> {
vec!(
Recipe::new(
vec!(
Molecules::new(Molecule::CarbonDioxide, 6),
Molecules::new(Molecule::CarbonDioxide, 6)
),
vec!(
Molecules::new(Molecule::Glucose, 1),
Molecules::new(Molecule::Oxygen, 6)
)
)
)
}