diff options
Diffstat (limited to 'src/grossmeister/UCI.rs')
| -rw-r--r-- | src/grossmeister/UCI.rs | 185 | 
1 files changed, 98 insertions, 87 deletions
| diff --git a/src/grossmeister/UCI.rs b/src/grossmeister/UCI.rs index 2351b2f..50af980 100644 --- a/src/grossmeister/UCI.rs +++ b/src/grossmeister/UCI.rs @@ -14,103 +14,114 @@ impl Grossmeister {          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" => { -                        *self = Self::default() -                    } -                    "position" => { -                        match tokens.next()  { -                            Some("startpos") => { -                                self.board = Board::new(); -                            } -                            Some("fen") => { -                                let fen = (0..6).filter_map(|_| tokens.next()).collect::<Vec<_>>().join(" "); -                                self.board = Board::from_FEN(fen.to_string()); -                            } -                            _ => panic!("Expected position"), +            let tokens = cmd.trim().split(' '); +            if !self.parse_command(tokens, &mut search_handle) { +                break +            } +        } +    } + +    pub fn parse_command(&mut self, mut tokens: Split<char>, search_handle: &mut Option<JoinHandle<Self>>) -> bool { +        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: {}", token),                          } -                        if let Some("moves") = tokens.next() { -                            for token in tokens.by_ref() { -                                let input_move = Move::from_notation(token.chars()); -                                let moves = self.board.generate_pseudolegal_moves(); -                                if let Some(mov) = moves -                                    .iter() -                                        .find(|m| { -                                            let promo_matches = match input_move.kind { -                                                MoveKind::Promotion(piece) => match m.kind { -                                                    MoveKind::Promotion(another_piece) => piece.without_color() == another_piece.without_color(), -                                                    _ => false -                                                }, -                                                _ => true, -                                            }; -                                            promo_matches && m.source == input_move.source && m.target == input_move.target -                                        }) { -                                            self.board.make_move(*mov); -                                        } else { -                                            panic!("Illegal move: {}", input_move); -                                        } -                            } +                    }; +                } +                "isready" => { +                    println!("readyok"); +                } +                "setoption" => { +                    todo!() +                } +                "ucinewgame" => { +                    *self = Self::default() +                } +                "position" => { +                    match tokens.next()  { +                        Some("startpos") => { +                            self.board = Board::new(); +                        } +                        Some("fen") => { +                            let fen = (0..6).filter_map(|_| tokens.next()).collect::<Vec<_>>().join(" "); +                            self.board = Board::from_FEN(fen);                          } +                        _ => panic!("Expected position"),                      } -                    "go" => { -                        // Before we go, let's join to the latest search -                        if let Some(hand) = search_handle.take() { -                            let better_self = hand.join().unwrap(); -                            self.transposition_table = better_self.transposition_table; +                    if let Some("moves") = tokens.next() { +                        for token in tokens.by_ref() { +                            let input_move = Move::from_notation(token.chars()); +                            let moves = self.board.generate_pseudolegal_moves(); +                            if let Some(mov) = moves +                                .iter() +                                    .find(|m| { +                                        let promo_matches = match input_move.kind { +                                            MoveKind::Promotion(piece) => match m.kind { +                                                MoveKind::Promotion(another_piece) => piece.without_color() == another_piece.without_color(), +                                                _ => false +                                            }, +                                            _ => true, +                                        }; +                                        promo_matches && m.source == input_move.source && m.target == input_move.target +                                    }) { +                                        self.board.make_move(*mov); +                                        let repeated = self.board.positions.iter().filter(|&&p| p == self.board.hash).count(); +                                        if self.board.hash == 13465997660506371065 { +                                            self.board.print(); +                                            dbg!(mov, repeated, self.board.hash, self.board.ply); +                                        } +                                    } else { +                                        panic!("Illegal move: {}", input_move); +                                    }                          } - -                        search_handle = Some(self.parse_go(tokens, false));                      } -                    "stop" => { -                        self.should_halt.store(true, std::sync::atomic::Ordering::SeqCst); +                } +                "go" => { +                    // Before we go, let's join to the latest search +                    if let Some(hand) = search_handle.take() { +                        let better_self = hand.join().unwrap(); +                        self.transposition_table = better_self.transposition_table;                      } -                    "ponderhit" => { -                        // Since we were pondering without any scheduled halting previously, -                        // in case of ponderhit we need to schedule a new halting based on clock -                        // TODO: isn't the color flipped here? Might lead to time management bugs -                        let color = self.board.color(); -                        let duration = (self.board.clock.time[color as usize] + self.board.clock.increment[color as usize]) / 20; -                        let halt_scheduled = self.schedule_halt(duration); - -                        // Join to the current pondering search -                        if let Some(hand) = search_handle.take() { -                            let better_self = hand.join().unwrap(); -                            halt_scheduled.store(false, Ordering::SeqCst); // Cancel scheduled halting -                            self.transposition_table = better_self.transposition_table; -                        } else { -                            panic!("Search thread not found!"); -                        } + +                    *search_handle = Some(self.parse_go(tokens, false)); +                } +                "stop" => { +                    self.should_halt.store(true, std::sync::atomic::Ordering::SeqCst); +                } +                "ponderhit" => { +                    // Since we were pondering without any scheduled halting previously, +                    // in case of ponderhit we need to schedule a new halting based on clock +                    // TODO: isn't the color flipped here? Might lead to time management bugs +                    let color = self.board.color(); +                    let duration = (self.board.clock.time[color as usize] + self.board.clock.increment[color as usize]) / 20; +                    let halt_scheduled = self.schedule_halt(duration); + +                    // Join to the current pondering search +                    if let Some(hand) = search_handle.take() { +                        let better_self = hand.join().unwrap(); +                        halt_scheduled.store(false, Ordering::SeqCst); // Cancel scheduled halting +                        self.transposition_table = better_self.transposition_table; +                    } else { +                        panic!("Search thread not found!");                      } -                    "quit" => break, -                    _ => {},                  } +                "quit" => return false, +                // Non-UCI debug commands +                "print" => self.board.print(), +                _ => {},              }          } +        true      }      fn parse_go(&mut self, mut tokens: Split<char>, ponder: bool) -> JoinHandle<Self> { | 
