Initial commit; board grid is defined

This commit is contained in:
Joel Therrien 2023-07-21 20:18:06 -07:00
commit b874bb99d4
3 changed files with 145 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/target
/Cargo.lock
.idea/

8
Cargo.toml Normal file
View file

@ -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]

134
src/lib.rs Normal file
View file

@ -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<Letter>,
cell_type: CellType,
}
#[derive(Debug)]
struct Board {
cells: Vec<Cell>,
}
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));
}
}