Browse Source

SOme issue with backslash escaping

ag-yep
Taylor Bockman 7 years ago
parent
commit
428da563dd
  1. 22
      README.md
  2. 9
      src/lib.rs
  3. 4
      src/options.rs
  4. 49
      tests/lib.rs

22
README.md

@ -63,9 +63,18 @@ Next, you'll need to create a copy of `Engine` by calling `Engine::new`. Once th
`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:
```EXAMPLE OF CONFIGURATION OF OPTIONS```
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<T>`
@ -115,3 +124,10 @@ an `isready` command which you will be responsible for replying to by using `Eng
** 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.

9
src/lib.rs

@ -69,12 +69,9 @@ where
/// Sends all available options in the options configuration and a final UCIOK meaning we are reading to go.
pub fn send_available_options(&mut self) {
// NOTE: Options can be represented as an array of EngineOption in the options.rs
// file and values are the associated options.
// This function will construct the proper string from the objects.
// Construct the strings using the `option_string` function of each engine option. Let it tell you
// what it is.
// TODO: This needs to be tested majorly
for eo in &self.engine_options {
write!(&mut self.writer, "{}", eo.to_string()).expect(&format!("failed to send `{}`", eo.to_string()));
}
// Again this command must complete before we can say the engine is connected, so panicking at this stage is ok
write!(&mut self.writer, "{}", commands::UCIOK).expect("failed to send `uciok` command");

4
src/options.rs

@ -6,6 +6,7 @@
use std::collections::HashMap;
use commands;
/// These constants can be used for naming options easily. Option name is fairly flexible.
pub mod constants {
/// Represents the hash option
@ -98,7 +99,8 @@ impl EngineOption {
}
}
pub fn option_string(&self) -> String {
/// Turns the EngineOption into a string that can be sent to the GUI
pub fn to_string(&self) -> String {
let mut option_data_string: String = String::new();
// NOTE: The user is left to understand what option takes which of these data type values. There's some

49
tests/lib.rs

@ -25,10 +25,6 @@ fn send_identification_data() {
let mut e = Engine::new("test_name", "test", &input[..], &mut output, vec!());
e.identify();
}
// NOTE: This looks weird bceause you'd think it would store each insertion into the output buffer
// as a separate element of that buffer, but it really just appends the two strings since in reality
// the buffer would be flushed after reading.
assert_eq!(str::from_utf8(&output).unwrap_or("Unwrapping output failed in send_identification_data"),
"id name test_name\nid author test\n");
}
@ -86,19 +82,46 @@ fn engine_option_string() {
(EngineOptionDataType::Max, EngineOptionData::Int(128))
].iter().cloned().collect();
let o = EngineOption {
name: name,
option_type: option_type,
option_data: option_data,
};
let o = EngineOption { name, option_type, option_data, };
let expected = "option name Hash type spin default 1 min 1 max 128\n";
assert_eq!(o.option_string(), expected);
assert_eq!(o.to_string(), expected);
}
#[test]
fn send_available_engine_options() {
// This should send two to three options and check the string in the
// buffer to make sure it's correct.
assert_eq!(true, false);
let input = b"UNUSED";
let mut output = Vec::new();
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(),
};
let o2 = EngineOption {
name: constants::NALIMOVPATH,
option_type: EngineOptionType::TypeString,
option_data: [(EngineOptionDataType::DefaultVal, EngineOptionData::Text(String::from(r"c:\"))),
].iter().cloned().collect(),
};
let o3 = EngineOption {
name: "Clear Hash",
option_type: EngineOptionType::Button,
option_data: [].iter().cloned().collect(),
};
{
let mut e = Engine::new("test_name", "test", &input[..], &mut output, vec!(o1, o2, o3));
e.send_available_options();
}
assert_eq!(str::from_utf8(&output).unwrap_or("Unwrapping output failed in send_identification_data"),
"option name Hash type spin default 1 min 1 max 128\n\
option name NalimovPath type string default c:\n\
option name Clear Hash type button\n\
uciok\n");
}

Loading…
Cancel
Save