Use visualization for all printing.
This commit is contained in:
parent
7d412ce610
commit
1c44d7aec1
10 changed files with 216 additions and 299 deletions
|
|
@ -1,7 +1,10 @@
|
|||
use std::io;
|
||||
|
||||
use clap::{Parser, ValueEnum};
|
||||
use factorio_blueprint::belt_finding::brute_force::{problems, Bruteforce};
|
||||
use factorio_blueprint::{
|
||||
belt_finding::brute_force::{problems, Bruteforce},
|
||||
common::visualize::Visualize,
|
||||
};
|
||||
|
||||
#[derive(ValueEnum, Clone)]
|
||||
enum Mode {
|
||||
|
|
@ -44,20 +47,20 @@ fn main() {
|
|||
|
||||
let mut b = args.problem.get_problem();
|
||||
|
||||
b.print();
|
||||
b.print_visualization();
|
||||
|
||||
match args.mode {
|
||||
Mode::Solutions => {
|
||||
while b.next_finish_state(None) {
|
||||
println!("{}\n{}\n{}", b.count(), b.solution_count(), b.cost());
|
||||
b.print();
|
||||
b.print_visualization();
|
||||
}
|
||||
|
||||
println!("Solutions: {}\nStates: {}", b.solution_count(), b.count());
|
||||
}
|
||||
Mode::Step => {
|
||||
while b.next_state() {
|
||||
b.print();
|
||||
b.print_visualization();
|
||||
let mut s = String::new();
|
||||
let _ = io::stdin().read_line(&mut s);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,87 +0,0 @@
|
|||
use clap::{Parser, ValueEnum};
|
||||
use factorio_blueprint::belt_finding::{conflict_avoidance::ConflictAvoidance, problems, Problem};
|
||||
use std::io;
|
||||
|
||||
#[derive(ValueEnum, Clone)]
|
||||
enum Mode {
|
||||
Solve,
|
||||
ConflictAvoidance,
|
||||
ConflictStep,
|
||||
}
|
||||
|
||||
#[derive(ValueEnum, Clone)]
|
||||
enum ProblemCase {
|
||||
Simple,
|
||||
Level1,
|
||||
Level2,
|
||||
Level3,
|
||||
Level5,
|
||||
}
|
||||
|
||||
impl ProblemCase {
|
||||
fn get_problem(&self) -> Problem {
|
||||
match self {
|
||||
ProblemCase::Simple => problems::simple(),
|
||||
ProblemCase::Level1 => problems::belt_madness_level_1(),
|
||||
ProblemCase::Level2 => problems::belt_madness_level_2(),
|
||||
ProblemCase::Level3 => problems::belt_madness_level_3(),
|
||||
ProblemCase::Level5 => problems::belt_madness_level_5(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
struct Args {
|
||||
#[arg(value_enum, default_value = "level1")]
|
||||
problem: ProblemCase,
|
||||
#[arg(value_enum, default_value = "conflict-avoidance")]
|
||||
mode: Mode,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
|
||||
let mut p = args.problem.get_problem();
|
||||
|
||||
match args.mode {
|
||||
Mode::Solve => {
|
||||
p.print();
|
||||
p.find_path();
|
||||
p.print();
|
||||
}
|
||||
Mode::ConflictAvoidance => {
|
||||
p.print();
|
||||
p.find_path();
|
||||
p.print();
|
||||
p.find_path();
|
||||
p.print();
|
||||
p.find_path();
|
||||
p.print();
|
||||
p.find_path();
|
||||
p.print();
|
||||
let mut c = ConflictAvoidance::new(&p);
|
||||
c.print();
|
||||
while c.remove_conflict(None) {
|
||||
c.print();
|
||||
}
|
||||
}
|
||||
Mode::ConflictStep => {
|
||||
p.print();
|
||||
p.find_path();
|
||||
p.print();
|
||||
p.find_path();
|
||||
p.print();
|
||||
p.find_path();
|
||||
p.print();
|
||||
p.find_path();
|
||||
p.print();
|
||||
let mut c = ConflictAvoidance::new(&p);
|
||||
c.print();
|
||||
while c.remove_conflict(None) {
|
||||
c.print();
|
||||
let mut s = String::new();
|
||||
let _ = io::stdin().read_line(&mut s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,7 @@
|
|||
use std::time::Instant;
|
||||
|
||||
use super::{
|
||||
common::{print_map, PathField},
|
||||
Position,
|
||||
};
|
||||
use crate::misc::Map;
|
||||
use super::{common::PathField, Position};
|
||||
use crate::prelude::*;
|
||||
use termcolor::ColorSpec;
|
||||
use crate::{common::visualize::Visualize, misc::Map};
|
||||
use std::time::Instant;
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct BruteforceField {
|
||||
|
|
@ -592,83 +587,67 @@ impl Bruteforce {
|
|||
pub fn solution_count(&self) -> u128 {
|
||||
self.solution_count
|
||||
}
|
||||
pub fn print(&self) {
|
||||
let mut m: Map<Option<(usize, &str)>> = Map::new(self.map.width, self.map.height);
|
||||
}
|
||||
|
||||
for (i, problem) in self.problems.iter().enumerate() {
|
||||
if problem.finished {
|
||||
m.set(
|
||||
problem.end_pos.x as usize,
|
||||
problem.end_pos.y as usize,
|
||||
Some((i, "T")),
|
||||
);
|
||||
} else {
|
||||
m.set(
|
||||
problem.end_pos.x as usize,
|
||||
problem.end_pos.y as usize,
|
||||
Some((i, "t")),
|
||||
);
|
||||
}
|
||||
for p in &problem.path {
|
||||
match p {
|
||||
PathField::Belt { pos, dir } => match dir {
|
||||
Direction::Up => m.set(pos.x as usize, pos.y as usize, Some((i, "↑"))),
|
||||
Direction::Right => m.set(pos.x as usize, pos.y as usize, Some((i, "→"))),
|
||||
Direction::Down => m.set(pos.x as usize, pos.y as usize, Some((i, "↓"))),
|
||||
Direction::Left => m.set(pos.x as usize, pos.y as usize, Some((i, "←"))),
|
||||
},
|
||||
PathField::Underground { pos, dir, len } => {
|
||||
match dir {
|
||||
Direction::Up => m.set(pos.x as usize, pos.y as usize, Some((i, "↟"))),
|
||||
Direction::Right => {
|
||||
m.set(pos.x as usize, pos.y as usize, Some((i, "↠")))
|
||||
}
|
||||
Direction::Down => {
|
||||
m.set(pos.x as usize, pos.y as usize, Some((i, "↡")))
|
||||
}
|
||||
Direction::Left => {
|
||||
m.set(pos.x as usize, pos.y as usize, Some((i, "↞")))
|
||||
}
|
||||
};
|
||||
let end_pos = pos.in_direction(dir, *len as PositionType);
|
||||
match dir {
|
||||
Direction::Up => {
|
||||
m.set(end_pos.x as usize, end_pos.y as usize, Some((i, "↥")))
|
||||
}
|
||||
Direction::Right => {
|
||||
m.set(end_pos.x as usize, end_pos.y as usize, Some((i, "↦")))
|
||||
}
|
||||
Direction::Down => {
|
||||
m.set(end_pos.x as usize, end_pos.y as usize, Some((i, "↧")))
|
||||
}
|
||||
Direction::Left => {
|
||||
m.set(end_pos.x as usize, end_pos.y as usize, Some((i, "↤")))
|
||||
}
|
||||
};
|
||||
}
|
||||
impl Visualize for Bruteforce {
|
||||
fn visualize(&self) -> crate::common::visualize::Visualization {
|
||||
let mut v = crate::common::visualize::Visualization::new(Position::new(
|
||||
self.map.width as i32,
|
||||
self.map.height as i32,
|
||||
));
|
||||
|
||||
for x in 0..self.map.width {
|
||||
for y in 0..self.map.height {
|
||||
if self.map.get(x, y).blocked {
|
||||
v.add_symbol(
|
||||
Position::new(x as i32, y as i32),
|
||||
crate::common::visualize::Symbol::Block,
|
||||
Some(crate::common::visualize::Color::white()),
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Print body
|
||||
|
||||
let _ = print_map(self.map.width as i32, self.map.height as i32, |x, y| {
|
||||
if let Some((i, c)) = m.get(x as usize, y as usize) {
|
||||
let mut color = ColorSpec::new();
|
||||
color.set_fg(Some(crate::common::color::COLORS[*i]));
|
||||
(color, *c)
|
||||
} else if self.map.get(x as usize, y as usize).blocked {
|
||||
(ColorSpec::new(), "#")
|
||||
} else if self.map.get(x as usize, y as usize).underground_horizontal {
|
||||
(ColorSpec::new(), "_")
|
||||
} else if self.map.get(x as usize, y as usize).underground_vertical {
|
||||
(ColorSpec::new(), "|")
|
||||
} else if x % 8 == 0 || y % 8 == 0 {
|
||||
(ColorSpec::new(), "∙")
|
||||
} else {
|
||||
(ColorSpec::new(), " ")
|
||||
for (i, problem) in self.problems.iter().enumerate() {
|
||||
for p in &problem.path {
|
||||
match p {
|
||||
PathField::Belt { pos, dir } => {
|
||||
v.add_symbol(
|
||||
*pos,
|
||||
crate::common::visualize::Symbol::Arrow(*dir),
|
||||
Some(crate::common::visualize::Color::index(i)),
|
||||
None,
|
||||
);
|
||||
}
|
||||
PathField::Underground { pos, dir, len } => {
|
||||
v.add_symbol(
|
||||
*pos,
|
||||
crate::common::visualize::Symbol::ArrowEnter(*dir),
|
||||
Some(crate::common::visualize::Color::index(i)),
|
||||
None,
|
||||
);
|
||||
v.add_symbol(
|
||||
pos.in_direction(dir, *len as i32),
|
||||
crate::common::visualize::Symbol::ArrowExit(*dir),
|
||||
Some(crate::common::visualize::Color::index(i)),
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
v.add_symbol(
|
||||
problem.end_pos,
|
||||
crate::common::visualize::Symbol::Char(match problem.finished {
|
||||
true => 'T',
|
||||
false => 't',
|
||||
}),
|
||||
Some(crate::common::visualize::Color::index(i)),
|
||||
None,
|
||||
);
|
||||
}
|
||||
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,10 @@
|
|||
use super::{
|
||||
common::{print_map, PathField},
|
||||
Problem,
|
||||
};
|
||||
use crate::prelude::*;
|
||||
use super::{common::PathField, Problem};
|
||||
use crate::{belt_finding::brute_force::BruteforceBuilder, misc::Map};
|
||||
use crate::{common::visualize::Visualize, prelude::*};
|
||||
use std::{
|
||||
ops::RangeInclusive,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use termcolor::ColorSpec;
|
||||
|
||||
#[derive(Default)]
|
||||
struct Field {
|
||||
|
|
@ -354,7 +350,7 @@ impl ConflictAvoidance {
|
|||
}
|
||||
// dbg!(&candidates);
|
||||
|
||||
while timeout.is_some_and(|t| t < Instant::now()) {
|
||||
while timeout.is_none_or(|t| t > Instant::now()) {
|
||||
candidates.sort_by_key(|c| -c.area());
|
||||
// dbg!(&candidates);
|
||||
let c = match candidates.pop() {
|
||||
|
|
@ -499,53 +495,14 @@ impl ConflictAvoidance {
|
|||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print(&self) {
|
||||
let mut m: Map<Option<(usize, &str)>> = Map::new(self.map.width, self.map.height);
|
||||
|
||||
for (i, problem) in self.belts.iter().enumerate() {
|
||||
for p in problem {
|
||||
match p {
|
||||
PathField::Belt { pos, dir } => match dir {
|
||||
Direction::Up => m.set(pos.x as usize, pos.y as usize, Some((i, "↑"))),
|
||||
Direction::Right => m.set(pos.x as usize, pos.y as usize, Some((i, "→"))),
|
||||
Direction::Down => m.set(pos.x as usize, pos.y as usize, Some((i, "↓"))),
|
||||
Direction::Left => m.set(pos.x as usize, pos.y as usize, Some((i, "←"))),
|
||||
},
|
||||
PathField::Underground { pos, dir, len } => {
|
||||
match dir {
|
||||
Direction::Up => m.set(pos.x as usize, pos.y as usize, Some((i, "↟"))),
|
||||
Direction::Right => {
|
||||
m.set(pos.x as usize, pos.y as usize, Some((i, "↠")))
|
||||
}
|
||||
Direction::Down => {
|
||||
m.set(pos.x as usize, pos.y as usize, Some((i, "↡")))
|
||||
}
|
||||
Direction::Left => {
|
||||
m.set(pos.x as usize, pos.y as usize, Some((i, "↞")))
|
||||
}
|
||||
};
|
||||
let end_pos = pos.in_direction(dir, *len as PositionType);
|
||||
match dir {
|
||||
Direction::Up => {
|
||||
m.set(end_pos.x as usize, end_pos.y as usize, Some((i, "↥")))
|
||||
}
|
||||
Direction::Right => {
|
||||
m.set(end_pos.x as usize, end_pos.y as usize, Some((i, "↦")))
|
||||
}
|
||||
Direction::Down => {
|
||||
m.set(end_pos.x as usize, end_pos.y as usize, Some((i, "↧")))
|
||||
}
|
||||
Direction::Left => {
|
||||
m.set(end_pos.x as usize, end_pos.y as usize, Some((i, "↤")))
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
let last_pos = problem.last().unwrap().pos();
|
||||
m.set(last_pos.x as usize, last_pos.y as usize, Some((i, "T")));
|
||||
}
|
||||
impl Visualize for ConflictAvoidance {
|
||||
fn visualize(&self) -> crate::common::visualize::Visualization {
|
||||
let mut v = crate::common::visualize::Visualization::new(Position::new(
|
||||
self.map.width as i32,
|
||||
self.map.height as i32,
|
||||
));
|
||||
|
||||
// create conflict map
|
||||
let mut conflicts: Map<usize> = Map::new(self.map.width, self.map.height);
|
||||
|
|
@ -554,6 +511,13 @@ impl ConflictAvoidance {
|
|||
for y in 0..self.map.height {
|
||||
if self.map.get(x, y).blocked {
|
||||
*conflicts.get_mut(x, y) += 1;
|
||||
|
||||
v.add_symbol(
|
||||
Position::new(x as i32, y as i32),
|
||||
crate::common::visualize::Symbol::Block,
|
||||
Some(crate::common::visualize::Color::white()),
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -572,31 +536,62 @@ impl ConflictAvoidance {
|
|||
}
|
||||
}
|
||||
}
|
||||
// Print body
|
||||
|
||||
let _ = print_map(self.map.width as i32, self.map.height as i32, |x, y| {
|
||||
let mut color = ColorSpec::new();
|
||||
|
||||
if let Some((xrange, yrange)) = &self.range {
|
||||
if xrange.contains(&x) && yrange.contains(&y) {
|
||||
color.set_bg(Some(termcolor::Color::Rgb(96, 96, 0)));
|
||||
for (i, path) in self.belts.iter().enumerate() {
|
||||
for p in path {
|
||||
match p {
|
||||
PathField::Belt { pos, dir } => {
|
||||
v.add_symbol(
|
||||
*pos,
|
||||
crate::common::visualize::Symbol::Arrow(*dir),
|
||||
Some(crate::common::visualize::Color::index(i)),
|
||||
None,
|
||||
);
|
||||
}
|
||||
PathField::Underground { pos, dir, len } => {
|
||||
v.add_symbol(
|
||||
*pos,
|
||||
crate::common::visualize::Symbol::ArrowEnter(*dir),
|
||||
Some(crate::common::visualize::Color::index(i)),
|
||||
None,
|
||||
);
|
||||
v.add_symbol(
|
||||
pos.in_direction(dir, *len as i32),
|
||||
crate::common::visualize::Symbol::ArrowExit(*dir),
|
||||
Some(crate::common::visualize::Color::index(i)),
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if conflicts.get(x as usize, y as usize) > &1 {
|
||||
color.set_bg(Some(termcolor::Color::Black));
|
||||
for x in 0..self.map.width {
|
||||
for y in 0..self.map.height {
|
||||
if conflicts.get(x, y) > &1 {
|
||||
v.overwrite_background(
|
||||
Position::new(x as i32, y as i32),
|
||||
Some(crate::common::visualize::Color::new(100, 80, 80)),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((i, c)) = m.get(x as usize, y as usize) {
|
||||
color.set_fg(Some(crate::common::color::COLORS[*i]));
|
||||
(color, c)
|
||||
} else if self.map.get(x as usize, y as usize).blocked {
|
||||
(color, "#")
|
||||
} else if x % 8 == 0 || y % 8 == 0 {
|
||||
(color, "∙")
|
||||
} else {
|
||||
(color, " ")
|
||||
for path in &self.belts {
|
||||
for p in &path[1..] {
|
||||
match p {
|
||||
PathField::Belt { pos, dir: _ } => {
|
||||
*conflicts.get_mut(pos.x as usize, pos.y as usize) += 1
|
||||
}
|
||||
PathField::Underground { pos, dir, len } => {
|
||||
*conflicts.get_mut(pos.x as usize, pos.y as usize) += 1;
|
||||
let end = pos.in_direction(dir, *len as PositionType);
|
||||
*conflicts.get_mut(end.x as usize, end.y as usize) += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
v
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
use crate::common::color::COLORS;
|
||||
use crate::common::visualize::Visualize;
|
||||
use crate::graph::wheighted_graph::shortest_path::dijkstra;
|
||||
use crate::graph::wheighted_graph::WheightedGraph;
|
||||
use crate::layout::Layout;
|
||||
use crate::misc::Map;
|
||||
use crate::prelude::*;
|
||||
use crate::priority_queue::BinaryHeap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use termcolor::ColorSpec;
|
||||
|
||||
use self::common::print_map;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub mod brute_force;
|
||||
pub mod common;
|
||||
|
|
@ -132,45 +129,58 @@ impl Problem {
|
|||
// self.map.get_mut(p.0.x as usize, p.0.y as usize).weight = f64::INFINITY;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print(&self) {
|
||||
let _ = print_map(self.map.width as i32, self.map.height as i32, |x, y| {
|
||||
let mut color = ColorSpec::new();
|
||||
if let Some(i) = self
|
||||
.start
|
||||
.iter()
|
||||
.position(|p| p.0 == Position::new(x as PositionType, y as PositionType))
|
||||
{
|
||||
color.set_fg(Some(COLORS[i]));
|
||||
(color, "s")
|
||||
} else if let Some(i) = self
|
||||
.end
|
||||
.iter()
|
||||
.position(|p| p.0 == Position::new(x as PositionType, y as PositionType))
|
||||
{
|
||||
color.set_fg(Some(COLORS[i]));
|
||||
(color, "t")
|
||||
} else if let Some((i, p)) = self.path.iter().enumerate().find_map(|(i, v)| {
|
||||
v.iter()
|
||||
.position(|p| p.0 == Position::new(x as PositionType, y as PositionType))
|
||||
.map(|j| (i, j))
|
||||
}) {
|
||||
color.set_fg(Some(COLORS[i]));
|
||||
let c = &self.path[i][p];
|
||||
match c.1 {
|
||||
Direction::Up => (color, "↑"),
|
||||
Direction::Right => (color, "→"),
|
||||
Direction::Down => (color, "↓"),
|
||||
Direction::Left => (color, "←"),
|
||||
impl Visualize for Problem {
|
||||
fn visualize(&self) -> crate::common::visualize::Visualization {
|
||||
let mut v = crate::common::visualize::Visualization::new(Position::new(
|
||||
self.map.width as i32,
|
||||
self.map.height as i32,
|
||||
));
|
||||
|
||||
for x in 0..self.map.width {
|
||||
for y in 0..self.map.height {
|
||||
if self.map.get(x, y).blocked {
|
||||
v.add_symbol(
|
||||
Position::new(x as i32, y as i32),
|
||||
crate::common::visualize::Symbol::Block,
|
||||
Some(crate::common::visualize::Color::white()),
|
||||
None,
|
||||
)
|
||||
}
|
||||
} else if self.map.get(x as usize, y as usize).blocked {
|
||||
(color, "#")
|
||||
} else if x % 8 == 0 || y % 8 == 0 {
|
||||
(color, "∙")
|
||||
} else {
|
||||
(color, " ")
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (i, (p, _d)) in self.start.iter().enumerate() {
|
||||
v.add_symbol(
|
||||
*p,
|
||||
crate::common::visualize::Symbol::Char('S'),
|
||||
Some(crate::common::visualize::Color::index(i)),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
for (i, (p, _d)) in self.end.iter().enumerate() {
|
||||
v.add_symbol(
|
||||
*p,
|
||||
crate::common::visualize::Symbol::Char('T'),
|
||||
Some(crate::common::visualize::Color::index(i)),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
for (i, p) in self.path.iter().enumerate() {
|
||||
for (pos, dir) in p {
|
||||
v.add_symbol(
|
||||
*pos,
|
||||
crate::common::visualize::Symbol::Arrow(*dir),
|
||||
Some(crate::common::visualize::Color::index(i)),
|
||||
None,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
use clap::{Parser, Subcommand, ValueEnum};
|
||||
use factorio_blueprint::belt_finding::{conflict_avoidance::ConflictAvoidance, problems, Problem};
|
||||
use factorio_blueprint::{
|
||||
belt_finding::{conflict_avoidance::ConflictAvoidance, problems, Problem},
|
||||
common::visualize::Visualize,
|
||||
};
|
||||
use std::{io, path::PathBuf};
|
||||
|
||||
#[derive(ValueEnum, Clone)]
|
||||
|
|
@ -50,28 +53,28 @@ fn main() {
|
|||
|
||||
match args.mode {
|
||||
Mode::Solve => {
|
||||
p.print();
|
||||
p.print_visualization();
|
||||
p.find_path();
|
||||
p.print();
|
||||
p.print_visualization();
|
||||
}
|
||||
Mode::ConflictAvoidance => {
|
||||
p.print();
|
||||
p.print_visualization();
|
||||
p.find_path();
|
||||
p.print();
|
||||
p.print_visualization();
|
||||
let mut c = ConflictAvoidance::new(&p);
|
||||
c.print();
|
||||
c.print_visualization();
|
||||
while c.remove_conflict(None) {
|
||||
c.print();
|
||||
c.print_visualization();
|
||||
}
|
||||
}
|
||||
Mode::ConflictStep => {
|
||||
p.print();
|
||||
p.print_visualization();
|
||||
p.find_path();
|
||||
p.print();
|
||||
p.print_visualization();
|
||||
let mut c = ConflictAvoidance::new(&p);
|
||||
c.print();
|
||||
c.print_visualization();
|
||||
while c.remove_conflict(None) {
|
||||
c.print();
|
||||
c.print_visualization();
|
||||
let mut s = String::new();
|
||||
let _ = io::stdin().read_line(&mut s);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
use crate::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::transformation;
|
||||
|
||||
pub type PositionType = i32;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use super::Visualization;
|
||||
use crate::{common::visualize::Symbol, prelude::Direction};
|
||||
use image::{GenericImage, Pixel, Rgba, RgbaImage};
|
||||
use image::{GenericImage, Rgba, RgbaImage};
|
||||
|
||||
pub(super) fn draw<I: GenericImage<Pixel = Rgba<u8>>>(v: &Visualization, image: &mut I) {
|
||||
assert_eq!(
|
||||
|
|
|
|||
|
|
@ -80,6 +80,10 @@ impl Color {
|
|||
Self { r, g, b }
|
||||
}
|
||||
|
||||
pub fn white() -> Self {
|
||||
Self::new(255, 255, 255)
|
||||
}
|
||||
|
||||
pub fn index(i: usize) -> Self {
|
||||
let c = [
|
||||
Color::new(0xe6, 0x00, 0x49),
|
||||
|
|
@ -112,7 +116,19 @@ impl Visualization {
|
|||
fg: Option<Color>,
|
||||
bg: Option<Color>,
|
||||
) {
|
||||
self.symbols.insert(pos, (symbol, fg, bg));
|
||||
if let Some(s) = self.symbols.get_mut(&pos) {
|
||||
*s = (symbol, fg, bg);
|
||||
} else {
|
||||
self.symbols.insert(pos, (symbol, fg, bg));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn overwrite_background(&mut self, pos: Position, bg: Option<Color>) {
|
||||
if let Some(s) = self.symbols.get_mut(&pos) {
|
||||
s.2 = bg;
|
||||
} else {
|
||||
self.symbols.insert(pos, (Symbol::Space, None, bg));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn size(&self) -> Position {
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ impl<'a> PathLayout<'a> {
|
|||
if !c.remove_all_conflicts(Some(std::time::Duration::from_secs(2))) {
|
||||
if start.elapsed().as_secs_f32() > 0.5 {
|
||||
println!("Conflict avoidance: {:.2}", start.elapsed().as_secs_f32());
|
||||
c.print();
|
||||
c.print_visualization();
|
||||
let file = std::fs::File::create(format!(
|
||||
"out/{}.json",
|
||||
OUTFILEINDEX.fetch_add(1, std::sync::atomic::Ordering::Relaxed)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue