extern crate chess_engine;
use chess_engine::*;
use std::{
convert::TryFrom,
io::{stdin, stdout, Write},
};
fn input(prompt: impl std::fmt::Display) -> String {
let mut s = String::new();
print!("{}", prompt);
let _ = stdout().flush();
stdin()
.read_line(&mut s)
.expect("Did not enter a correct string");
s
}
fn get_cpu_move(b: &Board, best: bool) -> Move {
let (m, count, _) = if best {
b.get_best_next_move(4)
} else {
b.get_worst_next_move(4)
};
print!("CPU evaluated {} moves before choosing to ", count);
match m {
Move::Piece(from, to) => match (b.get_piece(from), b.get_piece(to)) {
(Some(piece), Some(takes)) => println!(
"take {}({}) with {}({})",
takes.get_name(),
to,
piece.get_name(),
from
),
(Some(piece), None) => {
println!("move {}({}) to {}", piece.get_name(), from, to)
}
_ => println!("move {} to {}", from, to),
},
Move::KingSideCastle => {
println!("castle kingside")
}
Move::QueenSideCastle => {
println!("castle queenside")
}
Move::Resign => println!("resign"),
}
m
}
fn main() -> Result<(), String> {
let mut b = Board::default();
println!("{}", b);
let mut history = vec![];
loop {
let mut s = input(">>> ");
s = s.trim().to_string();
let m = if s.is_empty() {
println!("Waiting for CPU to choose best move...");
get_cpu_move(&b, true)
} else if s == "worst" {
println!("Waiting for CPU to choose worst move...");
get_cpu_move(&b, false)
} else if s == "rate" {
continue;
} else if s == "pass" {
b = b.change_turn();
continue;
} else if s == "history" {
for i in 0..history.len() {
if i < history.len() - 1 {
println!("{} {}", history[i], history[i + 1]);
} else {
println!("{}", history[i]);
}
}
continue;
} else {
match Move::try_from(s) {
Ok(m) => m,
Err(e) => {
eprintln!("{}", e);
continue;
}
}
};
match b.play_move(m) {
GameResult::Continuing(next_board) => {
b = next_board;
println!("{}", b);
history.push(m);
}
GameResult::Victory(winner) => {
println!("{}", b);
println!("{} loses. {} is victorious.", !winner, winner);
break;
}
GameResult::IllegalMove(x) => {
eprintln!("{} is an illegal move.", x);
}
GameResult::Stalemate => {
println!("Drawn game.");
break;
}
}
}
for m in history {
println!("{}", m);
}
Ok(())
}