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) {
|
||||
apply_move_to_board(board, 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) {
|
||||
match castle {
|
||||
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`.
|
||||
|
@ -142,6 +180,7 @@ pub fn get_castle_move(castle: u8) -> Move {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// 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
|
||||
|
|
21
src/uci.rs
21
src/uci.rs
|
@ -175,22 +175,19 @@ impl Uci {
|
|||
self.setup_engine();
|
||||
},
|
||||
UciCmd::Debug(on) => {
|
||||
let args = engine::Cmd::UciDebug(*on);
|
||||
self.engine_in.as_ref().unwrap().send(args).unwrap();
|
||||
self.send_engine_command(engine::Cmd::UciDebug(*on));
|
||||
}
|
||||
UciCmd::IsReady => if self.state == State::Ready { self.send_ready() },
|
||||
UciCmd::UciNewGame => if self.state == State::Ready { /* Nothing to do. */ },
|
||||
UciCmd::Position(args) => if self.state == State::Ready {
|
||||
let args = engine::Cmd::UciPosition(args.to_vec());
|
||||
self.engine_in.as_ref().unwrap().send(args).unwrap();
|
||||
self.send_engine_command(engine::Cmd::UciPosition(args.to_vec()));
|
||||
},
|
||||
UciCmd::Go(args) => if self.state == State::Ready {
|
||||
let args = engine::Cmd::UciGo(args.to_vec());
|
||||
self.engine_in.as_ref().unwrap().send(args).unwrap();
|
||||
self.send_engine_command(engine::Cmd::UciGo(args.to_vec()));
|
||||
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::Unknown(c) => { self.log(format!("Unknown command: {}", c)); }
|
||||
|
@ -226,6 +223,7 @@ impl Uci {
|
|||
self.send("uciok");
|
||||
}
|
||||
|
||||
/// Setup engine for UCI.
|
||||
fn setup_engine(&mut self) {
|
||||
let uci_s = self.cmd_channel.0.clone();
|
||||
thread::spawn(move || {
|
||||
|
@ -235,6 +233,15 @@ impl Uci {
|
|||
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.
|
||||
fn send_ready(&mut self) {
|
||||
self.send("readyok");
|
||||
|
|
Reference in a new issue