You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
5.7 KiB
169 lines
5.7 KiB
mod config;
|
|
mod eval;
|
|
mod piece_tables;
|
|
mod piece_values;
|
|
|
|
use chess::Board;
|
|
use config::INFO;
|
|
use eval::{Board as EvalBoard, Evaluator};
|
|
use minimax::{IterativeOptions, ParallelOptions, ParallelSearch, Strategy};
|
|
|
|
use std::io::{self, BufRead};
|
|
use std::str::FromStr;
|
|
use std::{process, unimplemented};
|
|
use vampirc_uci::parse_one;
|
|
use vampirc_uci::{UciMessage, UciOptionConfig, UciTimeControl};
|
|
|
|
use crate::config::DEFAULT_DEPTH;
|
|
|
|
struct Options {
|
|
pub en_passant: bool,
|
|
pub depth: i64,
|
|
pub debug: bool,
|
|
}
|
|
|
|
fn main() {
|
|
let mut board: Option<Board> = None;
|
|
let mut move_history: Vec<Board> = vec![];
|
|
let mut options: Options = Options {
|
|
en_passant: false,
|
|
depth: DEFAULT_DEPTH.into(),
|
|
debug: false,
|
|
};
|
|
|
|
for line in io::stdin().lock().lines() {
|
|
let line = line.unwrap();
|
|
let msg: UciMessage = parse_one(&line);
|
|
match msg {
|
|
UciMessage::Uci => {
|
|
println!(
|
|
"{}\n{}\n{}\n{}",
|
|
UciMessage::Id {
|
|
name: Some(INFO.to_name()),
|
|
author: Some(INFO.to_author())
|
|
},
|
|
UciMessage::Option(UciOptionConfig::Check {
|
|
name: "EnPassant".to_owned(),
|
|
default: Some(options.en_passant)
|
|
}),
|
|
UciMessage::Option(UciOptionConfig::Spin {
|
|
name: "Depth".to_owned(),
|
|
default: Some(options.depth),
|
|
min: Some(0),
|
|
max: None
|
|
}),
|
|
UciMessage::UciOk {}
|
|
)
|
|
}
|
|
UciMessage::SetOption { name, value } => match name.as_str() {
|
|
"EnPassant" => {
|
|
options.en_passant = match value.as_deref().unwrap_or_default() {
|
|
"true" => true,
|
|
"false" => false,
|
|
_ => options.en_passant,
|
|
}
|
|
}
|
|
"Depth" => {
|
|
options.depth = value.unwrap_or_default().parse().unwrap_or(options.depth)
|
|
}
|
|
_ => unimplemented!(),
|
|
},
|
|
UciMessage::Debug(debug) => options.debug = debug,
|
|
UciMessage::IsReady => {
|
|
println!("{}", UciMessage::ReadyOk)
|
|
}
|
|
UciMessage::UciNewGame => {
|
|
board = Some(Board::default());
|
|
move_history = vec![];
|
|
}
|
|
UciMessage::Position {
|
|
startpos,
|
|
fen,
|
|
moves,
|
|
} => {
|
|
if startpos {
|
|
board = Some(Board::default())
|
|
}
|
|
if let Some(fen) = fen {
|
|
board = Some(Board::from_str(fen.as_str()).expect("Invalid FEN board"))
|
|
}
|
|
if !moves.is_empty() {
|
|
for chess_move in moves.iter() {
|
|
if let Some(goofy_board) = board {
|
|
board = Some(goofy_board.make_move_new(*chess_move));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
UciMessage::Go {
|
|
time_control,
|
|
search_control,
|
|
} => {
|
|
if let Some(tc) = time_control {
|
|
match tc {
|
|
UciTimeControl::TimeLeft {
|
|
white_time: _,
|
|
black_time: _,
|
|
white_increment: _,
|
|
black_increment: _,
|
|
moves_to_go: _,
|
|
} => {
|
|
// FIXME: impl time-related Things
|
|
}
|
|
UciTimeControl::Infinite => {
|
|
// FIXME: impl
|
|
}
|
|
UciTimeControl::Ponder => {
|
|
// FIXME: impl
|
|
}
|
|
UciTimeControl::MoveTime(_) => {
|
|
// FIXME: impl
|
|
}
|
|
}
|
|
}
|
|
if let Some(_sc) = search_control {
|
|
// FIXME: impl search control things
|
|
}
|
|
|
|
if let Some(board) = board {
|
|
let mut strat = ParallelSearch::new(
|
|
Evaluator::default(),
|
|
IterativeOptions::new()
|
|
.verbose()
|
|
.with_null_window_search(true)
|
|
.with_countermoves()
|
|
.with_countermove_history()
|
|
.with_singular_extension()
|
|
.with_quiescence_search_depth(2)
|
|
.with_table_byte_size(8 * 1024 * 1024 * 1024),
|
|
ParallelOptions::new().with_background_pondering(),
|
|
);
|
|
|
|
strat.set_max_depth(DEFAULT_DEPTH);
|
|
let mov = strat
|
|
.choose_move(&EvalBoard {
|
|
current_board: board,
|
|
board_history: move_history.clone(),
|
|
last_move: Default::default(),
|
|
})
|
|
.unwrap();
|
|
|
|
println!("bestmove {}", mov);
|
|
}
|
|
}
|
|
UciMessage::Stop => {
|
|
// FIXME: impl
|
|
}
|
|
UciMessage::Quit => {
|
|
process::exit(0);
|
|
}
|
|
_ => {
|
|
todo!("{}", msg.to_string())
|
|
}
|
|
}
|
|
if options.debug {
|
|
println!("{}\n", UciMessage::info_string(line))
|
|
}
|
|
}
|
|
}
|