From f25b58448ed5a362018bba73293fcbbec448aed9 Mon Sep 17 00:00:00 2001 From: hal8174 Date: Wed, 20 Mar 2024 23:11:21 +0100 Subject: [PATCH] Change initial pathfinding. --- Cargo.lock | 134 ++++++------ examples/solve_belt.rs | 2 + src/belt_finding/common.rs | 2 +- src/belt_finding/conflict_avoidance.rs | 31 ++- src/belt_finding/mod.rs | 271 +++++++++++++++---------- 5 files changed, 254 insertions(+), 186 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1603cd7..9ff464e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,18 +10,18 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "anstream" -version = "0.6.11" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" dependencies = [ "anstyle", "anstyle-parse", @@ -96,9 +96,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" [[package]] name = "cast" @@ -125,9 +125,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.0" +version = "4.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" +checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813" dependencies = [ "clap_builder", "clap_derive", @@ -135,9 +135,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.0" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", @@ -147,9 +147,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.0" +version = "4.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +checksum = "90239a040c80f5e14809ca132ddc4176ab33d5e17e49691793296e3fcb34d72f" dependencies = [ "heck", "proc-macro2", @@ -271,7 +271,7 @@ name = "factorio_blueprint" version = "0.1.0" dependencies = [ "base64", - "clap 4.5.0", + "clap 4.5.3", "criterion", "flate2", "serde", @@ -291,15 +291,15 @@ dependencies = [ [[package]] name = "half" -version = "1.8.2" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" @@ -327,9 +327,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "js-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -348,9 +348,9 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "memchr" @@ -418,9 +418,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -436,9 +436,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" dependencies = [ "either", "rayon-core", @@ -468,9 +468,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", @@ -485,9 +485,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "same-file" @@ -500,9 +500,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] @@ -519,9 +519,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", @@ -530,9 +530,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.113" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ "itoa", "ryu", @@ -547,9 +547,9 @@ checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" dependencies = [ "proc-macro2", "quote", @@ -604,9 +604,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -614,9 +614,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -624,9 +624,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", @@ -639,9 +639,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -649,9 +649,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", @@ -662,15 +662,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -718,9 +718,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -733,42 +733,42 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" diff --git a/examples/solve_belt.rs b/examples/solve_belt.rs index 54e71cf..48cedc9 100644 --- a/examples/solve_belt.rs +++ b/examples/solve_belt.rs @@ -11,6 +11,7 @@ enum Mode { #[derive(ValueEnum, Clone)] enum ProblemCase { + simple, Level1, Level2, Level3, @@ -20,6 +21,7 @@ enum ProblemCase { 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(), diff --git a/src/belt_finding/common.rs b/src/belt_finding/common.rs index 28c9719..5233802 100644 --- a/src/belt_finding/common.rs +++ b/src/belt_finding/common.rs @@ -6,7 +6,7 @@ use termcolor::{ColorSpec, StandardStream, WriteColor}; pub type PositionType = i32; -#[derive(Clone, Copy, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] pub enum Direction { Up, Right, diff --git a/src/belt_finding/conflict_avoidance.rs b/src/belt_finding/conflict_avoidance.rs index c24b05a..ae6a169 100644 --- a/src/belt_finding/conflict_avoidance.rs +++ b/src/belt_finding/conflict_avoidance.rs @@ -69,6 +69,7 @@ impl ConflictAvoidance { } let mut belts = Vec::new(); for i in 0..problem.path.len() { + dbg!(&problem.path[i]); let mut p = Vec::new(); p.push(PathField::Belt { @@ -76,22 +77,34 @@ impl ConflictAvoidance { dir: problem.start[i].1, }); - for j in 0..problem.path[i].len() - 1 { - p.push(PathField::Belt { - pos: problem.path[i][j], - dir: Direction::from_neighbors(&problem.path[i][j], &problem.path[i][j + 1]), - }); + for (pos, dir) in &problem.path[i][1..] { + let start = p.last().unwrap().end_pos(); + let start = start.0.in_direction(&start.1, 1); + dbg!(start, pos); + if &start == pos { + p.push(PathField::Belt { + pos: *pos, + dir: *dir, + }); + } else { + p.push(PathField::Underground { + pos: start, + dir: *dir, + len: u8::max((start.x - pos.x).abs() as u8, (start.y - pos.y).abs() as u8), + }) + } } - p.push(PathField::Belt { - pos: *problem.path[i].last().unwrap(), - dir: problem.end[i].1, - }); + // p.push(PathField::Belt { + // pos: *problem.path[i].last().unwrap(), + // dir: problem.end[i].1, + // }); // p.push(PathField::Belt { // pos: problem.end[i].0, // dir: problem.end[i].1, // }); + dbg!(&p); belts.push(p); } diff --git a/src/belt_finding/mod.rs b/src/belt_finding/mod.rs index 38bf46a..2b3fec0 100644 --- a/src/belt_finding/mod.rs +++ b/src/belt_finding/mod.rs @@ -23,7 +23,7 @@ pub struct Problem { map: Map, start: Vec<(Position, Direction)>, end: Vec<(Position, Direction)>, - path: Vec>, + path: Vec>, } impl Problem { @@ -55,37 +55,37 @@ impl Problem { } fn calculate_wheights(&mut self, without: usize) { - for x in 0..self.map.width { - for y in 0..self.map.height { - let mut wheight = 1.0; + // for x in 0..self.map.width { + // for y in 0..self.map.height { + // let mut wheight = 1.0; - if self.map.get(x, y).blocked { - wheight += 100.0; - } + // if self.map.get(x, y).blocked { + // wheight += 100.0; + // } - self.map.get_mut(x, y).wheight = wheight; - } - } + // self.map.get_mut(x, y).wheight = wheight; + // } + // } - for (i, path) in self.path.iter().enumerate() { - if i != without { - for p in path { - let weight = 50.0; - let x = p.x as usize; - let y = p.y as usize; + // for (i, path) in self.path.iter().enumerate() { + // if i != without { + // for p in path { + // let weight = 50.0; + // let x = p.x as usize; + // let y = p.y as usize; - self.map.get_mut(x, y).wheight += weight; - } - } - } + // self.map.get_mut(x, y).wheight += weight; + // } + // } + // } - for p in &self.start { - self.map.get_mut(p.0.x as usize, p.0.y as usize).wheight = f64::INFINITY; - } + // for p in &self.start { + // self.map.get_mut(p.0.x as usize, p.0.y as usize).wheight = f64::INFINITY; + // } - for p in &self.end { - self.map.get_mut(p.0.x as usize, p.0.y as usize).wheight = f64::INFINITY; - } + // for p in &self.end { + // self.map.get_mut(p.0.x as usize, p.0.y as usize).wheight = f64::INFINITY; + // } } pub fn print(&self) { @@ -107,22 +107,16 @@ impl Problem { (color, "t") } else if let Some((i, p)) = self.path.iter().enumerate().find_map(|(i, v)| { v.iter() - .position(|p| p == &Position::new(x as PositionType, y as PositionType)) + .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]; - let n = self.path[i].get(p + 1).unwrap_or(&self.end[i].0); - if c.x < n.x { - (color, "→") - } else if c.x > n.x { - (color, "←") - } else if c.y < n.y { - (color, "↓") - } else if c.y > n.y { - (color, "↑") - } else { - unreachable!() + match c.1 { + Direction::Up => (color, "↑"), + Direction::Right => (color, "→"), + Direction::Down => (color, "↓"), + Direction::Left => (color, "←"), } } else if self.map.get(x as usize, y as usize).blocked { (color, "#") @@ -156,54 +150,102 @@ impl Index for Cyclic { struct MapInternal<'a> { map: &'a Map, -} - -impl<'a> MapInternal<'a> { - fn get_direction(&self, pos: Position) -> [Option; 4] { - let min = Position::new(0, 0); - let max = Position::new( - self.map.width as PositionType, - self.map.height as PositionType, - ); - [ - Position::new(pos.x - 1, pos.y) - .in_range(&min, &max) - .copied(), - Position::new(pos.x + 1, pos.y) - .in_range(&min, &max) - .copied(), - Position::new(pos.x, pos.y - 1) - .in_range(&min, &max) - .copied(), - Position::new(pos.x, pos.y + 1) - .in_range(&min, &max) - .copied(), - ] - } + end: (Position, Direction), } impl<'a> WheightedGraph for MapInternal<'a> { - type Node = Position; + type Node = (Position, Direction); fn num_edges(&self, node: &Self::Node) -> usize { - if self.map.get(node.x as usize, node.y as usize).blocked { - 0 - } else { - let t = self.get_direction(*node); + todo!(); + // let next = node.0.in_direction(&node.1, 1); + // if next + // .in_range( + // &Position::new(0, 0), + // &Position::new( + // self.map.width as PositionType, + // self.map.height as PositionType, + // ), + // ) + // .is_some() + // { + // return 0; + // } - let v = t.iter().flatten(); + // if self.map.get(next.x as usize, next.y as usize).blocked { + // return 0; + // } - v.count() - } + // let mut count = 3; + + // for l in 2..=6 { + // let n = node.0.in_direction(&node.1, l); + // dbg!(n, l); + // if n.in_range( + // &Position::new(0, 0), + // &Position::new( + // self.map.width as PositionType, + // self.map.height as PositionType, + // ), + // ) + // .is_some() + // { + // return count; + // } + // if !self.map.get(n.x as usize, n.y as usize).blocked { + // count += 1; + // } + // } + + // count } fn edge(&self, node: &Self::Node, num: usize) -> Option<(Self::Node, f64)> { - let t = self.get_direction(*node); - - t.iter() - .flatten() - .nth(num) - .map(|&p| (p, self.map.get(p.x as usize, p.y as usize).wheight)) + let next = node.0.in_direction(&node.1, 1); + if next + .in_range( + &Position::new(0, 0), + &Position::new( + self.map.width as PositionType, + self.map.height as PositionType, + ), + ) + .is_none() + { + return None; + } + if self.map.get(next.x as usize, next.y as usize).blocked && self.end != (next, node.1) { + return None; + } + match num { + 0 => Some(((next, node.1), 1.5)), + 1 => Some(((next, node.1.counter_clockwise()), 1.5)), + 2 => Some(((next, node.1.clockwise()), 1.5)), + _ => { + let mut count = 2; + for l in 2..=6 { + let n = node.0.in_direction(&node.1, l); + if n.in_range( + &Position::new(0, 0), + &Position::new( + self.map.width as PositionType, + self.map.height as PositionType, + ), + ) + .is_none() + { + return None; + } + if !self.map.get(n.x as usize, n.y as usize).blocked { + count += 1; + if count == num { + return Some(((n, node.1), 17.5)); + } + } + } + None + } + } } } @@ -211,13 +253,11 @@ impl Problem { pub fn find_path(&mut self) { for i in 0..self.start.len() { self.calculate_wheights(i); - let m = MapInternal { map: &self.map }; - let p = dijkstra::>( - &m, - self.start[i].0.in_direction(&self.start[i].1, 1), - self.end[i].0.in_direction(&self.end[i].1, -1), - ); - + let m = MapInternal { + map: &self.map, + end: self.end[i], + }; + let p = dijkstra::>(&m, self.start[i], self.end[i]); if let Some(p) = p { self.path[i] = p; } @@ -231,6 +271,19 @@ pub mod problems { Problem, }; + pub fn simple() -> Problem { + let mut p = Problem::new(5, 3); + + p.set_blocked_range(2, 0, 2, 2, true); + + p.add_connection( + (Position::new(0, 1), Direction::Right), + (Position::new(4, 1), Direction::Right), + ); + + p + } + pub fn belt_madness_level_1() -> Problem { let mut p = Problem::new(17, 13); @@ -264,20 +317,20 @@ pub mod problems { p.add_connection( (Position::new(2, 7), Direction::Right), - (Position::new(14, 4), Direction::Right), + (Position::new(13, 4), Direction::Right), ); p.add_connection( (Position::new(2, 8), Direction::Right), - (Position::new(14, 5), Direction::Right), + (Position::new(13, 5), Direction::Right), ); p.add_connection( (Position::new(2, 4), Direction::Right), - (Position::new(14, 8), Direction::Right), + (Position::new(13, 8), Direction::Right), ); p.add_connection( (Position::new(2, 5), Direction::Right), - (Position::new(14, 7), Direction::Right), + (Position::new(13, 7), Direction::Right), ); p @@ -301,36 +354,36 @@ pub mod problems { p.add_connection( (Position::new(2, 4), Direction::Right), - (Position::new(14, 2), Direction::Right), + (Position::new(13, 2), Direction::Right), ); p.add_connection( (Position::new(2, 7), Direction::Right), - (Position::new(14, 3), Direction::Right), + (Position::new(13, 3), Direction::Right), ); p.add_connection( (Position::new(2, 10), Direction::Right), - (Position::new(14, 4), Direction::Right), + (Position::new(13, 4), Direction::Right), ); p.add_connection( (Position::new(2, 9), Direction::Right), - (Position::new(14, 5), Direction::Right), + (Position::new(13, 5), Direction::Right), ); p.add_connection( (Position::new(2, 2), Direction::Right), - (Position::new(14, 7), Direction::Right), + (Position::new(13, 7), Direction::Right), ); p.add_connection( (Position::new(2, 3), Direction::Right), - (Position::new(14, 8), Direction::Right), + (Position::new(13, 8), Direction::Right), ); p.add_connection( (Position::new(2, 5), Direction::Right), - (Position::new(14, 9), Direction::Right), + (Position::new(13, 9), Direction::Right), ); p.add_connection( (Position::new(2, 8), Direction::Right), - (Position::new(14, 10), Direction::Right), + (Position::new(13, 10), Direction::Right), ); p @@ -473,59 +526,59 @@ pub mod problems { // Path p.add_connection( (Position::new(4, 2), Direction::Down), - (Position::new(26, 26), Direction::Down), + (Position::new(26, 25), Direction::Down), ); p.add_connection( (Position::new(12, 2), Direction::Down), - (Position::new(18, 26), Direction::Down), + (Position::new(18, 25), Direction::Down), ); p.add_connection( (Position::new(14, 2), Direction::Down), - (Position::new(2, 26), Direction::Left), + (Position::new(3, 26), Direction::Left), ); p.add_connection( (Position::new(16, 2), Direction::Down), - (Position::new(14, 26), Direction::Down), + (Position::new(14, 25), Direction::Down), ); p.add_connection( (Position::new(2, 4), Direction::Right), - (Position::new(28, 24), Direction::Right), + (Position::new(27, 24), Direction::Right), ); p.add_connection( (Position::new(2, 11), Direction::Right), - (Position::new(28, 17), Direction::Right), + (Position::new(27, 17), Direction::Right), ); p.add_connection( (Position::new(2, 13), Direction::Right), - (Position::new(28, 26), Direction::Right), + (Position::new(27, 26), Direction::Right), ); p.add_connection( (Position::new(2, 15), Direction::Right), - (Position::new(28, 13), Direction::Right), + (Position::new(27, 13), Direction::Right), ); p.add_connection( (Position::new(28, 15), Direction::Left), - (Position::new(2, 2), Direction::Up), + (Position::new(2, 3), Direction::Up), ); p.add_connection( (Position::new(2, 17), Direction::Right), - (Position::new(18, 2), Direction::Up), + (Position::new(18, 3), Direction::Up), ); p.add_connection( (Position::new(2, 24), Direction::Right), - (Position::new(26, 2), Direction::Up), + (Position::new(26, 3), Direction::Up), ); p.add_connection( (Position::new(4, 26), Direction::Up), - (Position::new(28, 4), Direction::Right), + (Position::new(27, 4), Direction::Right), ); p.add_connection( (Position::new(12, 26), Direction::Up), - (Position::new(28, 11), Direction::Right), + (Position::new(27, 11), Direction::Right), ); p.add_connection( (Position::new(16, 26), Direction::Up), - (Position::new(28, 2), Direction::Up), + (Position::new(28, 3), Direction::Up), ); p