diff --git a/cspuz_solver_backend/src/board.rs b/cspuz_solver_backend/src/board.rs index 88ecd132..43f87a01 100644 --- a/cspuz_solver_backend/src/board.rs +++ b/cspuz_solver_backend/src/board.rs @@ -421,6 +421,86 @@ impl Board { } } + /// Renders grid edges (for puzzles like Slitherlink, Litherslink, Crosswall). + /// + /// This helper function adds edge items to the board based on a GridEdges structure. + /// - Vertical edges are rendered at positions (y * 2 + 1, x * 2) + /// - Horizontal edges are rendered at positions (y * 2, x * 2 + 1) + /// + /// # Arguments + /// * `edges` - The grid edges to render (with .vertical and .horizontal fields) + /// * `color` - Color to use for the rendered edges + /// * `true_kind` - ItemKind to use when edge value is true + /// * `false_kind` - ItemKind to use when edge value is false + pub fn add_grid_edges( + &mut self, + edges: &graph::GridEdges>>>, + color: &'static str, + true_kind: ItemKind, + false_kind: ItemKind, + ) { + let height = self.height; + let width = self.width; + + // Render vertical edges + for y in 0..height { + for x in 0..=width { + if let Some(b) = edges.vertical[y][x] { + self.push(Item { + y: y * 2 + 1, + x: x * 2, + color, + kind: if b { true_kind.clone() } else { false_kind.clone() }, + }); + } + } + } + + // Render horizontal edges + for y in 0..=height { + for x in 0..width { + if let Some(b) = edges.horizontal[y][x] { + self.push(Item { + y: y * 2, + x: x * 2 + 1, + color, + kind: if b { true_kind.clone() } else { false_kind.clone() }, + }); + } + } + } + } + + /// Renders Block/Dot items based on boolean answer grid (for region-based puzzles). + /// + /// This helper function adds Block or Dot items to the board for cells that have + /// determined values in the answer grid. + /// + /// # Arguments + /// * `is_black` - Answer grid with Option values + /// * `color` - Color to use for the rendered items + pub fn add_block_dot_answer( + &mut self, + is_black: &Vec>>, + color: &'static str, + ) { + let height = self.height; + let width = self.width; + + for y in 0..height { + for x in 0..width { + if let Some(b) = is_black[y][x] { + self.push(Item::cell( + y, + x, + color, + if b { ItemKind::Block } else { ItemKind::Dot }, + )); + } + } + } + } + pub fn to_json(&self) -> String { let kind = "grid"; let height = self.height; diff --git a/cspuz_solver_backend/src/puzzle/akichiwake.rs b/cspuz_solver_backend/src/puzzle/akichiwake.rs index c99a9ed5..4fab903a 100644 --- a/cspuz_solver_backend/src/puzzle/akichiwake.rs +++ b/cspuz_solver_backend/src/puzzle/akichiwake.rs @@ -25,19 +25,8 @@ pub fn solve(url: &str) -> Result { board.add_borders(&borders, "black"); - for y in 0..height { - for x in 0..width { - if let Some(is_black) = &is_black { - if let Some(b) = is_black[y][x] { - board.push(Item::cell( - y, - x, - "green", - if b { ItemKind::Block } else { ItemKind::Dot }, - )); - } - } - } + if let Some(is_black) = &is_black { + board.add_block_dot_answer(is_black, "green"); } let rooms = graph::borders_to_rooms(&borders); assert_eq!(rooms.len(), clues.len()); diff --git a/cspuz_solver_backend/src/puzzle/aqre.rs b/cspuz_solver_backend/src/puzzle/aqre.rs index 8423d089..eee48806 100644 --- a/cspuz_solver_backend/src/puzzle/aqre.rs +++ b/cspuz_solver_backend/src/puzzle/aqre.rs @@ -25,19 +25,8 @@ pub fn solve(url: &str) -> Result { board.add_borders(&borders, "black"); - for y in 0..height { - for x in 0..width { - if let Some(is_black) = &is_black { - if let Some(b) = is_black[y][x] { - board.push(Item::cell( - y, - x, - "green", - if b { ItemKind::Block } else { ItemKind::Dot }, - )); - } - } - } + if let Some(is_black) = &is_black { + board.add_block_dot_answer(is_black, "green"); } let rooms = graph::borders_to_rooms(&borders); assert_eq!(rooms.len(), clues.len()); diff --git a/cspuz_solver_backend/src/puzzle/chocona.rs b/cspuz_solver_backend/src/puzzle/chocona.rs index 448895cc..d42f0162 100644 --- a/cspuz_solver_backend/src/puzzle/chocona.rs +++ b/cspuz_solver_backend/src/puzzle/chocona.rs @@ -25,18 +25,7 @@ pub fn solve(url: &str) -> Result { board.add_borders(&borders, "black"); if let Some(is_black) = &is_black { - for y in 0..height { - for x in 0..width { - if let Some(b) = is_black[y][x] { - board.push(Item::cell( - y, - x, - "green", - if b { ItemKind::Block } else { ItemKind::Dot }, - )); - } - } - } + board.add_block_dot_answer(is_black, "green"); } let rooms = graph::borders_to_rooms(&borders); assert_eq!(rooms.len(), clues.len()); diff --git a/cspuz_solver_backend/src/puzzle/cocktail.rs b/cspuz_solver_backend/src/puzzle/cocktail.rs index d1feb380..7fc82830 100644 --- a/cspuz_solver_backend/src/puzzle/cocktail.rs +++ b/cspuz_solver_backend/src/puzzle/cocktail.rs @@ -21,19 +21,8 @@ pub fn solve(url: &str) -> Result { board.add_borders(&borders, "black"); - if let Some(is_black) = is_black { - for y in 0..height { - for x in 0..width { - if let Some(b) = is_black[y][x] { - board.push(Item::cell( - y, - x, - "green", - if b { ItemKind::Block } else { ItemKind::Dot }, - )); - } - } - } + if let Some(is_black) = &is_black { + board.add_block_dot_answer(is_black, "green"); } let rooms = graph::borders_to_rooms(&borders); diff --git a/cspuz_solver_backend/src/puzzle/crosswall.rs b/cspuz_solver_backend/src/puzzle/crosswall.rs index a194f044..a4e60e97 100644 --- a/cspuz_solver_backend/src/puzzle/crosswall.rs +++ b/cspuz_solver_backend/src/puzzle/crosswall.rs @@ -28,31 +28,8 @@ pub fn solve(url: &str) -> Result { } } - if let Some(is_line) = ans { - for y in 0..height { - for x in 0..=width { - if let Some(b) = is_line.vertical[y][x] { - board.push(Item { - y: y * 2 + 1, - x: x * 2, - color: "green", - kind: if b { ItemKind::Wall } else { ItemKind::Cross }, - }) - } - } - } - for y in 0..=height { - for x in 0..width { - if let Some(b) = is_line.horizontal[y][x] { - board.push(Item { - y: y * 2, - x: x * 2 + 1, - color: "green", - kind: if b { ItemKind::Wall } else { ItemKind::Cross }, - }) - } - } - } + if let Some(is_line) = &ans { + board.add_grid_edges(is_line, "green", ItemKind::Wall, ItemKind::Cross); } Ok(board) diff --git a/cspuz_solver_backend/src/puzzle/double_lits.rs b/cspuz_solver_backend/src/puzzle/double_lits.rs index c500f327..4800da6e 100644 --- a/cspuz_solver_backend/src/puzzle/double_lits.rs +++ b/cspuz_solver_backend/src/puzzle/double_lits.rs @@ -21,19 +21,8 @@ pub fn solve(url: &str) -> Result { board.add_borders(&borders, "black"); - if let Some(is_black) = ans { - for y in 0..height { - for x in 0..width { - if let Some(b) = is_black[y][x] { - board.push(Item::cell( - y, - x, - "green", - if b { ItemKind::Block } else { ItemKind::Dot }, - )); - } - } - } + if let Some(is_black) = &ans { + board.add_block_dot_answer(is_black, "green"); } Ok(board) diff --git a/cspuz_solver_backend/src/puzzle/heyawake_internal.rs b/cspuz_solver_backend/src/puzzle/heyawake_internal.rs index caadeb25..a695b6d6 100644 --- a/cspuz_solver_backend/src/puzzle/heyawake_internal.rs +++ b/cspuz_solver_backend/src/puzzle/heyawake_internal.rs @@ -41,19 +41,8 @@ pub fn solve(url: &str, is_ayeheya: bool) -> Result { board.add_borders(&borders, "black"); - for y in 0..height { - for x in 0..width { - if let Some(is_black) = &is_black { - if let Some(b) = is_black[y][x] { - board.push(Item::cell( - y, - x, - "green", - if b { ItemKind::Block } else { ItemKind::Dot }, - )); - } - } - } + if let Some(is_black) = &is_black { + board.add_block_dot_answer(is_black, "green"); } let rooms = graph::borders_to_rooms(&borders); assert_eq!(rooms.len(), clues.len()); diff --git a/cspuz_solver_backend/src/puzzle/inverse_litso.rs b/cspuz_solver_backend/src/puzzle/inverse_litso.rs index 94d15837..121f961e 100644 --- a/cspuz_solver_backend/src/puzzle/inverse_litso.rs +++ b/cspuz_solver_backend/src/puzzle/inverse_litso.rs @@ -24,18 +24,7 @@ pub fn solve(url: &str) -> Result { board.add_borders(&borders, "black"); if let Some(is_black) = &is_black { - for y in 0..height { - for x in 0..width { - if let Some(b) = is_black[y][x] { - board.push(Item::cell( - y, - x, - "green", - if b { ItemKind::Block } else { ItemKind::Dot }, - )); - } - } - } + board.add_block_dot_answer(is_black, "green"); } Ok(board) diff --git a/cspuz_solver_backend/src/puzzle/litherslink.rs b/cspuz_solver_backend/src/puzzle/litherslink.rs index 808d8c5f..24ea4bba 100644 --- a/cspuz_solver_backend/src/puzzle/litherslink.rs +++ b/cspuz_solver_backend/src/puzzle/litherslink.rs @@ -23,30 +23,7 @@ pub fn solve(url: &str) -> Result { } } if let Some(is_line) = &ans { - for y in 0..height { - for x in 0..=width { - if let Some(b) = is_line.vertical[y][x] { - board.push(Item { - y: y * 2 + 1, - x: x * 2, - color: "green", - kind: if b { ItemKind::Wall } else { ItemKind::Cross }, - }) - } - } - } - for y in 0..=height { - for x in 0..width { - if let Some(b) = is_line.horizontal[y][x] { - board.push(Item { - y: y * 2, - x: x * 2 + 1, - color: "green", - kind: if b { ItemKind::Wall } else { ItemKind::Cross }, - }) - } - } - } + board.add_grid_edges(is_line, "green", ItemKind::Wall, ItemKind::Cross); } Ok(board) diff --git a/cspuz_solver_backend/src/puzzle/lits.rs b/cspuz_solver_backend/src/puzzle/lits.rs index 5f1405e2..15d7266e 100644 --- a/cspuz_solver_backend/src/puzzle/lits.rs +++ b/cspuz_solver_backend/src/puzzle/lits.rs @@ -22,18 +22,7 @@ pub fn solve(url: &str) -> Result { board.add_borders(&borders, "black"); if let Some(is_black) = &ans { - for y in 0..height { - for x in 0..width { - if let Some(b) = is_black[y][x] { - board.push(Item::cell( - y, - x, - "green", - if b { ItemKind::Block } else { ItemKind::Dot }, - )); - } - } - } + board.add_block_dot_answer(is_black, "green"); } Ok(board) diff --git a/cspuz_solver_backend/src/puzzle/norinori.rs b/cspuz_solver_backend/src/puzzle/norinori.rs index d6ac4258..0b53910a 100644 --- a/cspuz_solver_backend/src/puzzle/norinori.rs +++ b/cspuz_solver_backend/src/puzzle/norinori.rs @@ -18,18 +18,7 @@ pub fn solve(url: &str) -> Result { board.add_borders(&borders, "black"); if let Some(is_black) = &ans { - for y in 0..height { - for x in 0..width { - if let Some(b) = is_black[y][x] { - board.push(Item::cell( - y, - x, - "green", - if b { ItemKind::Block } else { ItemKind::Dot }, - )); - } - } - } + board.add_block_dot_answer(is_black, "green"); } Ok(board) diff --git a/cspuz_solver_backend/src/puzzle/nuritwin.rs b/cspuz_solver_backend/src/puzzle/nuritwin.rs index 234a6283..be235edf 100644 --- a/cspuz_solver_backend/src/puzzle/nuritwin.rs +++ b/cspuz_solver_backend/src/puzzle/nuritwin.rs @@ -18,18 +18,7 @@ pub fn solve(url: &str) -> Result { board.add_borders(&borders, "black"); if let Some(is_black) = &ans { - for y in 0..height { - for x in 0..width { - if let Some(b) = is_black[y][x] { - board.push(Item::cell( - y, - x, - "green", - if b { ItemKind::Block } else { ItemKind::Dot }, - )); - } - } - } + board.add_block_dot_answer(is_black, "green"); } let rooms = graph::borders_to_rooms(&borders); assert_eq!(rooms.len(), clues.len()); diff --git a/cspuz_solver_backend/src/puzzle/shimaguni.rs b/cspuz_solver_backend/src/puzzle/shimaguni.rs index eb438555..1df1a3a7 100644 --- a/cspuz_solver_backend/src/puzzle/shimaguni.rs +++ b/cspuz_solver_backend/src/puzzle/shimaguni.rs @@ -21,18 +21,7 @@ pub fn solve(url: &str) -> Result { board.add_borders(&borders, "black"); if let Some(is_black) = &is_black { - for y in 0..height { - for x in 0..width { - if let Some(b) = is_black[y][x] { - board.push(Item::cell( - y, - x, - "green", - if b { ItemKind::Block } else { ItemKind::Dot }, - )); - } - } - } + board.add_block_dot_answer(is_black, "green"); } let rooms = graph::borders_to_rooms(&borders); assert_eq!(rooms.len(), clues.len()); diff --git a/cspuz_solver_backend/src/puzzle/slitherlink.rs b/cspuz_solver_backend/src/puzzle/slitherlink.rs index 9c9bb314..0afd283f 100644 --- a/cspuz_solver_backend/src/puzzle/slitherlink.rs +++ b/cspuz_solver_backend/src/puzzle/slitherlink.rs @@ -29,30 +29,7 @@ pub fn solve(url: &str) -> Result { } } if let Some(is_line) = &is_line { - for y in 0..height { - for x in 0..=width { - if let Some(b) = is_line.vertical[y][x] { - board.push(Item { - y: y * 2 + 1, - x: x * 2, - color: "green", - kind: if b { ItemKind::Wall } else { ItemKind::Cross }, - }) - } - } - } - for y in 0..=height { - for x in 0..width { - if let Some(b) = is_line.horizontal[y][x] { - board.push(Item { - y: y * 2, - x: x * 2 + 1, - color: "green", - kind: if b { ItemKind::Wall } else { ItemKind::Cross }, - }) - } - } - } + board.add_grid_edges(is_line, "green", ItemKind::Wall, ItemKind::Cross); } Ok(board) diff --git a/cspuz_solver_backend/src/puzzle/stostone.rs b/cspuz_solver_backend/src/puzzle/stostone.rs index 6c4eb4d2..0a8d7b8f 100644 --- a/cspuz_solver_backend/src/puzzle/stostone.rs +++ b/cspuz_solver_backend/src/puzzle/stostone.rs @@ -21,18 +21,7 @@ pub fn solve(url: &str) -> Result { board.add_borders(&borders, "black"); if let Some(is_black) = &is_black { - for y in 0..height { - for x in 0..width { - if let Some(b) = is_black[y][x] { - board.push(Item::cell( - y, - x, - "green", - if b { ItemKind::Block } else { ItemKind::Dot }, - )); - } - } - } + board.add_block_dot_answer(is_black, "green"); } let rooms = graph::borders_to_rooms(&borders); assert_eq!(rooms.len(), clues.len()); diff --git a/cspuz_solver_backend/src/puzzle/yajilin_regions.rs b/cspuz_solver_backend/src/puzzle/yajilin_regions.rs index dedd32f9..15ba1242 100644 --- a/cspuz_solver_backend/src/puzzle/yajilin_regions.rs +++ b/cspuz_solver_backend/src/puzzle/yajilin_regions.rs @@ -37,18 +37,7 @@ pub fn solve(url: &str) -> Result { board.add_borders(&borders, "black"); if let Some((ref is_line, ref is_black)) = ans { - for y in 0..height { - for x in 0..width { - if let Some(b) = is_black[y][x] { - board.push(Item::cell( - y, - x, - "green", - if b { ItemKind::Block } else { ItemKind::Dot }, - )); - } - } - } + board.add_block_dot_answer(is_black, "green"); let mut skip_line = vec![]; for y in 0..height {