#![warn(missing_docs)]
use anyhow::{Error, Result};
use franklin::{
crossover::{
ArithmeticAverageCrossover, CrossoverFunction, EqualHalfsCrossover,
LeftOrRightCloneCrossover,
},
fitness::{AbsoluteDistance, FitnessFunction, SquareDistance},
mutators::{CircleMutator, Mutator, RectangleMutator, TriangleMutator},
ArgParser, ColorMode, DisplayCondition, EnvironmentBuilder, ImageReader, SaveCondition,
};
#[doc(hidden)]
fn get_color_mode_from_name(name: &str) -> Result<ColorMode> {
match name {
"Rgb" => Ok(ColorMode::Rgb),
"Grayscale" => Ok(ColorMode::Grayscale),
_ => Err(Error::msg("Unknown mode.")),
}
}
#[doc(hidden)]
fn get_mutator_from_name(name: &str) -> Result<Box<dyn Mutator + Send + Sync + 'static>> {
match name {
"Rectangle" => Ok(Box::<RectangleMutator>::default()),
"Triangle" => Ok(Box::<TriangleMutator>::default()),
"Circle" => Ok(Box::<CircleMutator>::default()),
_ => Err(Error::msg("Unknown mutator.")),
}
}
#[doc(hidden)]
fn get_fitness_from_name(name: &str) -> Result<Box<dyn FitnessFunction + Send + Sync + 'static>> {
match name {
"SquareDistance" => Ok(Box::<SquareDistance>::default()),
"AbsoluteDistance" => Ok(Box::<AbsoluteDistance>::default()),
_ => Err(Error::msg("Unknown fitness function.")),
}
}
#[doc(hidden)]
fn get_crossover_from_name(name: &str) -> Result<Box<dyn CrossoverFunction + Send + 'static>> {
match name {
"LeftOrRight" => Ok(Box::<LeftOrRightCloneCrossover>::default()),
"EqualHalfs" => Ok(Box::<EqualHalfsCrossover>::default()),
"ArithmeticAverage" => Ok(Box::<ArithmeticAverageCrossover>::default()),
_ => Err(Error::msg("Unknown crossover function.")),
}
}
fn main() -> Result<()> {
let args = ArgParser::default();
let image = ImageReader::load(args.get_value("image").unwrap())?;
let mut environment_builder = EnvironmentBuilder::default();
environment_builder.set_image(image);
environment_builder.set_color_mode(get_color_mode_from_name(
args.get_value("color_mode").unwrap(),
)?);
environment_builder.set_mutator(get_mutator_from_name(args.get_value("mutator").unwrap())?);
environment_builder
.set_fitness_function(get_fitness_from_name(args.get_value("fitness").unwrap())?);
environment_builder.set_crossover_function(get_crossover_from_name(
args.get_value("crossover").unwrap(),
)?);
let generation_size: usize = args.get_value_t("generation_size")?;
environment_builder.set_generation_size(generation_size);
let threads: usize = args.get_value_t("threads")?;
environment_builder.set_threads(threads);
if args.is_present("display") {
if args.is_present("display_all") {
environment_builder.set_display_condition(DisplayCondition::All);
} else if let Ok(per) = args.get_value_t::<u32>("display_every") {
environment_builder.set_display_condition(DisplayCondition::Every(per));
}
}
if let Some(output_directory) = args.get_value("output_directory") {
let filename_prefix = args.get_value("filename_prefix").unwrap();
environment_builder.set_filename_prefix(filename_prefix);
let save_condition = if args.is_present("save_all") {
SaveCondition::All
} else if let Ok(per) = args.get_value_t::<u32>("save_every") {
SaveCondition::Each(per)
} else {
SaveCondition::Never
};
environment_builder.set_output_directory(output_directory, save_condition)?;
}
let environment = environment_builder.build()?;
environment.run()?;
Ok(())
}