aboutsummaryrefslogtreecommitdiff
path: root/src/grossmeister/UCI.rs
blob: 1e85b715ee5661e704f1595f78eec3f600aa7017 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use std::{io::stdin, thread::Builder};

use crate::{board::{Board, io::IO}, moves::Move, player::Player};

use super::Grossmeister;

const NAME: &str = "Chessnost";
const AUTHOR: &str = "Eugene Sokolov";

impl Grossmeister {
    pub fn start(&mut self) {
        let mut search_handle = None;

        loop {
            let mut cmd = String::new();
            stdin().read_line(&mut cmd).unwrap();
            let mut tokens = cmd.trim().split(' ');

            if let Some(token) = tokens.next() {
                match token {
                    "uci" => {
                        println!("id name {}", NAME);
                        println!("id author {}", AUTHOR);
                        println!("uciok");
                    }
                    "debug" => {
                        if let Some(token) = tokens.next() {
                            match token {
                                "on" => self.debug = true,
                                "off" => self.debug = false,
                                _ => {
                                    panic!("Wrong option to debug: {}. CMD: {}", token, cmd);
                                },
                            }
                        };
                    }
                    "isready" => {
                        println!("readyok");
                    }
                    "setoption" => {
                        todo!()
                    }
                    "ucinewgame" => {
                        todo!("What should we even do here?")
                    }
                    "position" => {
                        if let Some(token) = tokens.next() {
                            match token  {
                                "startpos" => {
                                    self.board = Board::new();

                                    if let Some(token) = tokens.next() {
                                        if token == "moves" {
                                            for token in tokens.by_ref() {
                                                let mov = Move::from_notation(token.chars());
                                                self.board.make_move(mov);
                                                println!("{:?}", mov);
                                                self.board.print();
                                            }
                                        } else {
                                            panic!("Unexpected token: {}. CMD: {}", token, cmd);
                                        }
                                    }
                                }
                                "fen" => {
                                    // TODO: handle "moves" command after "fen"?
                                    let index = "position fen".len() + 1;
                                    if let Some(fen) = cmd.get(index..) {
                                        self.board = Board::from_FEN(fen.to_string());
                                    };
                                }
                                _ => {
                                    todo!("Parse FEN")
                                }
                            }
                        } else {
                            todo!("Decide what to do when position is now provided")
                        }
                    }
                    "go" => {
                        if let Some(token) = tokens.next() {
                            match token {
                                "searchmoves" => todo!(),
                                "ponder" => todo!(),
                                "wtime" => todo!(),
                                "btime" => todo!(),
                                "winc" => todo!(),
                                "binc" => todo!(),
                                "movestogo" => todo!(),
                                "depth" => todo!(),
                                "nodes" => todo!(),
                                "mate" => todo!(),
                                "movetime" => todo!(),
                                "infinite" => {
                                    // Clone current self and move it
                                    // into thread to analyze a position
                                    let mut gm = self.clone();
                                    let builder = Builder::new();

                                    search_handle = Some(builder.spawn(move || {
                                        gm.analyze(gm.board);
                                        gm
                                    }).unwrap());
                                },
                                _ => todo!()
                            }
                        }
                    },
                    "stop" => {
                        self.should_halt.store(true, std::sync::atomic::Ordering::Relaxed);
                        if let Some(hand) = search_handle.take() {
                            // Search returns new SELF that is more powerful
                            // because he evaluated many new positions and
                            // his transposition table is more saturated
                            *self = hand.join().unwrap();
                        }
                        self.should_halt.store(false, std::sync::atomic::Ordering::Relaxed);
                    }
                    "ponderhit" => todo!(),
                    "quit" => break,
                    _ => {},
                }
            }
        }
    }
}