# UCI UCI is an acronym for **U**niversal **C**hess **I**nterface. It is a standard for communication that competes with XBoard/Winboard. [http://wbec-ridderkerk.nl/html/UCIProtocol.html](UCI) makes communication a little easier, but it seems there's a nearly religious debate on which is better. Here are some benefits to using UCI: * It works with Chessbase 14 * Simple to use * Fewer bugs in code * Built from scratch rather than ad-hoc * Flexible time controls * Additional search information can be displayed and to be fair, some downsides: * Stateless * Delegates some important decisions to the GUI * Difficult to add new features on top of it * Sends the whole move list each turn Overall, UCI seems to be fairly popular and is worth considering for your next engine. ## Why People shouldn't waste their time implementing protocols that really should be libraries. With this, you can include it in your project, build your engine on top of it, and be able to focus on what matters - beating Stockfish. ### Yeah, but why Rust? Originally I had written part of this library in C++. However, considering how prone people are to errors in C++, I decided to choose a language that provides a little more safety to the user. Currently [Rust is beating Go](http://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=rust&lang2=go) in the Computer Language Benchmark Game, so it was the winner. People who write chess engines care about performance. If you're not writing C/C++, Rust seems like the next best thing. ## Will You Implement Winboard? Yeah, probably. ## Why GPL 3.0? I have noticed that there are no good _free_ solutions so that anyone can build a chess engine. Since UCI is a common format, and something all engines (should) implement, making this chunk of it free makes _total_ sense. ## Usage UCI is designed to complement your chess engine rather than be a one-stop shop for engine development. As such, you will be responsible for maintaining the game loop. What UCI provides is a series of functions that will help you send data to, and receive data from the GUI. ### First Steps Your engine will first need to wait on STDIN for a command `uci` from the GUI. This indicates that your engine should switch to UCI mode. You can use `commands::UCI` to make sure the command text you are waiting for is correct. Next, you'll need to create a copy of `Engine` by calling `Engine::new`. Once this is setup, you can call `Engine::identify` to send identification information to the GUI. Once identification is done, you need to send your configuration options. This is dependent on your engine. Refer to the UCI standard for the available options. Here is an example of an option configuration: ```rust let o1 = EngineOption { name: constants::HASH, option_type: EngineOptionType::Spin, option_data: [(EngineOptionDataType::DefaultVal, EngineOptionData::Int(1)), (EngineOptionDataType::Min, EngineOptionData::Int(1)), (EngineOptionDataType::Max, EngineOptionData::Int(128)) ].iter().cloned().collect(); }; ``` As nice as it would be to have fully typechecked options you will need to be careful a little here. The available options your engine uses must be passed to `Engine::new` as an array of `Options::EngineOption` from `options.rs`. Every `Options::EngineOption` has a `name`, which you can use any of the `Options::*` constants to represent, a `type`, which can be an `Options::EngineOptionType`, and a hashmap of `Options::EngineOptionDataType` to `Options::EngineOptionDataValue`. Refer to the standard for more information on option configurations. The `T` type parameters represents the type of that particular `Options::EngineOption` and allows us to at least fix the type in the HashMap to a single type. You can still hurt yourself, but doing this makes it much harder. Keep this list of options close, the GUI may send back information after call `Engine::send_available_options` to reconfigure default settings. You must configure this before calling `Engine::new` so the rest of this guide assumes you've done that already. To send your configuration options simply call `Engine::send_available_options`. Once this finishes `uciok` will also be sent, indicating to the GUI your engine is ready to roll. At this point you need to set up two threads, one to calculate with your engine, and one to read STDIN. ``` EXAMPLE HERE WITH LOOPS IN THREADS AND BLOCKING AND WHATEVER ``` Notice how in our STDIN thread we are calling `Engine::parse` and the handling the output using a match statement depending on what kind of token it was. You are responsible for obeying the commands from this thread, the UCI library just makes it convenient to work with. At this point the engine will send a series of `setoption` commands to you in your STDIN thread. We can use the `Engine::parse` function to get these: ``` EXAMPLE HERE ``` Once the options are extracted you will be responsible for configuring your engine with the values. The GUI will send an `isready` command which you will be responsible for replying to by using `Engine::ready`. **TODO: MORE STUFF WITH EXAMPLES** **THINGS LIKE SENDINB BEST MOVE AFTER CALCULATING, ETC** **RECEIVING SETOPTION COMMANDS AND PROCESSING THEM** ### Other Options **TODO: Talk about the additional helpers available in the UCI library and what-not**. * Copy protection checking * Registration checking ** TODO: Put an example engine under `/examples` that does nothing but talks to the GUI and receives commands. ** Document it here and mention it can be used for guidance. ### Other Libraries in the works In the future more libraries will be available to help chess engine developers get started. I will be writing a library to give some standard implementations of [Zobrist Hashing](https://en.wikipedia.org/wiki/Zobrist_hashing), among other useful tools that are commonly re-implemented a thousand times for every engine.