You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
5.2 KiB
143 lines
5.2 KiB
//! 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. |
|
|
|
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 |
|
pub const HASH: &'static str = "Hash"; |
|
|
|
/// Represents the Nalimov Path option |
|
pub const NALIMOVPATH: &'static str = "NalimovPath"; |
|
|
|
/// Represents the Nalimov Cache option |
|
pub const NALIMOVCACHE: &'static str = "NalimovCache"; |
|
|
|
/// Represents the ponder option |
|
pub const PONDER: &'static str = "Ponder"; |
|
|
|
/// Represents the OwnBook option |
|
pub const OWNBOOK: &'static str = "OwnBook"; |
|
|
|
/// Represents the MultiPV option |
|
pub const MULTIPV: &'static str = "MultiPV"; |
|
|
|
/// Represents the UCI_ShowCurrLine option |
|
pub const UCISHOWCURRLINE: &'static str = "UCI_ShowCurrLine"; |
|
|
|
/// Represents the UCI_Refutations option |
|
pub const UCISHOWREFUTATIONS: &'static str = "UCI_ShowRefutations"; |
|
|
|
/// Represents the UCI_LimitStrength option |
|
pub const UCILIMITSTRENGTH: &'static str = "UCI_LimitStrength"; |
|
|
|
/// Represents the UCI_Elo option |
|
pub const UCIELO: &'static str = "UCI_Elo"; |
|
|
|
/// Represents the UCI_AnalysisMode option |
|
pub const UCIANALYSISMODE: &'static str = "UCI_AnalysisMode"; |
|
|
|
/// Represents the UCI_Opponent option |
|
pub const UCIOPPONENT: &'static str = "UCI_Opponent"; |
|
|
|
} |
|
|
|
/// The `EngineOptionType` type used to indicate what type of option the GUI should display |
|
#[derive(Copy, Clone, Debug, PartialEq)] |
|
pub enum EngineOptionType { |
|
Check, |
|
Spin, |
|
Combo, |
|
Button, |
|
TypeString, // `String` is a reserved word so `TypeString` is substituted |
|
} |
|
|
|
#[derive(Clone, Debug, PartialEq, PartialOrd)] |
|
/// The `EngineOptionData` makes the data type generic so one `EngineOption` can represent everything |
|
/// This would be set to the type of the engine option (ex. i32) |
|
pub enum EngineOptionData { |
|
Int(i32), |
|
Float(f64), |
|
Text(String), |
|
} |
|
|
|
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] |
|
/// The `EngineOptionDataType` type used to indicate the type of the `EngineOption` setting |
|
pub enum EngineOptionDataType { |
|
DefaultVal, // `Default` is reserved so `DefaultVal` is used |
|
Min, |
|
Max, |
|
Var, |
|
} |
|
|
|
#[derive(Debug, PartialEq)] |
|
/// The `EngineOption` type is the overarching type representing a single configurable engine option |
|
pub struct EngineOption { |
|
pub name: &'static str, |
|
pub option_type: EngineOptionType, |
|
pub option_data: HashMap<EngineOptionDataType, EngineOptionData>, |
|
} |
|
|
|
impl EngineOption { |
|
|
|
/// Constructs a new EngineOption of type T |
|
pub fn new(name: &'static str, option_type: EngineOptionType, |
|
option_data: HashMap<EngineOptionDataType, EngineOptionData>) -> EngineOption { |
|
EngineOption { name, option_type, option_data, } |
|
} |
|
|
|
fn engine_option_data_string(d: &EngineOptionData) -> String { |
|
match d { |
|
&EngineOptionData::Int(v) => v.to_string(), |
|
&EngineOptionData::Float(v) => v.to_string(), |
|
&EngineOptionData::Text(ref v) => v.clone(), |
|
} |
|
} |
|
|
|
/// 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 |
|
// work that can be done later switching based on the option type, but for now it's reasonable to |
|
// expect the user understands the standard well enough to know which options take what kind |
|
// of settings. |
|
if self.option_data.contains_key(&EngineOptionDataType::DefaultVal) { |
|
let data = self.option_data.get(&EngineOptionDataType::DefaultVal); |
|
option_data_string.push_str(&format!(" {} {}", "default", |
|
EngineOption::engine_option_data_string(&data.unwrap()))); |
|
} |
|
|
|
if self.option_data.contains_key(&EngineOptionDataType::Min) { |
|
let data = self.option_data.get(&EngineOptionDataType::Min); |
|
option_data_string.push_str(&format!(" {} {}", "min", EngineOption::engine_option_data_string(&data.unwrap()))); |
|
} |
|
|
|
if self.option_data.contains_key(&EngineOptionDataType::Max) { |
|
let data = self.option_data.get(&EngineOptionDataType::Max); |
|
option_data_string.push_str(&format!(" {} {}", "max", EngineOption::engine_option_data_string(&data.unwrap()))); |
|
} |
|
|
|
if self.option_data.contains_key(&EngineOptionDataType::Var) { |
|
let data = self.option_data.get(&EngineOptionDataType::Var); |
|
option_data_string.push_str(&format!(" {} {}", "var", EngineOption::engine_option_data_string(&data.unwrap()))); |
|
} |
|
|
|
|
|
let ots = match self.option_type { |
|
EngineOptionType::Check => "check", |
|
EngineOptionType::Spin => "spin", |
|
EngineOptionType::Combo => "combo", |
|
EngineOptionType::Button => "button", |
|
EngineOptionType::TypeString => "string", |
|
}; |
|
|
|
format!("{} {} {} {} {}{}\n", commands::OPTION, commands::OPTIONNAME, self.name, |
|
commands::TYPE, ots, option_data_string) |
|
} |
|
}
|
|
|