|
|
|
@ -1,24 +1,24 @@
|
|
|
|
|
mod config;
|
|
|
|
|
mod eval;
|
|
|
|
|
|
|
|
|
|
use chess::{Board, MoveGen};
|
|
|
|
|
use chess::{Board, ChessMove, MoveGen};
|
|
|
|
|
use config::INFO;
|
|
|
|
|
use eval::eval_board;
|
|
|
|
|
use itertools::Itertools;
|
|
|
|
|
use rand::seq::IteratorRandom;
|
|
|
|
|
|
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
use std::io::{self, BufRead};
|
|
|
|
|
use std::process;
|
|
|
|
|
use std::str::FromStr;
|
|
|
|
|
use vampirc_uci::parse_one;
|
|
|
|
|
use vampirc_uci::{
|
|
|
|
|
MessageList, Serializable, UciMessage, UciOptionConfig, UciSearchControl, UciTimeControl,
|
|
|
|
|
};
|
|
|
|
|
use vampirc_uci::{UciMessage, UciOptionConfig, UciTimeControl};
|
|
|
|
|
|
|
|
|
|
use crate::config::depth;
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let mut rng = rand::thread_rng();
|
|
|
|
|
let _rng = rand::thread_rng();
|
|
|
|
|
let mut board: Option<Board> = None;
|
|
|
|
|
let mut move_history: Vec<(ChessMove, Board)> = vec![];
|
|
|
|
|
for line in io::stdin().lock().lines() {
|
|
|
|
|
let msg: UciMessage = parse_one(&line.unwrap());
|
|
|
|
|
match msg {
|
|
|
|
@ -39,7 +39,10 @@ fn main() {
|
|
|
|
|
UciMessage::IsReady => {
|
|
|
|
|
println!("{}", UciMessage::ReadyOk)
|
|
|
|
|
}
|
|
|
|
|
UciMessage::UciNewGame => board = Some(Board::default()),
|
|
|
|
|
UciMessage::UciNewGame => {
|
|
|
|
|
board = Some(Board::default());
|
|
|
|
|
move_history = vec![];
|
|
|
|
|
}
|
|
|
|
|
UciMessage::Position {
|
|
|
|
|
startpos,
|
|
|
|
|
fen,
|
|
|
|
@ -51,7 +54,7 @@ fn main() {
|
|
|
|
|
if let Some(fen) = fen {
|
|
|
|
|
board = Some(Board::from_str(fen.as_str()).expect("Invalid FEN board"))
|
|
|
|
|
}
|
|
|
|
|
if moves.len() != 0 {
|
|
|
|
|
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));
|
|
|
|
@ -66,11 +69,11 @@ fn main() {
|
|
|
|
|
if let Some(tc) = time_control {
|
|
|
|
|
match tc {
|
|
|
|
|
UciTimeControl::TimeLeft {
|
|
|
|
|
white_time,
|
|
|
|
|
black_time,
|
|
|
|
|
white_increment,
|
|
|
|
|
black_increment,
|
|
|
|
|
moves_to_go,
|
|
|
|
|
white_time: _,
|
|
|
|
|
black_time: _,
|
|
|
|
|
white_increment: _,
|
|
|
|
|
black_increment: _,
|
|
|
|
|
moves_to_go: _,
|
|
|
|
|
} => {
|
|
|
|
|
// FIXME: impl time-related Things
|
|
|
|
|
}
|
|
|
|
@ -85,25 +88,50 @@ fn main() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if let Some(sc) = search_control {
|
|
|
|
|
if let Some(_sc) = search_control {
|
|
|
|
|
// FIXME: impl search control things
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let Some(board) = board {
|
|
|
|
|
let color = board.side_to_move();
|
|
|
|
|
let moves = MoveGen::new_legal(&board).into_iter();
|
|
|
|
|
let moves = MoveGen::new_legal(&board);
|
|
|
|
|
let iter = moves.map(|mov| (mov, board.make_move_new(mov)));
|
|
|
|
|
|
|
|
|
|
println!(
|
|
|
|
|
"bestmove {}",
|
|
|
|
|
iter.sorted_by(|a, b| Ord::cmp(
|
|
|
|
|
&eval_board(b.1, color, depth),
|
|
|
|
|
&eval_board(a.1, color, depth)
|
|
|
|
|
))
|
|
|
|
|
.next()
|
|
|
|
|
.unwrap()
|
|
|
|
|
.0
|
|
|
|
|
let mut moves_hash_map = HashMap::new();
|
|
|
|
|
|
|
|
|
|
let mut sorted_moves = iter.sorted_by(|a, b| {
|
|
|
|
|
if !moves_hash_map.contains_key(a) {
|
|
|
|
|
moves_hash_map
|
|
|
|
|
.insert(*a, eval_board(a.1, color, depth, move_history.clone()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !moves_hash_map.contains_key(b) {
|
|
|
|
|
moves_hash_map
|
|
|
|
|
.insert(*b, eval_board(b.1, color, depth, move_history.clone()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let a_eval = moves_hash_map.get(a).unwrap();
|
|
|
|
|
let b_eval = moves_hash_map.get(b).unwrap();
|
|
|
|
|
Ord::cmp(&b_eval, &a_eval)
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let best_move = sorted_moves.next().unwrap();
|
|
|
|
|
let worst_move = sorted_moves.last().unwrap_or(best_move);
|
|
|
|
|
|
|
|
|
|
move_history.push(best_move);
|
|
|
|
|
|
|
|
|
|
eprintln!(
|
|
|
|
|
"best move: {}, {}",
|
|
|
|
|
best_move.0,
|
|
|
|
|
moves_hash_map.get(&best_move).unwrap_or(&0)
|
|
|
|
|
);
|
|
|
|
|
eprintln!(
|
|
|
|
|
"worst move: {}, {}",
|
|
|
|
|
worst_move.0,
|
|
|
|
|
moves_hash_map.get(&worst_move).unwrap_or(&0)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
println!("bestmove {}", best_move.0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
UciMessage::Stop => {
|
|
|
|
|