commit b874bb99d411ee23f9ac27a13ef5d39913da5341 Author: Joel Therrien Date: Fri Jul 21 20:18:06 2023 -0700 Initial commit; board grid is defined diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..91b8835 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +/Cargo.lock +.idea/ diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..aa2112a --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "WordGrid" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..9b2d479 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,134 @@ +const GRID_LENGTH: u8 = 15; +const TRAY_LENGTH: u8 = 7; +const ALL_LETTERS_BONUS: u32 = 50; + +#[derive(Debug)] +enum Letter { + FixedLetter{text: char, points: u32}, + Blank(char) +} + +#[derive(Debug)] +enum CellType { + Normal, + DoubleWord, + DoubleLetter, + TripleLetter, + TripleWord, + Start, +} + +#[derive(Debug)] +struct Cell { + value: Option, + cell_type: CellType, +} + +#[derive(Debug)] +struct Board { + cells: Vec, +} + + +impl Board { + fn new() -> Self { + let mut cells = Vec::new(); + + + /// Since the board is symmetrical in both directions for the purposes of our logic we can keep our coordinates in one corner + /// + /// # Arguments + /// + /// * `x`: A coordinate + /// + /// returns: u8 The coordinate mapped onto the lower-half + fn map_to_corner(x: u8) -> u8 { + return if x > GRID_LENGTH / 2 { + GRID_LENGTH - x - 1 + } else { + x + } + } + + for i in 0..GRID_LENGTH { + let i = map_to_corner(i); + for j in 0..GRID_LENGTH { + let j = map_to_corner(j); + + let mut typee = CellType::Normal; + + // double word scores are diagonals + if i == j { + typee = CellType::DoubleWord; + } + + // Triple letters + if (i % 4 == 1) && j % 4 == 1 && !(i == 1 && j == 1) { + typee = CellType::TripleLetter; + } + + // Double letters + if (i % 4 == 2) && (j % 4 == 2) && !( + i == 2 && j == 2 + ) { + typee = CellType::DoubleLetter; + } + if (i.min(j) == 0 && i.max(j) == 3) || (i.min(j)==3 && i.max(j) == 7) { + typee = CellType::DoubleLetter; + } + + // Triple word scores + if (i % 7 == 0) && (j % 7 == 0) { + typee = CellType::TripleWord; + } + + // Start + if i == 7 && j == 7 { + typee = CellType::Start; + } + + cells.push(Cell { + cell_type: typee, + value: None, + }) + + } + } + + Board {cells} + } + + fn get_cell(&self, x: u8, y: u8) -> Result<&Cell, &str> { + if x >= GRID_LENGTH || y >= GRID_LENGTH { + Err("x & y must be within the board's coordinates") + } else { + let coord = (x + GRID_LENGTH*y) as usize; + Ok(self.cells.get(coord).unwrap()) + } + } +} + + + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_cell_types() { + let board = Board::new(); + + assert!(matches!(board.get_cell(0, 0).unwrap().cell_type, CellType::TripleWord)); + assert!(matches!(board.get_cell(1, 0).unwrap().cell_type, CellType::Normal)); + assert!(matches!(board.get_cell(0, 1).unwrap().cell_type, CellType::Normal)); + assert!(matches!(board.get_cell(1, 1).unwrap().cell_type, CellType::DoubleWord)); + + assert!(matches!(board.get_cell(13, 13).unwrap().cell_type, CellType::DoubleWord)); + assert!(matches!(board.get_cell(14, 14).unwrap().cell_type, CellType::TripleWord)); + assert!(matches!(board.get_cell(11, 14).unwrap().cell_type, CellType::DoubleLetter)); + + assert!(matches!(board.get_cell(7, 7).unwrap().cell_type, CellType::Start)); + assert!(matches!(board.get_cell(8, 6).unwrap().cell_type, CellType::DoubleLetter)); + assert!(matches!(board.get_cell(5, 9).unwrap().cell_type, CellType::TripleLetter)); + } +}