use serde::Serialize;
use serde_json::{Map, Value};
#[derive(Debug, Clone, Default, Serialize)]
#[serde(transparent)]
pub struct Config(Map<String, Value>);
impl Config {
pub fn new() -> Self {
Default::default()
}
pub fn insert(&mut self, key: impl Into<String>, value: impl Into<Value>) -> &mut Self {
self.0.insert(key.into(), value.into());
self
}
pub fn remove(&mut self, key: &str) -> &mut Self {
self.0.remove(key);
self
}
pub fn with(mut self, key: impl Into<String>, value: impl Into<Value>) -> Self {
self.insert(key, value);
self
}
pub fn to_command_line_arg(&self) -> Result<String, String> {
Ok(self
.0
.iter()
.map(|(k, v)| {
let value = match v {
Value::String(s) => s.clone(),
Value::Number(n) => n.to_string(),
Value::Bool(b) => b.to_string(),
_ => return Err(k.clone()),
};
Ok(format!("{}={}", k, value))
})
.collect::<Result<Vec<String>, String>>()?
.join(","))
}
pub fn with_analysis_pv_len(self, analysis_pv_len: usize) -> Self {
self.with("analysisPVLen", analysis_pv_len)
}
pub fn with_anti_mirror(self, anti_mirror: bool) -> Self {
self.with("antiMirror", anti_mirror)
}
pub fn with_human_sl_profile(self, human_sl_profile: impl Into<String>) -> Self {
self.with("humanSLProfile", human_sl_profile.into())
}
pub fn with_ignore_pre_root_history(self, ignore_pre_root_history: bool) -> Self {
self.with("ignorePreRootHistory", ignore_pre_root_history)
}
pub fn with_max_time(self, max_time: f64) -> Self {
self.with("maxTime", max_time)
}
pub fn with_max_visits(self, max_visits: u32) -> Self {
self.with("maxVisits", max_visits)
}
pub fn with_num_analysis_threads(self, num_analysis_threads: u32) -> Self {
self.with("numAnalysisThreads", num_analysis_threads)
}
pub fn with_num_search_threads_per_analysis_thread(self, num_search_threads: u32) -> Self {
self.with("numSearchThreadsPerAnalysisThread", num_search_threads)
}
pub fn with_playout_doubling_advantage(self, playout_doubling_advantage: f64) -> Self {
self.with("playoutDoublingAdvantage", playout_doubling_advantage)
}
pub fn with_report_analysis_winrates_as(self, report_analysis_winrates_as: Side) -> Self {
self.with("reportAnalysisWinratesAs", report_analysis_winrates_as)
}
pub fn with_root_num_symmetries_to_sample(self, root_num_symmetries_to_sample: u8) -> Self {
self.with("rootNumSymmetriesToSample", root_num_symmetries_to_sample)
}
pub fn with_wide_root_noise(self, wide_root_noise: f64) -> Self {
self.with("wideRootNoise", wide_root_noise)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Side {
Black,
White,
SideToMove,
}
impl From<Side> for Value {
fn from(side: Side) -> Self {
Value::String(
match side {
Side::Black => "BLACK",
Side::White => "WHITE",
Side::SideToMove => "SIDETOMOVE",
}
.to_string(),
)
}
}