diff --git a/rs/src/board.rs b/rs/src/board.rs index 2e56da2..f365fc8 100644 --- a/rs/src/board.rs +++ b/rs/src/board.rs @@ -250,7 +250,11 @@ impl Board { fn get_at(&self, position: &Position) -> Option<&Piece> { self.state.get(position) } - fn set_at(&mut self, position: Position, piece_or_empty: Option) { + pub fn set_at( + &mut self, + position: Position, + piece_or_empty: Option, + ) { match piece_or_empty { Some(piece) => self.state.insert(position, piece), None => self.state.remove(&position), diff --git a/rs/src/ui.rs b/rs/src/ui.rs index 9e18937..ea3a413 100644 --- a/rs/src/ui.rs +++ b/rs/src/ui.rs @@ -69,6 +69,41 @@ impl board::Position { } } +impl board::PieceType { + fn parse(c: char) -> Result { + match c { + 'P' => Ok(board::PieceType::Pawn), + _ => Err(()), + } + } +} + +impl board::Color { + fn parse(c: char) -> Result { + match c { + 'B' => Ok(board::Color::Black), + 'W' => Ok(board::Color::White), + _ => Err(()), + } + } +} + +impl board::Piece { + fn parse(s: &str) -> Result { + let mut chars = s.chars(); + let piece_type = board::PieceType::parse(chars.next().ok_or(())?)?; + let color = board::Color::parse(chars.next().ok_or(())?)?; + if chars.next().is_none() { + Ok(board::Piece { + piece_type, + color, + }) + } else { + Err(()) + } + } +} + impl std::fmt::Display for board::Position { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}{}", self.file, self.rank) @@ -84,6 +119,26 @@ impl std::fmt::Display for board::Board { } } +impl board::Board { + fn parse(s: &str) -> Result { + if s.chars().all(|c| char::is_ascii_alphanumeric(&c)) { + let mut board = board::Board::new(); + for piece_pos in s.as_bytes().chunks(4) { + let position = board::Position::parse( + std::str::from_utf8(&piece_pos[2..]).unwrap(), + )?; + let piece = board::Piece::parse( + std::str::from_utf8(&piece_pos[..2]).unwrap(), + )?; + board.set_at(position, Some(piece)); + } + Ok(board) + } else { + Err(()) + } + } +} + pub struct Ui { board: board::Board, } @@ -104,6 +159,16 @@ impl Ui { Err("get_state takes no args".to_owned()) } } + fn set_state(&mut self, args: &[&str]) -> Result { + if let [state_str] = args { + self.board = board::Board::parse(state_str) + .map_err(|_| format!("Error parsing state {}", state_str))?; + let result = format!("{}", self.board); + Ok(result) + } else { + Err("set_state takes 1 arg".to_owned()) + } + } fn get_moves(&self, args: &[&str]) -> Result { if let [position_str] = args { let position = @@ -150,6 +215,7 @@ impl Ui { "get_state" => self.get_state(&args), "get_moves" => self.get_moves(&args), "make_move" => self.make_move(&args), + "set_state" => self.set_state(&args), "" => Err("No command given".to_owned()), _ => Err("Invalid command".to_owned()), }