factorio_blueprint/factorio-pathfinding/src/bin/beltfinding.rs

104 lines
3 KiB
Rust

use clap::{Parser, Subcommand, ValueEnum};
use factorio_blueprint::{Blueprint, BlueprintString, encode};
use factorio_core::{beltoptions::Beltspeed, visualize::Visualize};
use factorio_graph::priority_queue::binary_heap::FastBinaryHeap;
use factorio_pathfinding::{
belt_finding::{Problem, conflict_avoidance::ConflictAvoidance},
examples,
};
use std::{io, path::PathBuf};
#[derive(ValueEnum, Clone)]
enum Mode {
Solve,
ConflictAvoidance,
ConflictStep,
}
#[derive(Subcommand)]
enum ProblemCase {
Simple,
Level1,
Level2,
Level3,
Level5,
File { filename: PathBuf },
}
impl ProblemCase {
fn get_problem(&self) -> Problem {
match self {
ProblemCase::Simple => examples::simple().into(),
ProblemCase::Level1 => examples::belt_madness_level_1().into(),
ProblemCase::Level2 => examples::belt_madness_level_2().into(),
ProblemCase::Level3 => examples::belt_madness_level_3().into(),
ProblemCase::Level5 => examples::belt_madness_level_5().into(),
ProblemCase::File { filename } => {
let file = std::fs::File::open(filename).unwrap();
serde_json::from_reader(file).unwrap()
}
}
}
}
#[derive(Parser)]
struct Args {
#[arg(value_enum, default_value = "conflict-avoidance")]
mode: Mode,
#[command(subcommand)]
problem: ProblemCase,
}
fn output_blueprint(conflict: &ConflictAvoidance) {
let mut offset = 0;
let belts = conflict.belt_blueprint(&Beltspeed::Normal, &mut offset);
let bp = BlueprintString::Blueprint(
Blueprint::builder()
.entities(belts)
.label("solution".to_string())
.build(),
);
println!("{}", encode(&serde_json::to_string(&bp).unwrap()));
}
fn main() {
let args = Args::parse();
let mut p = args.problem.get_problem();
match args.mode {
Mode::Solve => {
p.print_visualization();
p.find_path::<FastBinaryHeap<_>>();
p.print_visualization();
}
Mode::ConflictAvoidance => {
p.print_visualization();
p.find_path::<FastBinaryHeap<_>>();
p.print_visualization();
p.find_path::<FastBinaryHeap<_>>();
p.print_visualization();
let mut c = ConflictAvoidance::new(&p);
c.print_visualization();
while c.remove_conflict(None) {
c.print_visualization();
}
output_blueprint(&c);
}
Mode::ConflictStep => {
p.print_visualization();
p.find_path::<FastBinaryHeap<_>>();
p.print_visualization();
let mut c = ConflictAvoidance::new(&p);
c.print_visualization();
while c.remove_conflict(None) {
c.print_visualization();
let mut s = String::new();
let _ = io::stdin().read_line(&mut s);
}
output_blueprint(&c);
}
}
}