1extern crate chess_engine;
2use chess_engine::*;
3use std::{
4 convert::TryFrom,
5 io::{stdin, stdout, Write},
6};
7
8fn input(prompt: impl std::fmt::Display) -> String {
9 let mut s = String::new();
10 print!("{}", prompt);
11 let _ = stdout().flush();
12 stdin()
13 .read_line(&mut s)
14 .expect("Did not enter a correct string");
15 s
16}
17
18fn get_cpu_move(b: &Board, best: bool) -> Move {
19 let (m, count, _) = if best {
20 b.get_best_next_move(4)
21 } else {
22 b.get_worst_next_move(4)
23 };
24
25 print!("CPU evaluated {} moves before choosing to ", count);
26 match m {
27 Move::Piece(from, to) => match (b.get_piece(from), b.get_piece(to)) {
28 (Some(piece), Some(takes)) => println!(
29 "take {}({}) with {}({})",
30 takes.get_name(),
31 to,
32 piece.get_name(),
33 from
34 ),
35 (Some(piece), None) => {
36 println!("move {}({}) to {}", piece.get_name(), from, to)
37 }
38 _ => println!("move {} to {}", from, to),
39 },
40 Move::KingSideCastle => {
41 println!("castle kingside")
42 }
43 Move::QueenSideCastle => {
44 println!("castle queenside")
45 }
46 Move::Resign => println!("resign"),
47 }
48
49 m
50}
51
52fn main() -> Result<(), String> {
53 let mut b = Board::default();
54
55 println!("{}", b);
56 let mut history = vec![];
57
58 loop {
59 let mut s = input(">>> ");
60 s = s.trim().to_string();
61
62 let m = if s.is_empty() {
63 println!("Waiting for CPU to choose best move...");
64 get_cpu_move(&b, true)
65 } else if s == "worst" {
66 println!("Waiting for CPU to choose worst move...");
67 get_cpu_move(&b, false)
68 } else if s == "rate" {
69 continue;
70 } else if s == "pass" {
71 b = b.change_turn();
72 continue;
73 } else if s == "history" {
74 for i in 0..history.len() {
75 if i < history.len() - 1 {
76 println!("{} {}", history[i], history[i + 1]);
77 } else {
78 println!("{}", history[i]);
79 }
80 }
81 continue;
82 } else {
83 match Move::try_from(s) {
84 Ok(m) => m,
85 Err(e) => {
86 eprintln!("{}", e);
87 continue;
88 }
89 }
90 };
91
92 match b.play_move(m) {
93 GameResult::Continuing(next_board) => {
94 b = next_board;
95 println!("{}", b);
96 history.push(m);
97 }
98
99 GameResult::Victory(winner) => {
100 println!("{}", b);
101 println!("{} loses. {} is victorious.", !winner, winner);
102 break;
103 }
104
105 GameResult::IllegalMove(x) => {
106 eprintln!("{} is an illegal move.", x);
107 }
108
109 GameResult::Stalemate => {
110 println!("Drawn game.");
111 break;
112 }
113 }
114 }
115
116 for m in history {
117 println!("{}", m);
118 }
119 Ok(())
120}