diff --git a/src/agent.rs b/src/agent.rs new file mode 100644 index 0000000..acd9df7 --- /dev/null +++ b/src/agent.rs @@ -0,0 +1,15 @@ +use crate::repr::Piece; + +pub struct Agent { + color: Piece, +} + +impl Agent { + pub const fn new(color: Piece) -> Self { + Self { color } + } + + pub fn next_move() -> (usize, usize) { + todo!("next_move not implemented") + } +} diff --git a/src/main.rs b/src/main.rs index 71b2fcc..a106cd9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +mod agent; mod repr; fn main() { diff --git a/src/repr.rs b/src/repr.rs index 63de19e..bf12bed 100644 --- a/src/repr.rs +++ b/src/repr.rs @@ -1,4 +1,4 @@ -#[derive(Copy, Clone)] +#[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum Piece { Black, White, @@ -30,15 +30,118 @@ impl Board { &self.board[i][j] } + fn place_unchecked(&mut self, i: usize, j: usize, piece: Piece) { + *self.get_mut(i, j) = Some(piece); + } + + // TODO! make this better and actually readable + // TODO! propegate from propegated pieces + fn propegate_from(&mut self, i: usize, j: usize) { + // returns if that place is empty + let Some(starting_color) = self.get(i, j).clone() else { + return; + }; + + // both ranges expand __from__ the piece + let i_ranges: Vec> = + vec![(0..i).rev().collect(), ((i + 1)..BOARD_SIZE).collect()]; + let j_ranges: Vec> = + vec![(0..j).rev().collect(), ((j + 1)..BOARD_SIZE).collect()]; + + for i_range in i_ranges { + let mut chain_length: usize = 0; + for new_i in i_range { + match self.get(new_i, j) { + Some(piece) => { + if piece == &starting_color { + if chain_length > 0 { + todo!("matching end") + } + break; + } else { + todo!("add to the chain"); + } + } + None => break, + } + } + } + + for j_range in j_ranges { + for new_j in j_range {} + } + + todo!("propegation is not implemented"); + } + + fn place_and_prop_unchecked(&mut self, i: usize, j: usize, piece: Piece) { + self.place_unchecked(i, j, piece); + self.propegate_from(i, j); + } + /// Place a piece on the [`Board`] /// Returns an error if there already exists a piece there pub fn place(&mut self, i: usize, j: usize, piece: Piece) -> Result<(), String> { if self.get(i, j).is_some() { return Err(format!("Cannot place on ({},{}), piece exists", i, j)); } else { - *self.get_mut(i, j) = Some(piece); + self.place_and_prop_unchecked(i, j, piece); } Ok(()) } } + +#[cfg(test)] +mod test { + use super::*; + #[test] + fn place_and_get() { + let mut board = Board::new(); + assert_eq!(board.get(0, 0), &None); + assert_eq!( + board.place(0, 0, Piece::Black), + Ok(()), + "placing black on (0, 0)" + ); + assert_eq!(board.get(0, 0), &Some(Piece::Black)); + } + + #[test] + fn place_and_capture_simple() { + let mut board = Board::new(); + assert_eq!( + board.place(0, 0, Piece::Black), + Ok(()), + "first move of piece black to (0, 0)" + ); + assert_eq!( + board.place(0, 1, Piece::White), + Ok(()), + "white move to (0, 1)" + ); + assert_eq!( + board.place(0, 2, Piece::Black), + Ok(()), + "black counter, capturing white" + ); + assert_eq!(board.get(0, 1), &Some(Piece::Black)); + } + + #[test] + fn failed_capture() { + let mut board = Board::new(); + + assert_eq!(board.place(0, 0, Piece::Black), Ok(())); + + assert_eq!(board.place(0, 2, Piece::White), Ok(())); + + assert_eq!(board.place(0, 3, Piece::Black), Ok(())); + + assert_eq!( + board.get(0, 1), + &None, + "(0, 1) was overridden even though it's an empty space" + ); + } +}