Conversation
- Cleaned up main.rs to only run UCI mode - Removed all interactive mode functions and constants - Simplified codebase while maintaining full feature parity - UCI implementation provides all functionality plus more
There was a problem hiding this comment.
Pull Request Overview
Adds full Universal Chess Interface (UCI) support by introducing new parsing utilities, a search manager for async UCI output, and refactoring main.rs to always run in UCI mode.
- Utilities for converting and parsing UCI move strings and building principal variation (PV) lines.
SearchManagerhandles threaded searches, timing, infinite/depth-based searches, and UCI-compliant info output.- New
protocolmodule parses UCIgo,position, andsetoptioncommands;main.rsnow launches the UCI loop only and interactive mode is removed.
Reviewed Changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/uci/utils.rs | Implement UCI move formatting/parsing and PV line construction |
| src/uci/search_manager.rs | Introduce SearchManager to manage and output UCI search results |
| src/uci/protocol.rs | Parse go, position, and setoption commands into structs |
| src/uci/mod.rs | Entry point for the UCI read/dispatch loop |
| src/uci/engine.rs | Extend engine to handle UCI commands, options, and searches |
| src/uci/commands.rs | Registry of valid UCI commands (currently unused) |
| src/searcher.rs | Update searcher to support external stop flags and clean up style |
| src/main.rs | Switch to UCI-only mode and remove old interactive logic |
| README.md | Expanded UCI usage docs (interactive section now outdated) |
| Cargo.toml | Removed an obsolete chess-tui dependency |
Comments suppressed due to low confidence (2)
README.md:70
- Interactive mode instructions are outdated—
main.rsno longer supports direct terminal play. Please update or remove the interactive usage section to reflect UCI-only mode.
cargo run --release
src/searcher.rs:355
- [nitpick] The temporary variable
tt_is ambiguous. Renaming it toentryor a more descriptive name would improve readability.
let tt_ = tt_eval.unwrap();
| "display", | ||
| ]; | ||
|
|
||
| pub fn is_valid_uci_command(command: &str) -> bool { |
There was a problem hiding this comment.
The is_valid_uci_command function and UCI_COMMANDS array are defined but never used in the dispatch loop. Consider integrating this check or removing the unused module.
| println!( | ||
| "info string Starting search on position: {}", | ||
| board.to_string() | ||
| ); | ||
|
|
||
| // Check if there are legal moves | ||
| let legal_moves: Vec<chess::ChessMove> = MoveGen::new_legal(&board).collect(); | ||
| println!("info string Legal moves count: {}", legal_moves.len()); | ||
| if legal_moves.len() > 0 { | ||
| println!( | ||
| "info string First few legal moves: {:?}", | ||
| &legal_moves[..legal_moves.len().min(3)] | ||
| ); | ||
| } else { | ||
| println!("info string No legal moves available!"); | ||
| } | ||
| io::stdout().flush().unwrap(); |
There was a problem hiding this comment.
[nitpick] Multiple flush() calls after individual println! statements can degrade performance. Consider batching output or flushing once after grouped messages.
| println!( | |
| "info string Starting search on position: {}", | |
| board.to_string() | |
| ); | |
| // Check if there are legal moves | |
| let legal_moves: Vec<chess::ChessMove> = MoveGen::new_legal(&board).collect(); | |
| println!("info string Legal moves count: {}", legal_moves.len()); | |
| if legal_moves.len() > 0 { | |
| println!( | |
| "info string First few legal moves: {:?}", | |
| &legal_moves[..legal_moves.len().min(3)] | |
| ); | |
| } else { | |
| println!("info string No legal moves available!"); | |
| } | |
| io::stdout().flush().unwrap(); | |
| let legal_moves: Vec<chess::ChessMove> = MoveGen::new_legal(&board).collect(); | |
| let debug_message = if legal_moves.len() > 0 { | |
| format!( | |
| "info string Starting search on position: {}\n\ | |
| info string Legal moves count: {}\n\ | |
| info string First few legal moves: {:?}", | |
| board.to_string(), | |
| legal_moves.len(), | |
| &legal_moves[..legal_moves.len().min(3)] | |
| ) | |
| } else { | |
| format!( | |
| "info string Starting search on position: {}\n\ | |
| info string Legal moves count: {}\n\ | |
| info string No legal moves available!", | |
| board.to_string(), | |
| legal_moves.len() | |
| ) | |
| }; | |
| println!("{}", debug_message); |
| } | ||
| i += 2; | ||
| } | ||
| "nodes" if i + 1 < tokens.len() => { |
There was a problem hiding this comment.
The nodes (and similarly mate) parameter is parsed into GoParams but never used in the search logic. Either implement support for stopping by node count/mate in SearchManager or remove parsing of unused options.
There was a problem hiding this comment.
Bug: Search Initialization Ignores Stop Flag
Non-infinite searches (time-based and depth-based) cannot be stopped by the UCI 'stop' command. The Searcher is incorrectly initialized without the external stop flag (is_searching) for these types, unlike infinite searches which use Searcher::new_with_stop_flag(). This prevents immediate termination via stop_search(), violating UCI protocol expectations.
src/uci/search_manager.rs#L69-L77
Chess-AI-Rust/src/uci/search_manager.rs
Lines 69 to 77 in c06fe6f
src/uci/search_manager.rs#L178-L183
Chess-AI-Rust/src/uci/search_manager.rs
Lines 178 to 183 in c06fe6f
src/uci/search_manager.rs#L253-L258
Chess-AI-Rust/src/uci/search_manager.rs
Lines 253 to 258 in c06fe6f
Was this report helpful? Give feedback by reacting with 👍 or 👎
No description provided.