use std::fmt;
pub struct Grid {
cells: Vec<Vec<char>>,
protected: Vec<Vec<bool>>,
pub width: usize,
pub height: usize,
}
impl Grid {
pub fn new(width: usize, height: usize) -> Self {
Self {
cells: vec![vec![' '; width]; height],
protected: vec![vec![false; width]; height],
width,
height,
}
}
pub fn set(&mut self, x: usize, y: usize, c: char) {
if x < self.width && y < self.height {
self.cells[y][x] = c;
}
}
#[allow(dead_code)]
pub fn set_protected(&mut self, x: usize, y: usize, c: char) {
if x < self.width && y < self.height {
self.cells[y][x] = c;
self.protected[y][x] = true;
}
}
pub fn mark_protected(&mut self, x: usize, y: usize) {
if x < self.width && y < self.height {
self.protected[y][x] = true;
}
}
pub fn set_if_empty(&mut self, x: usize, y: usize, c: char) -> bool {
if x < self.width && y < self.height && !self.protected[y][x] {
self.cells[y][x] = c;
return true;
}
false
}
#[allow(dead_code)]
pub fn is_protected(&self, x: usize, y: usize) -> bool {
if x < self.width && y < self.height {
self.protected[y][x]
} else {
true }
}
#[allow(dead_code)]
pub fn get(&self, x: usize, y: usize) -> Option<char> {
if x < self.width && y < self.height {
Some(self.cells[y][x])
} else {
None
}
}
}
impl fmt::Display for Grid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for (i, row) in self.cells.iter().enumerate() {
let line: String = row.iter().collect();
write!(f, "{}", line)?;
if i < self.cells.len() - 1 {
writeln!(f)?;
}
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_grid_creation() {
let grid = Grid::new(5, 3);
assert_eq!(grid.width, 5);
assert_eq!(grid.height, 3);
}
#[test]
fn test_grid_set_get() {
let mut grid = Grid::new(5, 3);
grid.set(2, 1, 'X');
assert_eq!(grid.get(2, 1), Some('X'));
assert_eq!(grid.get(0, 0), Some(' '));
}
#[test]
fn test_grid_bounds_check() {
let mut grid = Grid::new(5, 3);
grid.set(10, 10, 'X'); assert_eq!(grid.get(10, 10), None);
}
#[test]
fn test_grid_display() {
let mut grid = Grid::new(3, 2);
grid.set(0, 0, 'A');
grid.set(2, 1, 'B');
let s = grid.to_string();
assert_eq!(s, "A \n B");
}
#[test]
fn test_grid_protected() {
let mut grid = Grid::new(5, 3);
grid.set_protected(2, 1, 'N'); assert!(grid.is_protected(2, 1));
let written = grid.set_if_empty(2, 1, '│');
assert!(!written);
assert_eq!(grid.get(2, 1), Some('N')); }
#[test]
fn test_grid_set_if_empty() {
let mut grid = Grid::new(5, 3);
let written = grid.set_if_empty(1, 1, '─');
assert!(written);
assert_eq!(grid.get(1, 1), Some('─'));
}
}