rustenginelib/
uci.rs

1use crate::bitboard::*;
2use crate::constants::*;
3use crate::lineargame::*;
4use crate::piece::*;
5use crate::square::*;
6//use crate::state::*;
7
8use std::io::{self, BufRead};
9
10pub struct Uci {
11    pub engine_name: String,
12    pub engine_author: String,
13    pub linear_game: LinearGame,
14}
15
16pub fn create_default_uci() -> Uci {
17    let mut uci = Uci {
18        engine_name: "rustengine".to_string(),
19        engine_author: "easychessanimations".to_string(),
20        linear_game: LinearGame::new(),
21    };
22    uci.linear_game.init(DEFAULT_VARIANT);
23    uci
24}
25
26pub fn demo() {
27    let x: Bitboard = 0xffff00000000ffff;
28
29    println!("{}", x.pretty_print_string());
30
31    let sq: Square = rank_file(RANK_3, FILE_D);
32
33    println!("square {} file {} rank {}", sq.uci(), sq.file(), sq.rank());
34
35    let fig: Figure = LANCERNE;
36
37    println!("\nfigure {} symbol {}", fig, fig.symbol());
38
39    let p: Piece = color_figure(WHITE, LANCERNE);
40
41    println!(
42        "\npiece {} fen symbol {} san symbol {} uci symbol {} san letter {}",
43        p,
44        p.fen_symbol(),
45        p.san_symbol(),
46        p.uci_symbol(),
47        p.san_letter()
48    );
49
50    let mut bb: Bitboard = sq.bitboard() | SQUARE_G6.bitboard();
51
52    loop {
53        println!("\n{}", bb.pretty_print_string());
54
55        let (sq, ok) = bb.pop_square();
56
57        if ok {
58            println!("{}", sq.uci());
59        } else {
60            println!("no square could be popped\n");
61            break;
62        }
63    }
64
65    println!(
66        "{}",
67        jump_attack(SQUARE_E4, &KNIGHT_DELTAS, SQUARE_F6.bitboard()).pretty_print_string()
68    );
69
70    println!(
71        "{}",
72        sliding_attack(SQUARE_E4, &QUEEN_DELTAS, SQUARE_G6.bitboard()).pretty_print_string()
73    );
74
75    println!("{}", BISHOP_ATTACK[SQUARE_C7].pretty_print_string());
76
77    println!("{}", KING_AREA[SQUARE_G8].pretty_print_string());
78}
79
80pub fn enum_occup_demo() {
81    let occup = BISHOP_ATTACK[SQUARE_C7];
82
83    let mut mask: usize = 0;
84
85    loop {
86        if mask < occup.variation_count() {
87            println!(
88                "{}\n{}",
89                mask,
90                translate_mask_to_occupancy(mask, occup).pretty_print_string()
91            );
92            mask += 1;
93        } else {
94            break;
95        }
96    }
97}
98
99pub fn mobility_demo() {
100    println!(
101        "{}",
102        queen_mobility(
103            SQUARE_E4,
104            MoveGenMode::All,
105            SQUARE_G6.bitboard() | SQUARE_C4.bitboard(),
106            SQUARE_D5.bitboard() | SQUARE_E7.bitboard()
107        )
108        .pretty_print_string()
109    )
110}
111
112pub fn magic_space() {
113    let tb = total_magic_space(BISHOP_MAGICS);
114
115    let sb = tb * std::mem::size_of::<Bitboard>();
116
117    println!("total bishop magic space {} bytes", sb);
118
119    let tr = total_magic_space(ROOK_MAGICS);
120
121    let sr = tr * std::mem::size_of::<Bitboard>();
122
123    println!("total rook magic space {} bytes", sr);
124
125    println!(
126        "\ngrand total magic space {} bytes = {:0.2} MiBs",
127        sb + sr,
128        (sb + sr) as f32 / 1e6
129    );
130
131    println!("magic units bishop {} rook {} total {}", tb, tr, tb + tr);
132}
133
134impl Uci {
135    pub fn execute_uci_command(&self) {
136        println!("id name {}", self.engine_name);
137        println!("id author {}\n", self.engine_author);
138        println!("uciok");
139    }
140
141    pub fn process_uci_command(&mut self, line: String) -> bool {
142        let parts: Vec<&str> = line.split(" ").collect();
143
144        let command = parts[0];
145
146        if command == "quit" || command == "q" || command == "exit" || command == "x" {
147            return false;
148        }
149
150        if command == "uci" {
151            self.execute_uci_command();
152            return true;
153        }
154
155        if command == "i" {
156            self.linear_game.print();
157            return true;
158        }
159
160        if command == "demo" {
161            let mut arg = "";
162
163            if parts.len() > 0 {
164                arg = parts[1];
165            }
166
167            match arg {
168                "occup" => enum_occup_demo(),
169                "mob" => mobility_demo(),
170                "space" => magic_space(),
171                _ => demo(),
172            }
173
174            return true;
175        }
176
177        if command == "perft" || command == "p" {
178            let depth = if command == "p" {
179                4
180            } else {
181                parts[1].parse().expect("illegal perft depth")
182            };
183            let perft_result = self.linear_game.perft(depth);
184
185            println!(
186                "node(s) {:?} , time {:.2} sec(s) , nps {} kNode(s)/sec",
187                perft_result.0, perft_result.1, perft_result.2
188            );
189        }
190
191        if command == "bb" {
192            self.linear_game.current().print_bitboards();
193
194            return true;
195        }
196
197        if command == "d" {
198            self.linear_game.pop();
199            self.linear_game.print();
200        }
201
202        match command.parse::<usize>() {
203            Ok(n) => {
204                if n > 0 {
205                    self.linear_game.push_by_index(n - 1);
206                    self.linear_game.print();
207                }
208                return true;
209            }
210            Err(_) => (),
211        }
212
213        true
214    }
215
216    pub fn welcome(&self, build_info: &str) {
217        println!(
218            "{} bitboard multi variant uci chess analysis engine by {} [ {} ]",
219            self.engine_name, self.engine_author, build_info
220        );
221    }
222
223    pub fn uci_loop(&mut self) {
224        let stdin = io::stdin();
225
226        for line in stdin.lock().lines() {
227            if !self.process_uci_command(line.unwrap()) {
228                break;
229            }
230        }
231    }
232}