bitboard: complete moving all code to new structs
This commit is contained in:
parent
5b678dd595
commit
b4dd16d87d
|
@ -7,7 +7,6 @@ use crate::board;
|
||||||
use crate::engine;
|
use crate::engine;
|
||||||
use crate::movement::Move;
|
use crate::movement::Move;
|
||||||
use crate::node::Node;
|
use crate::node::Node;
|
||||||
use crate::notation;
|
|
||||||
use crate::rules;
|
use crate::rules;
|
||||||
use crate::stats;
|
use crate::stats;
|
||||||
|
|
||||||
|
@ -105,7 +104,7 @@ impl Analyzer {
|
||||||
if self.debug {
|
if self.debug {
|
||||||
self.log(format!("Analyzing node:\n{}", &self.node));
|
self.log(format!("Analyzing node:\n{}", &self.node));
|
||||||
let moves = self.node.get_player_moves(true);
|
let moves = self.node.get_player_moves(true);
|
||||||
self.log(format!("Legal moves: {}", notation::move_list_to_string(&moves)));
|
self.log(format!("Legal moves: {}", Move::list_to_uci_string(&moves)));
|
||||||
self.log(format!("Move time: {}", self.time_limit));
|
self.log(format!("Move time: {}", self.time_limit));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,18 +112,15 @@ impl Analyzer {
|
||||||
self.current_per_second_timer = Some(Instant::now());
|
self.current_per_second_timer = Some(Instant::now());
|
||||||
let (max_score, best_move) = self.negamax(&self.node.clone(), MIN_F32, MAX_F32, 0);
|
let (max_score, best_move) = self.negamax(&self.node.clone(), MIN_F32, MAX_F32, 0);
|
||||||
|
|
||||||
if best_move.is_some() {
|
if let Some(m) = best_move {
|
||||||
let log_str = format!(
|
let log_str = format!("Best move {} evaluated {}", m.to_uci_string(), max_score);
|
||||||
"Best move {} evaluated {}",
|
|
||||||
notation::move_to_string(&best_move.unwrap()), max_score
|
|
||||||
);
|
|
||||||
self.log(log_str);
|
self.log(log_str);
|
||||||
self.report_best_move(best_move);
|
self.report_best_move(Some(m));
|
||||||
} else {
|
} else {
|
||||||
// If no best move could be found, checkmate is unavoidable; send the first legal move.
|
// If no best move could be found, checkmate is unavoidable; send the first legal move.
|
||||||
self.log("Checkmate is unavoidable.".to_string());
|
self.log("Checkmate is unavoidable.".to_string());
|
||||||
let moves = rules::get_player_moves(&self.node.board, &self.node.game_state, true);
|
let moves = rules::get_player_moves(&self.node.board, &self.node.game_state, true);
|
||||||
let m = if moves.len() > 0 { Some(moves[0]) } else { None };
|
let m = if moves.len() > 0 { Some(moves[0].clone()) } else { None };
|
||||||
self.report_best_move(m);
|
self.report_best_move(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,7 +131,7 @@ impl Analyzer {
|
||||||
self.time_limit = if args.move_time != -1 {
|
self.time_limit = if args.move_time != -1 {
|
||||||
args.move_time
|
args.move_time
|
||||||
} else {
|
} else {
|
||||||
let (time, inc) = if board::is_white(self.node.game_state.color) {
|
let (time, inc) = if self.node.game_state.color == board::WHITE {
|
||||||
(args.white_time, args.white_inc)
|
(args.white_time, args.white_inc)
|
||||||
} else {
|
} else {
|
||||||
(args.black_time, args.black_inc)
|
(args.black_time, args.black_inc)
|
||||||
|
|
|
@ -265,14 +265,15 @@ impl Board {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Debug only: count number of pieces on board.
|
/// Debug only: count number of pieces on board.
|
||||||
|
#[allow(dead_code)] // Currently used in tests only.
|
||||||
pub(crate) fn num_pieces(&self) -> u8 {
|
pub(crate) fn num_pieces(&self) -> u8 {
|
||||||
let cbb = self.combined();
|
let mut cbb = self.combined();
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
while cbb > 0 {
|
while cbb > 0 {
|
||||||
count += cbb & 1;
|
count += cbb & 1;
|
||||||
cbb >>= 1;
|
cbb >>= 1;
|
||||||
}
|
}
|
||||||
0
|
count as u8
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Debug only: write a text view of the board.
|
/// Debug only: write a text view of the board.
|
||||||
|
@ -294,9 +295,10 @@ impl Board {
|
||||||
ROOK => 'r',
|
ROOK => 'r',
|
||||||
QUEEN => 'q',
|
QUEEN => 'q',
|
||||||
KING => 'k',
|
KING => 'k',
|
||||||
|
_ => panic!("Invalid piece.")
|
||||||
};
|
};
|
||||||
if color == WHITE {
|
if color == WHITE {
|
||||||
let piece_char = piece_char.to_ascii_uppercase();
|
piece_char = piece_char.to_ascii_uppercase();
|
||||||
}
|
}
|
||||||
piece_char
|
piece_char
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,9 +11,9 @@ use std::thread;
|
||||||
use crate::analysis;
|
use crate::analysis;
|
||||||
use crate::board;
|
use crate::board;
|
||||||
use crate::castling;
|
use crate::castling;
|
||||||
use crate::movement::{self, Move};
|
use crate::fen;
|
||||||
|
use crate::movement::Move;
|
||||||
use crate::node::Node;
|
use crate::node::Node;
|
||||||
use crate::notation;
|
|
||||||
use crate::uci;
|
use crate::uci;
|
||||||
|
|
||||||
/// Analysis engine.
|
/// Analysis engine.
|
||||||
|
@ -123,7 +123,7 @@ impl Engine {
|
||||||
// Workers commands.
|
// Workers commands.
|
||||||
Cmd::Log(s) => self.reply(Cmd::Log(s.to_string())),
|
Cmd::Log(s) => self.reply(Cmd::Log(s.to_string())),
|
||||||
Cmd::WorkerInfo(infos) => self.reply(Cmd::Info(infos.to_vec())),
|
Cmd::WorkerInfo(infos) => self.reply(Cmd::Info(infos.to_vec())),
|
||||||
Cmd::WorkerBestMove(m) => self.reply(Cmd::BestMove(*m)),
|
Cmd::WorkerBestMove(m) => self.reply(Cmd::BestMove(m.clone())),
|
||||||
_ => eprintln!("Not an engine input command: {:?}", cmd),
|
_ => eprintln!("Not an engine input command: {:?}", cmd),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,13 +141,13 @@ impl Engine {
|
||||||
/// Apply a FEN string to the engine state, replacing it.
|
/// Apply a FEN string to the engine state, replacing it.
|
||||||
///
|
///
|
||||||
/// For speed purposes, it assumes values are always valid.
|
/// For speed purposes, it assumes values are always valid.
|
||||||
fn apply_fen(&mut self, fen: ¬ation::Fen) {
|
fn apply_fen(&mut self, fen: &fen::Fen) {
|
||||||
// Placement.
|
// Placement.
|
||||||
self.node.board = board::new_from_fen(&fen.placement);
|
self.node.board = board::Board::new_from_fen(&fen.placement);
|
||||||
// Color.
|
// Color.
|
||||||
match fen.color.chars().next().unwrap() {
|
match fen.color.chars().next().unwrap() {
|
||||||
'w' => self.node.game_state.color = board::SQ_WH,
|
'w' => self.node.game_state.color = board::WHITE,
|
||||||
'b' => self.node.game_state.color = board::SQ_BL,
|
'b' => self.node.game_state.color = board::BLACK,
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
// Castling.
|
// Castling.
|
||||||
|
@ -163,7 +163,7 @@ impl Engine {
|
||||||
// En passant.
|
// En passant.
|
||||||
self.node.game_state.en_passant = match fen.en_passant.as_ref() {
|
self.node.game_state.en_passant = match fen.en_passant.as_ref() {
|
||||||
"-" => None,
|
"-" => None,
|
||||||
p => Some(board::pos(p)),
|
s => Some(board::sq_from_string(s)),
|
||||||
};
|
};
|
||||||
// Half moves.
|
// Half moves.
|
||||||
self.node.game_state.halfmove = fen.halfmove.parse::<i32>().ok().unwrap();
|
self.node.game_state.halfmove = fen.halfmove.parse::<i32>().ok().unwrap();
|
||||||
|
@ -178,7 +178,7 @@ impl Engine {
|
||||||
|
|
||||||
/// Apply a move to the current node.
|
/// Apply a move to the current node.
|
||||||
fn apply_move(&mut self, m: &Move) {
|
fn apply_move(&mut self, m: &Move) {
|
||||||
movement::apply_move_to(&mut self.node.board, &mut self.node.game_state, m);
|
m.apply_to(&mut self.node.board, &mut self.node.game_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start working on board, returning the best move found.
|
/// Start working on board, returning the best move found.
|
||||||
|
@ -221,7 +221,7 @@ impl Engine {
|
||||||
self.apply_fen(&fen);
|
self.apply_fen(&fen);
|
||||||
},
|
},
|
||||||
uci::PositionArgs::Startpos => {
|
uci::PositionArgs::Startpos => {
|
||||||
let fen = notation::parse_fen(notation::FEN_START).unwrap();
|
let fen = fen::parse_fen(fen::FEN_START).unwrap();
|
||||||
self.apply_fen(&fen);
|
self.apply_fen(&fen);
|
||||||
},
|
},
|
||||||
uci::PositionArgs::Moves(moves) => {
|
uci::PositionArgs::Moves(moves) => {
|
||||||
|
|
|
@ -47,6 +47,7 @@ impl Move {
|
||||||
H1 => { game_state.castling &= !CASTLING_WH_K; }
|
H1 => { game_state.castling &= !CASTLING_WH_K; }
|
||||||
A8 => { game_state.castling &= !CASTLING_BL_Q; }
|
A8 => { game_state.castling &= !CASTLING_BL_Q; }
|
||||||
H8 => { game_state.castling &= !CASTLING_BL_K; }
|
H8 => { game_state.castling &= !CASTLING_BL_K; }
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update board and game state.
|
// Update board and game state.
|
||||||
|
|
|
@ -35,7 +35,7 @@ impl Node {
|
||||||
|
|
||||||
/// Compute stats for both players for this node.
|
/// Compute stats for both players for this node.
|
||||||
pub fn compute_stats(&self) -> (stats::BoardStats, stats::BoardStats) {
|
pub fn compute_stats(&self) -> (stats::BoardStats, stats::BoardStats) {
|
||||||
stats::compute_stats(&self.board, &self.game_state)
|
stats::BoardStats::new_from(&self.board, &self.game_state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -282,7 +282,7 @@ impl Uci {
|
||||||
fn send_bestmove(&mut self, m: &Option<Move>) {
|
fn send_bestmove(&mut self, m: &Option<Move>) {
|
||||||
self.send(&format!(
|
self.send(&format!(
|
||||||
"bestmove {}",
|
"bestmove {}",
|
||||||
if let Some(m) = m { &m.to_uci_string() } else { UCI_NULL_MOVE_STR }
|
if let Some(m) = m { m.to_uci_string() } else { UCI_NULL_MOVE_STR.to_string() }
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue