Add command for manual state setting at engine

This commit is contained in:
2021-12-20 21:46:21 +01:00
parent ef5719f2f5
commit 802b069269
2 changed files with 71 additions and 1 deletions

View File

@@ -250,7 +250,11 @@ impl Board {
fn get_at(&self, position: &Position) -> Option<&Piece> { fn get_at(&self, position: &Position) -> Option<&Piece> {
self.state.get(position) self.state.get(position)
} }
fn set_at(&mut self, position: Position, piece_or_empty: Option<Piece>) { pub fn set_at(
&mut self,
position: Position,
piece_or_empty: Option<Piece>,
) {
match piece_or_empty { match piece_or_empty {
Some(piece) => self.state.insert(position, piece), Some(piece) => self.state.insert(position, piece),
None => self.state.remove(&position), None => self.state.remove(&position),

View File

@@ -69,6 +69,41 @@ impl board::Position {
} }
} }
impl board::PieceType {
fn parse(c: char) -> Result<Self, ()> {
match c {
'P' => Ok(board::PieceType::Pawn),
_ => Err(()),
}
}
}
impl board::Color {
fn parse(c: char) -> Result<Self, ()> {
match c {
'B' => Ok(board::Color::Black),
'W' => Ok(board::Color::White),
_ => Err(()),
}
}
}
impl board::Piece {
fn parse(s: &str) -> Result<Self, ()> {
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 { impl std::fmt::Display for board::Position {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}{}", self.file, self.rank) 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<Self, ()> {
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 { pub struct Ui {
board: board::Board, board: board::Board,
} }
@@ -104,6 +159,16 @@ impl Ui {
Err("get_state takes no args".to_owned()) Err("get_state takes no args".to_owned())
} }
} }
fn set_state(&mut self, args: &[&str]) -> Result<String, String> {
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<String, String> { fn get_moves(&self, args: &[&str]) -> Result<String, String> {
if let [position_str] = args { if let [position_str] = args {
let position = let position =
@@ -150,6 +215,7 @@ impl Ui {
"get_state" => self.get_state(&args), "get_state" => self.get_state(&args),
"get_moves" => self.get_moves(&args), "get_moves" => self.get_moves(&args),
"make_move" => self.make_move(&args), "make_move" => self.make_move(&args),
"set_state" => self.set_state(&args),
"" => Err("No command given".to_owned()), "" => Err("No command given".to_owned()),
_ => Err("Invalid command".to_owned()), _ => Err("Invalid command".to_owned()),
} }