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
//! A module for working with USI protocol in a type-safe way.
//!
//! USI protocol defines commands sent from either GUIs or engines.
//! Detail about USI protocol can be found at <http://www.geocities.jp/shogidokoro/usi.html>.
//!
//! # Data types representing commands defined in USI protocol.
//!
//! `GuiCommand` and `EngineCommand` represents input/output commands defined in the protocol.
//!
//! # Examples
//!
//! ```
//! use std::time::Duration;
//! use usi::{GuiCommand, ThinkParams, EngineCommand, BestMoveParams};
//!
//! // GuiCommand can be converted into the USI compliant string.
//! let params = ThinkParams::new().btime(Duration::from_secs(1)).wtime(Duration::from_secs(2));
//! let cmd = GuiCommand::Go(params);
//! assert_eq!("go btime 1000 wtime 2000", cmd.to_string());
//!
//! // EngineCommand can be parsed from the command string sent from the USI engine.
//! let cmd = EngineCommand::parse("bestmove 7g7f ponder 8c8d").unwrap();
//! match cmd {
//! EngineCommand::BestMove(BestMoveParams::MakeMove(ref m, Some(ref pm))) => {
//! assert_eq!("7g7f", *m);
//! assert_eq!("8c8d", *pm);
//! },
//! _ => unreachable!(),
//! }
//! ```
//!
//! # Working with a USI engine process
//!
//! `UsiEngineHandler` can be used to spawn the USI engine process.
//! You can send `GuiCommand`s and receive `EngineCommand`.
//!
//! # Examples
//! ```no_run
//! use usi::{BestMoveParams, Error, EngineCommand, GuiCommand, UsiEngineHandler};
//!
//! let mut handler = UsiEngineHandler::spawn("/path/to/usi_engine", "/path/to/working_dir").unwrap();
//!
//! // Get the USI engine information.
//! let info = handler.get_info().unwrap();
//! assert_eq!("engine name", info.name());
//!
//! // Set options.
//! handler.send_command(&GuiCommand::SetOption("USI_Ponder".to_string(), Some("true".to_string()))).unwrap();
//! handler.prepare().unwrap();
//! handler.send_command(&GuiCommand::UsiNewGame).unwrap();
//!
//! // Start listening to the engine output.
//! // You can pass the closure which will be called
//! // everytime new command is received from the engine.
//! handler.listen(move |output| -> Result<(), Error> {
//! match output.response() {
//! Some(EngineCommand::BestMove(BestMoveParams::MakeMove(
//! ref best_move_sfen,
//! ref ponder_move,
//! ))) => {
//! assert_eq!("5g5f", best_move_sfen);
//! }
//! _ => {}
//! }
//! Ok(())
//! }).unwrap();
//! handler.send_command(&GuiCommand::Usi).unwrap();
//! ```
mod error;
mod process;
mod protocol;
pub use self::error::*;
pub use self::process::*;
pub use self::protocol::*;