bitboard: complete moving all code to new structs

This commit is contained in:
dece 2020-06-19 20:27:03 +02:00
parent 5b678dd595
commit b4dd16d87d
6 changed files with 24 additions and 25 deletions

View file

@ -7,7 +7,6 @@ use crate::board;
use crate::engine;
use crate::movement::Move;
use crate::node::Node;
use crate::notation;
use crate::rules;
use crate::stats;
@ -105,7 +104,7 @@ impl Analyzer {
if self.debug {
self.log(format!("Analyzing node:\n{}", &self.node));
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));
}
@ -113,18 +112,15 @@ impl Analyzer {
self.current_per_second_timer = Some(Instant::now());
let (max_score, best_move) = self.negamax(&self.node.clone(), MIN_F32, MAX_F32, 0);
if best_move.is_some() {
let log_str = format!(
"Best move {} evaluated {}",
notation::move_to_string(&best_move.unwrap()), max_score
);
if let Some(m) = best_move {
let log_str = format!("Best move {} evaluated {}", m.to_uci_string(), max_score);
self.log(log_str);
self.report_best_move(best_move);
self.report_best_move(Some(m));
} else {
// If no best move could be found, checkmate is unavoidable; send the first legal move.
self.log("Checkmate is unavoidable.".to_string());
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);
}
}
@ -135,7 +131,7 @@ impl Analyzer {
self.time_limit = if args.move_time != -1 {
args.move_time
} 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)
} else {
(args.black_time, args.black_inc)

View file

@ -265,14 +265,15 @@ impl Board {
}
/// Debug only: count number of pieces on board.
#[allow(dead_code)] // Currently used in tests only.
pub(crate) fn num_pieces(&self) -> u8 {
let cbb = self.combined();
let mut cbb = self.combined();
let mut count = 0;
while cbb > 0 {
count += cbb & 1;
cbb >>= 1;
}
0
count as u8
}
/// Debug only: write a text view of the board.
@ -294,9 +295,10 @@ impl Board {
ROOK => 'r',
QUEEN => 'q',
KING => 'k',
_ => panic!("Invalid piece.")
};
if color == WHITE {
let piece_char = piece_char.to_ascii_uppercase();
piece_char = piece_char.to_ascii_uppercase();
}
piece_char
};

View file

@ -11,9 +11,9 @@ use std::thread;
use crate::analysis;
use crate::board;
use crate::castling;
use crate::movement::{self, Move};
use crate::fen;
use crate::movement::Move;
use crate::node::Node;
use crate::notation;
use crate::uci;
/// Analysis engine.
@ -123,7 +123,7 @@ impl Engine {
// Workers commands.
Cmd::Log(s) => self.reply(Cmd::Log(s.to_string())),
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),
}
}
@ -141,13 +141,13 @@ impl Engine {
/// Apply a FEN string to the engine state, replacing it.
///
/// For speed purposes, it assumes values are always valid.
fn apply_fen(&mut self, fen: &notation::Fen) {
fn apply_fen(&mut self, fen: &fen::Fen) {
// Placement.
self.node.board = board::new_from_fen(&fen.placement);
self.node.board = board::Board::new_from_fen(&fen.placement);
// Color.
match fen.color.chars().next().unwrap() {
'w' => self.node.game_state.color = board::SQ_WH,
'b' => self.node.game_state.color = board::SQ_BL,
'w' => self.node.game_state.color = board::WHITE,
'b' => self.node.game_state.color = board::BLACK,
_ => {}
};
// Castling.
@ -163,7 +163,7 @@ impl Engine {
// En passant.
self.node.game_state.en_passant = match fen.en_passant.as_ref() {
"-" => None,
p => Some(board::pos(p)),
s => Some(board::sq_from_string(s)),
};
// Half moves.
self.node.game_state.halfmove = fen.halfmove.parse::<i32>().ok().unwrap();
@ -178,7 +178,7 @@ impl Engine {
/// Apply a move to the current node.
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.
@ -221,7 +221,7 @@ impl Engine {
self.apply_fen(&fen);
},
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);
},
uci::PositionArgs::Moves(moves) => {

View file

@ -47,6 +47,7 @@ impl Move {
H1 => { game_state.castling &= !CASTLING_WH_K; }
A8 => { game_state.castling &= !CASTLING_BL_Q; }
H8 => { game_state.castling &= !CASTLING_BL_K; }
_ => {}
}
// Update board and game state.

View file

@ -35,7 +35,7 @@ impl Node {
/// Compute stats for both players for this node.
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)
}
}

View file

@ -282,7 +282,7 @@ impl Uci {
fn send_bestmove(&mut self, m: &Option<Move>) {
self.send(&format!(
"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() }
));
}
}