rules: disable castling when king/rook moves
This commit is contained in:
parent
a8a680b944
commit
c4f5412cd4
39
src/rules.rs
39
src/rules.rs
|
@ -64,6 +64,7 @@ pub fn apply_move(board: &Board, game_state: &GameState, m: &Move) -> (Board, Ga
|
||||||
pub fn apply_move_to(board: &mut Board, game_state: &mut GameState, m: &Move) {
|
pub fn apply_move_to(board: &mut Board, game_state: &mut GameState, m: &Move) {
|
||||||
apply_move_to_board(board, m);
|
apply_move_to_board(board, m);
|
||||||
apply_move_to_state(game_state, m);
|
apply_move_to_state(game_state, m);
|
||||||
|
// If the move is a castle, remove it from castling options.
|
||||||
if let Some(castle) = get_castle(m) {
|
if let Some(castle) = get_castle(m) {
|
||||||
match castle {
|
match castle {
|
||||||
CASTLING_WH_K | CASTLING_WH_Q => game_state.castling &= !CASTLING_WH_MASK,
|
CASTLING_WH_K | CASTLING_WH_Q => game_state.castling &= !CASTLING_WH_MASK,
|
||||||
|
@ -71,6 +72,43 @@ pub fn apply_move_to(board: &mut Board, game_state: &mut GameState, m: &Move) {
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// Else, check if it's either to rook or the king that moved.
|
||||||
|
else {
|
||||||
|
let piece = get_square(board, &m.1);
|
||||||
|
if is_white(piece) && game_state.castling & CASTLING_WH_MASK != 0 {
|
||||||
|
match get_type(piece) {
|
||||||
|
SQ_K => {
|
||||||
|
if m.0 == pos("e1") {
|
||||||
|
game_state.castling &= !CASTLING_WH_MASK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SQ_R => {
|
||||||
|
if m.0 == pos("a1") {
|
||||||
|
game_state.castling &= !CASTLING_WH_Q;
|
||||||
|
} else if m.0 == pos("h1") {
|
||||||
|
game_state.castling &= !CASTLING_WH_K;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
} else if is_black(piece) && game_state.castling & CASTLING_BL_MASK != 0 {
|
||||||
|
match get_type(piece) {
|
||||||
|
SQ_K => {
|
||||||
|
if m.0 == pos("e8") {
|
||||||
|
game_state.castling &= !CASTLING_BL_MASK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SQ_R => {
|
||||||
|
if m.0 == pos("a8") {
|
||||||
|
game_state.castling &= !CASTLING_BL_Q;
|
||||||
|
} else if m.0 == pos("h8") {
|
||||||
|
game_state.castling &= !CASTLING_BL_K;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply a move `m` into `board`.
|
/// Apply a move `m` into `board`.
|
||||||
|
@ -142,6 +180,7 @@ pub fn get_castle_move(castle: u8) -> Move {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Get a list of moves for all pieces of the playing color.
|
/// Get a list of moves for all pieces of the playing color.
|
||||||
///
|
///
|
||||||
/// If `commit` is false, do not check for illegal moves. This is used
|
/// If `commit` is false, do not check for illegal moves. This is used
|
||||||
|
|
21
src/uci.rs
21
src/uci.rs
|
@ -175,22 +175,19 @@ impl Uci {
|
||||||
self.setup_engine();
|
self.setup_engine();
|
||||||
},
|
},
|
||||||
UciCmd::Debug(on) => {
|
UciCmd::Debug(on) => {
|
||||||
let args = engine::Cmd::UciDebug(*on);
|
self.send_engine_command(engine::Cmd::UciDebug(*on));
|
||||||
self.engine_in.as_ref().unwrap().send(args).unwrap();
|
|
||||||
}
|
}
|
||||||
UciCmd::IsReady => if self.state == State::Ready { self.send_ready() },
|
UciCmd::IsReady => if self.state == State::Ready { self.send_ready() },
|
||||||
UciCmd::UciNewGame => if self.state == State::Ready { /* Nothing to do. */ },
|
UciCmd::UciNewGame => if self.state == State::Ready { /* Nothing to do. */ },
|
||||||
UciCmd::Position(args) => if self.state == State::Ready {
|
UciCmd::Position(args) => if self.state == State::Ready {
|
||||||
let args = engine::Cmd::UciPosition(args.to_vec());
|
self.send_engine_command(engine::Cmd::UciPosition(args.to_vec()));
|
||||||
self.engine_in.as_ref().unwrap().send(args).unwrap();
|
|
||||||
},
|
},
|
||||||
UciCmd::Go(args) => if self.state == State::Ready {
|
UciCmd::Go(args) => if self.state == State::Ready {
|
||||||
let args = engine::Cmd::UciGo(args.to_vec());
|
self.send_engine_command(engine::Cmd::UciGo(args.to_vec()));
|
||||||
self.engine_in.as_ref().unwrap().send(args).unwrap();
|
|
||||||
self.state = State::Working;
|
self.state = State::Working;
|
||||||
}
|
}
|
||||||
UciCmd::Stop => if self.state == State::Working {
|
UciCmd::Stop => if self.state == State::Working {
|
||||||
self.engine_in.as_ref().unwrap().send(engine::Cmd::Stop).unwrap();
|
self.send_engine_command(engine::Cmd::Stop);
|
||||||
},
|
},
|
||||||
UciCmd::Quit => return false,
|
UciCmd::Quit => return false,
|
||||||
UciCmd::Unknown(c) => { self.log(format!("Unknown command: {}", c)); }
|
UciCmd::Unknown(c) => { self.log(format!("Unknown command: {}", c)); }
|
||||||
|
@ -226,6 +223,7 @@ impl Uci {
|
||||||
self.send("uciok");
|
self.send("uciok");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Setup engine for UCI.
|
||||||
fn setup_engine(&mut self) {
|
fn setup_engine(&mut self) {
|
||||||
let uci_s = self.cmd_channel.0.clone();
|
let uci_s = self.cmd_channel.0.clone();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
|
@ -235,6 +233,15 @@ impl Uci {
|
||||||
self.state = State::Ready;
|
self.state = State::Ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Send a command to the engine if it is has been setup, else log an error.
|
||||||
|
fn send_engine_command(&mut self, cmd: engine::Cmd) {
|
||||||
|
if let Some(tx) = self.engine_in.as_ref() {
|
||||||
|
tx.send(cmd).unwrap();
|
||||||
|
} else {
|
||||||
|
self.log("Attempt to send command to offline engine.".to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Notify interface that it is ready.
|
/// Notify interface that it is ready.
|
||||||
fn send_ready(&mut self) {
|
fn send_ready(&mut self) {
|
||||||
self.send("readyok");
|
self.send("readyok");
|
||||||
|
|
Reference in a new issue