use rschess::{Board, Fen};
use std::{env, fmt, process, time::Instant};
fn error<T: fmt::Display>(e: T) -> ! {
eprintln!("{e}");
process::exit(1);
}
fn search(board: Board, maxdepth: usize) -> Vec<Board> {
if maxdepth == 0 {
return Vec::new();
}
let mut sols = Vec::new();
for m in board.gen_legal_moves() {
let mut new_board = board.clone();
new_board.make_move(m).unwrap();
if new_board.is_checkmate() && new_board.checkmated_side().unwrap().is_black() {
sols.push(new_board)
} else {
sols.append(&mut search(new_board, maxdepth - 1))
}
}
sols
}
fn main() {
let maxdepth: usize = if let Some(n) = env::args().nth(1) { n.parse().expect("Invalid max depth") } else { 4 };
let fen = Fen::try_from("1RrB2b1/8/4n3/2n3p1/2K2b2/1p1rk3/6BR/8 b - - 1 1").unwrap();
if fen.position().side_to_move().is_white() {
error("Must be black to move");
}
let board = Board::from_fen(fen);
println!("{board}\nSearching for helpmates (depth = {maxdepth})...");
let start = Instant::now();
let sols = search(board, maxdepth);
let end = Instant::now();
let dur = end.duration_since(start);
println!("Finished searching in {dur:?}");
if sols.is_empty() {
println!("No solutions found");
} else {
println!("Solution(s):");
for sol in sols {
println!("{}", sol.gen_movetext());
}
}
}