Add auxilary functions

This commit is contained in:
Baptiste Fouques 2023-01-16 17:08:06 +01:00
parent 08a39c258e
commit a65678343a
2 changed files with 53 additions and 27 deletions

View File

@ -32,8 +32,8 @@ use chess::{Game, Board, ChessMove};
/// uci.push_raw("quit\n"); /// uci.push_raw("quit\n");
/// ``` /// ```
pub struct UciEngine<Fi: Read, Fo: Write> { pub struct UciEngine<Fi: Read, Fo: Write> {
source: BufReader<Fi>, source: Option<BufReader<Fi>>,
destination: Fo, destination: Option<Fo>,
uciok: bool, uciok: bool,
id: Id, id: Id,
initial: Board, initial: Board,
@ -45,9 +45,9 @@ impl<Fi: Read, Fo: Write> UciEngine<Fi, Fo> {
/// Create new game manager /// Create new game manager
/// ///
/// Requires line by line input and output streams to communicate with uci engine /// Requires line by line input and output streams to communicate with uci engine
pub fn new(source: Fi, destination: Fo) -> UciEngine<Fi, Fo> { pub fn new(source: Option<Fi>, destination: Option<Fo>) -> UciEngine<Fi, Fo> {
UciEngine::<Fi, Fo>{ UciEngine::<Fi, Fo>{
source: BufReader::new(source), source: if let Some(source) = source {Some(BufReader::new(source))} else {None},
destination, destination,
id: Id::new(), id: Id::new(),
uciok: false, uciok: false,
@ -148,45 +148,71 @@ impl<Fi: Read, Fo: Write> UciEngine<Fi, Fo> {
/// Retrieve a line from the uci engine input stream and parse it /// Retrieve a line from the uci engine input stream and parse it
pub fn pull(&mut self) { pub fn pull(&mut self) {
let mut command = String::new(); if let Some(source) = &mut self.source {
match self.source.read_line(&mut command) { let mut command = String::new();
Ok(0) => self.terminate("Chess engine closed connection."), match source.read_line(&mut command) {
Ok(_) => { Ok(0) => self.terminate("Chess engine closed connection."),
info!("← {}", command); Ok(_) => {
self.exec(&command) info!("← {}", command);
}, self.exec(&command)
Err(reason) => warn!("Unable to read from engine: {reason}"), },
Err(reason) => warn!("Unable to read from engine: {reason}"),
}
} else {
info!("❌ No connected uci engine");
} }
} }
/// Read a line from the uci engine input stream (do not parse) /// Read a line from the uci engine input stream (do not parse)
pub fn pull_raw(&mut self) -> Option<String> { pub fn pull_raw(&mut self) -> Option<String> {
let mut data = String::new(); if let Some(source) = &mut self.source {
match self.source.read_line(&mut data) { let mut data = String::new();
Ok(0) => {self.terminate("Chess engine closed connection."); None}, match source.read_line(&mut data) {
Ok(_) => {info!("↜ {}", data); Some(data.clone())}, Ok(0) => {self.terminate("Chess engine closed connection."); None},
Err(reason) => {warn!("Unable to read from engine: {reason}"); None}, Ok(_) => {info!("↜ {}", data); Some(data.clone())},
Err(reason) => {warn!("Unable to read from engine: {reason}"); None},
}
} else {
info!("❌ No connected uci engine");
None
} }
} }
/// Push a Uci Gui command to the engine /// Push a Uci Gui command to the engine
fn push(&mut self, command: GuiCommand) { fn push(&mut self, command: GuiCommand) {
let command_str = command.to_string(); if let Some(destination) = &mut self.destination {
match self.destination.write(&command_str.as_bytes()){ let command_str = command.to_string();
Ok(n) if n == command_str.len() => info!("→ gui: {command_str}"), match destination.write(&command_str.as_bytes()){
Ok(n) => warn!("⚠ gui: {command_str} truncated at {n}"), Ok(n) if n == command_str.len() => info!("→ gui: {command_str}"),
Err(reason) => warn!("Unable to send command {command_str}: {reason}"), Ok(n) => warn!("⚠ gui: {command_str} truncated at {n}"),
Err(reason) => warn!("Unable to send command {command_str}: {reason}"),
}
} else {
info!("❌ No connected uci engine");
} }
} }
/// Push string (not a game manager integrated command) to the Uci engine output stream /// Push string (not a game manager integrated command) to the Uci engine output stream
pub fn push_raw(&mut self, data: &str){ pub fn push_raw(&mut self, data: &str){
match self.destination.write(data.as_bytes()) { if let Some(destination) = &mut self.destination {
Ok(n) if n == data.len() => info!("↝ raw: {data}"), match destination.write(data.as_bytes()) {
Ok(n) => warn!("⚠ raw: {data} truncated at {n}"), Ok(n) if n == data.len() => info!("↝ raw: {data}"),
Err(reason) => warn!("Unable to send raw {data}: {reason}"), Ok(n) => warn!("⚠ raw: {data} truncated at {n}"),
Err(reason) => warn!("Unable to send raw {data}: {reason}"),
}
} else {
info!("❌ No connected uci engine");
} }
} }
} }
use chess::{Square, Piece, Color};
impl<Fi: Read, Fo: Write> UciEngine<Fi, Fo> {
pub fn piece_on(&self, square: Square) -> Option<Piece> {
self.game.current_position().piece_on(square)
}
pub fn color_on(&self, square: Square) -> Option<Color> {
self.game.current_position().color_on(square)
}
}
// LocalWords: uci // LocalWords: uci

View File

@ -22,7 +22,7 @@ pub fn main(){
}; };
let (sf_in,sf_out) = (process.stdin.expect("Program stdin"), process.stdout.expect("Program stdout")); let (sf_in,sf_out) = (process.stdin.expect("Program stdin"), process.stdout.expect("Program stdout"));
let mut uci = UciEngine::new(sf_out, sf_in); let mut uci = UciEngine::new(Some(sf_out), Some(sf_in));
uci.init(); uci.init();
println!("Engine: {} \nby: {}", println!("Engine: {} \nby: {}",