From 2bf648f657c041cd77249adedbc18682f0d852bf Mon Sep 17 00:00:00 2001 From: hal8174 Date: Sun, 18 Feb 2024 14:46:57 +0100 Subject: [PATCH] Changed bruteforce end pos. --- src/belt_finding/brute_force.rs | 97 ++++++++++++++++---------- src/belt_finding/conflict_avoidance.rs | 47 +++++++++---- 2 files changed, 95 insertions(+), 49 deletions(-) diff --git a/src/belt_finding/brute_force.rs b/src/belt_finding/brute_force.rs index 26fbbea..5476823 100644 --- a/src/belt_finding/brute_force.rs +++ b/src/belt_finding/brute_force.rs @@ -40,6 +40,22 @@ impl BruteforceBuilder { self.map.get_mut(x, y).blocked = blocked; } + pub fn set_underground(&mut self, x: usize, y: usize, dir: Option) { + match dir { + Some(d) => { + if d.vertical() { + self.map.get_mut(x, y).underground_vertical = true; + } else { + self.map.get_mut(x, y).underground_horizontal = true; + } + } + None => { + self.map.get_mut(x, y).underground_vertical = false; + self.map.get_mut(x, y).underground_horizontal = false; + } + } + } + pub fn set_blocked_range(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, blocked: bool) { for x in x1..=x2 { for y in y1..=y2 { @@ -65,10 +81,10 @@ impl BruteforceBuilder { }; for [start, end] in self.path { - b.map - .get_mut(start.0.x as usize, start.0.y as usize) - .blocked = true; - b.map.get_mut(end.0.x as usize, end.0.y as usize).blocked = true; + // b.map + // .get_mut(start.0.x as usize, start.0.y as usize) + // .blocked = true; + // b.map.get_mut(end.0.x as usize, end.0.y as usize).blocked = true; b.problems.push(Problem { path: vec![PathField::Belt { pos: start.0, @@ -299,20 +315,22 @@ impl Bruteforce { } fn check_finish(&self, i: usize) -> bool { - match self.problems[i].path.last().unwrap() { - PathField::Belt { pos, dir } => Some(pos.in_direction(dir, 1)) - .filter(|p| { - p == &self.problems[i].end_pos && dir != &self.problems[i].end_dir.reverse() - }) - .is_some(), - PathField::Underground { pos, dir, len } => { - Some(pos.in_direction(dir, *len as PositionType + 1)) - .filter(|p| { - p == &self.problems[i].end_pos && dir != &self.problems[i].end_dir.reverse() - }) - .is_some() - } - } + self.problems[i].path.last().unwrap().end_pos() + == (self.problems[i].end_pos, self.problems[i].end_dir) + // match self.problems[i].path.last().unwrap() { + // PathField::Belt { pos, dir } => Some(pos.in_direction(dir, 1)) + // .filter(|p| { + // p == &self.problems[i].end_pos && dir != &self.problems[i].end_dir.reverse() + // }) + // .is_some(), + // PathField::Underground { pos, dir, len } => { + // Some(pos.in_direction(dir, *len as PositionType + 1)) + // .filter(|p| { + // p == &self.problems[i].end_pos && dir != &self.problems[i].end_dir.reverse() + // }) + // .is_some() + // } + // } } fn modify_underground(&mut self, pos: &Position, dir: &Direction, len: u8) -> bool { @@ -492,18 +510,21 @@ impl Bruteforce { fn is_next_free(&self, pos: &Position, dir: &Direction) -> bool { let i = self.modify_pointer(); - pos.in_direction(dir, 1) - .in_range( - &Position::new(0, 0), - &Position::new( - self.map.width as PositionType, - self.map.height as PositionType, - ), - ) - .filter(|&p| { - !self.map.get(p.x as usize, p.y as usize).blocked || self.problems[i].end_pos == *p - }) - .is_some() + self.check_finish(i) + || pos + .in_direction(dir, 1) + .in_range( + &Position::new(0, 0), + &Position::new( + self.map.width as PositionType, + self.map.height as PositionType, + ), + ) + .filter(|&p| { + !self.map.get(p.x as usize, p.y as usize).blocked + || self.problems[i].end_pos == *p + }) + .is_some() } // Add an Path elemeent @@ -686,7 +707,7 @@ mod test { }; } - test_bruteforce!(simple 9; mid 238240; snake 5); + test_bruteforce!(simple 9; mid 308986; snake 5); } pub mod problems { @@ -700,11 +721,15 @@ pub mod problems { (Position::new(0, 0), Direction::Up), ); + b.set_blocked(1, 0, true); + b.add_path( (Position::new(4, 0), Direction::Down), (Position::new(1, 7), Direction::Up), ); + b.set_blocked(4, 0, true); + b.set_blocked_range(0, 2, 5, 5, true); b.build() @@ -717,29 +742,31 @@ pub mod problems { (Position::new(0, 0), Direction::Down), (Position::new(5, 5), Direction::Down), ); + b.set_blocked(0, 0, true); b.add_path( (Position::new(0, 5), Direction::Up), (Position::new(5, 0), Direction::Up), ); + b.set_blocked(0, 0, true); b.build() } pub fn snake() -> Bruteforce { - let mut p = BruteforceBuilder::new(14, 3); + let mut p = BruteforceBuilder::new(13, 3); p.add_path( (Position::new(0, 0), Direction::Right), - (Position::new(13, 0), Direction::Right), + (Position::new(12, 0), Direction::Right), ); p.add_path( (Position::new(0, 1), Direction::Right), - (Position::new(13, 1), Direction::Right), + (Position::new(12, 1), Direction::Right), ); p.add_path( (Position::new(0, 2), Direction::Right), - (Position::new(13, 2), Direction::Right), + (Position::new(12, 2), Direction::Right), ); p.set_blocked_range(3, 2, 10, 2, true); diff --git a/src/belt_finding/conflict_avoidance.rs b/src/belt_finding/conflict_avoidance.rs index e054ee1..b8c75fe 100644 --- a/src/belt_finding/conflict_avoidance.rs +++ b/src/belt_finding/conflict_avoidance.rs @@ -225,11 +225,7 @@ impl ConflictAvoidance { // edge cases with underground into and end - if let Some(PathField::Underground { - pos, - dir: _, - len: _, - }) = path.get(end_index + 1) + if let Some(PathField::Underground { pos, dir, len }) = path.get(end_index + 1) { if xrange.contains(&(pos.x as usize)) && yrange.contains(&(pos.y as usize)) { @@ -237,9 +233,38 @@ impl ConflictAvoidance { println!("Blocked {:?}", p); b.set_blocked(p.x as usize, p.y as usize, true); } + + for l in 1..*len { + let p = pos.in_direction(dir, l as i32); + + if xrange.contains(&(p.x as usize)) && yrange.contains(&(p.y as usize)) + { + let p = p - offset; + b.set_underground(p.x as usize, p.y as usize, Some(*dir)); + } + } } - b.add_path((start_pos - offset, start_dir), (end_pos - offset, end_dir)); + let start_pos_offset = start_pos - offset; + b.set_blocked( + start_pos_offset.x as usize, + start_pos_offset.y as usize, + true, + ); + + if let PathField::Underground { pos, dir, len } = path[start_index] { + for l in 1..len { + let p = pos.in_direction(&dir, l as i32); + + if xrange.contains(&(p.x as usize)) && yrange.contains(&(p.y as usize)) + { + let p = p - offset; + b.set_underground(p.x as usize, p.y as usize, Some(dir)); + } + } + } + + b.add_path((start_pos_offset, start_dir), (end_pos - offset, end_dir)); mapping.push((i, start_index, end_index)); } @@ -249,6 +274,7 @@ impl ConflictAvoidance { let mut b = b.build(); + println!("{}", b); println!("{}", self); let mut min_cost = f64::INFINITY; @@ -274,14 +300,7 @@ impl ConflictAvoidance { t.extend_from_slice(&self.belts[index][0..=start]); t.extend(p[1..].iter().map(|p| p.offset(&offset))); - let (end_pos, end_dir) = self.belts[index][end].end_pos(); - t.push(PathField::Belt { - pos: end_pos, - dir: end_dir, - }); - if end + 1 < self.belts[index].len() { - t.extend_from_slice(&self.belts[index][end + 1..]); - } + t.extend_from_slice(&self.belts[index][end + 1..]); // println!("{:?}", &t); // println!(); // println!("{:?}", &self.belts[index]);