diff --git a/README.md b/README.md index 7fca26b..b3edf29 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # yayagram - Play nonograms/picross in your terminal -**yayagram** is a puzzle game in which you fill out a grid with cells based on logic and number clues. +**yayagram** is a puzzle game in which you fill out a grid with cells based on logic and number clues in your terminal. The game goes by many names: nonogram, picross, paint by numbers, griddlers, pic-a-pix, hanjie and others. @@ -23,7 +23,7 @@ Binaries are also provided in the [Releases](https://github.com/r00ster91/yayagr * Runs in the terminal! * Cross-platform: runs on Linux and macOS. -* Helpful features and tools like undo, redo and clear. +* Helpful features and tools like undo, redo and, clear. * Random grids. * Custom grids: [create your own grids](#Editor) for others to play. * A new kind of cell: [maybed](#Maybed). diff --git a/src/editor.rs b/src/editor.rs index 8104677..9339505 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -57,7 +57,7 @@ impl Editor { help[2] = Some("?: maybed"); "????" // Represents unclearness. } - Cell::Measured(_) => { + Cell::Measured(_, _) => { help[3] = Some("R: measured"); "RRRR" // Resembles 尺 which is a unit of measure. } @@ -206,7 +206,7 @@ fn deserialize(str: &str) -> Result<(Size, Vec), LoadError> { '1' => Cell::Filled, 'X' => Cell::Crossed, '?' => Cell::Maybed, - 'R' => Cell::Measured(None), + 'R' => Cell::Measured(None, None), _ => { return Err(LoadError { message: "expected ' ', '1', 'X', '?' or 'R'", diff --git a/src/grid.rs b/src/grid.rs index 5e81466..761311f 100644 --- a/src/grid.rs +++ b/src/grid.rs @@ -23,6 +23,7 @@ pub struct Grid { pub vertical_clues_solutions: Vec, pub max_clues_size: Size, pub undo_redo_buffer: UndoRedoBuffer, + pub measurement_counter: usize, } fn get_index(grid_width: u16, point: Point) -> usize { @@ -90,6 +91,8 @@ impl Grid { let undo_redo_buffer = UndoRedoBuffer::default(); + let measurement_counter = 0; + Self { size, cells, @@ -97,6 +100,7 @@ impl Grid { vertical_clues_solutions, max_clues_size, undo_redo_buffer, + measurement_counter, } } diff --git a/src/grid/cell.rs b/src/grid/cell.rs index caa2a42..cda6637 100644 --- a/src/grid/cell.rs +++ b/src/grid/cell.rs @@ -16,9 +16,14 @@ pub enum Cell { /// Used to mark cells that are certainly empty. Crossed, /// Used for indicating cells that were measured using the measurement tool. + /// The first element of this tuple, the index, is a number shown on the cell. /// - /// When this cell is saved, the index is not preserved. - Measured(Option), + /// When this cell is saved, the index is not preserved and therefore the index can be null. + /// + /// The second element is a measurement counter. On each new measurement added, the counter is incremented. + /// We use the measurement counter to make measurement cells disappear after a while. + /// Use None for them to never disappear. + Measured(Option, Option), } impl Default for Cell { @@ -40,7 +45,7 @@ impl Cell { Cell::Filled => Color::White, Cell::Maybed => Color::Blue, Cell::Crossed => Color::Red, - Cell::Measured(_) => Color::Green, + Cell::Measured(_, _) => Color::Green, } } @@ -50,7 +55,7 @@ impl Cell { Cell::Filled => Color::Gray, Cell::Maybed => Color::DarkBlue, Cell::Crossed => Color::DarkRed, - Cell::Measured(_) => Color::DarkGreen, + Cell::Measured(_, _) => Color::DarkGreen, } } @@ -95,7 +100,7 @@ impl Cell { (None, background_color, " ".into()) } - Cell::Measured(index) => { + Cell::Measured(index, _) => { let (foreground_color, content) = if let Some(index) = index { (Some(Color::Black), format!("{:>2}", index).into()) } else { @@ -130,13 +135,27 @@ pub const fn get_cell_point_from_cursor_point(cursor_point: Point, builder: &Bui } pub fn set_measured_cells(grid: &mut Grid, line_points: &[Point]) { + let measurement_counter = grid.measurement_counter; for (index, point) in line_points.iter().enumerate() { let cell = grid.get_mut_cell(*point); + if let Cell::Empty | Cell::Measured(_, _) = cell { + *cell = Cell::Measured(Some(index + 1), Some(measurement_counter)); + } + } - if let Cell::Empty | Cell::Measured(_) = cell { - *cell = Cell::Measured(Some(index + 1)); + // We want to clean up old measurement lines after a while to avoid cluttering up the grid with green cells, + // so we'll only allow a certain amount of lines at a time. + let allowed_count = 2; + for cell in &mut grid.cells { + if let Cell::Measured(_, Some(measurement_counter)) = *cell { + if grid.measurement_counter >= allowed_count + && measurement_counter == grid.measurement_counter - allowed_count + { + *cell = Cell::Empty; + } } } + grid.measurement_counter += 1; } pub fn draw_highlighted_cells( diff --git a/src/grid/tools/fill.rs b/src/grid/tools/fill.rs index a4f6915..2893e5c 100644 --- a/src/grid/tools/fill.rs +++ b/src/grid/tools/fill.rs @@ -6,7 +6,7 @@ pub fn fill(grid: &mut Grid, point: Point, first_cell: Cell, fill_cell: Cell) { // We want to fill multiple measured cells as one, regardless of the index let measured_cell = - matches!(*cell, Cell::Measured(_)) && matches!(first_cell, Cell::Measured(_)); + matches!(*cell, Cell::Measured(_, _)) && matches!(first_cell, Cell::Measured(_, _)); if *cell == first_cell || measured_cell { *cell = fill_cell;