From 969aed2734e829f55668420b45fd44e10f144367 Mon Sep 17 00:00:00 2001 From: Taylor Bockman Date: Wed, 13 Dec 2017 21:15:02 -0800 Subject: [PATCH] Some small work on engine options --- README.md | 16 ++++++++++++++-- src/lib.rs | 8 +++----- src/options.rs | 45 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 61 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 7b39224..6d71e60 100644 --- a/README.md +++ b/README.md @@ -53,8 +53,20 @@ 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. You must configure this before calling `Engine::new` so this guide assumes -you've done that already. +the UCI standard for the available options: + +```EXAMPLE OF CONFIGURATION OF OPTIONS``` + +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. + +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 diff --git a/src/lib.rs b/src/lib.rs index 7489c06..ef6286e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -64,13 +64,11 @@ 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 a hashmap with keys that are constant strings in the options.rs + // 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. - // How can you make this as easy as possible for the user...give it some thought. The value has to be - // some sort of object that can store various optiobns that change on the option. - // Since options are fixed it would be nice to type check the key values. Maybe use a trait or something - // that is actually a wrapped string, but typecheckable so not just any string can be put in. + // 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 // Again this command must complete before we can say the engine is connected, so panicking at this stage is ok diff --git a/src/options.rs b/src/options.rs index 8a974fc..a576ed9 100644 --- a/src/options.rs +++ b/src/options.rs @@ -1 +1,44 @@ -//! Options contains constant strings representing the options that are possible in an UCI engin. +//! Options contains everything related to engine options. The idea behind this is to take as much +//! advantage of the typechecker as possible. As a result, engine option names are constant static strings, +//! and EngineOption tries to be flexible so it can be reused for each option, which also maintaining some +//! of the nicer parts of typechecking. + +#[derive(Debug)] +enum EngineOptionType { + Check, + Spin, + Combo, + Button, + TypeString, // `String` is a reserved word so `TypeString` is substituted +} + +#[derive(Debug)] +enum EngineOptionDataType { + DefaultVal, // `Default` is reserved so `DefaultVal` is used + Min, + Max, + Var, +} + +#[derive(Debug, PartialEq)] +struct EngineOption { + name: String, + option_type: EngineOptionType, + option_data: HashMap>, +} + +impl PartialEq for EngineOption { + pub fn eq(&self, other: EngineOption) { + // TODO: Implement equality on the EngineOption struct and write tests for it. + } +} + +impl EngineOption { + pub fn option_string(&self) -> String { + // TODO: Implement this to save this when looping through and sending options + // TODO: This should be tested in isolation as well + // This should handle the case where optional min max var are specified as well. + // pattern match the engine option type and convert it to the correct string. + format!("PUT THE FULL COMMAND STRING HERE!"); + } +}