katago_analysis/
config.rs1use serde::Serialize;
2use serde_json::{Map, Value};
3
4#[derive(Debug, Clone, Default, Serialize)]
15#[serde(transparent)]
16pub struct Config(Map<String, Value>);
17
18impl Config {
19 pub fn new() -> Self {
21 Default::default()
22 }
23
24 pub fn insert(&mut self, key: impl Into<String>, value: impl Into<Value>) -> &mut Self {
26 self.0.insert(key.into(), value.into());
27 self
28 }
29
30 pub fn remove(&mut self, key: &str) -> &mut Self {
32 self.0.remove(key);
33 self
34 }
35
36 pub fn with(mut self, key: impl Into<String>, value: impl Into<Value>) -> Self {
38 self.insert(key, value);
39 self
40 }
41
42 pub fn to_command_line_arg(&self) -> Result<String, String> {
46 Ok(self
47 .0
48 .iter()
49 .map(|(k, v)| {
50 let value = match v {
51 Value::String(s) => s.clone(),
52 Value::Number(n) => n.to_string(),
53 Value::Bool(b) => b.to_string(),
54 _ => return Err(k.clone()),
55 };
56 Ok(format!("{}={}", k, value))
57 })
58 .collect::<Result<Vec<String>, String>>()?
59 .join(","))
60 }
61
62 pub fn with_analysis_pv_len(self, analysis_pv_len: usize) -> Self {
64 self.with("analysisPVLen", analysis_pv_len)
65 }
66
67 pub fn with_anti_mirror(self, anti_mirror: bool) -> Self {
69 self.with("antiMirror", anti_mirror)
70 }
71
72 pub fn with_human_sl_profile(self, human_sl_profile: impl Into<String>) -> Self {
74 self.with("humanSLProfile", human_sl_profile.into())
75 }
76
77 pub fn with_ignore_pre_root_history(self, ignore_pre_root_history: bool) -> Self {
79 self.with("ignorePreRootHistory", ignore_pre_root_history)
80 }
81
82 pub fn with_max_time(self, max_time: f64) -> Self {
84 self.with("maxTime", max_time)
85 }
86
87 pub fn with_max_visits(self, max_visits: u32) -> Self {
89 self.with("maxVisits", max_visits)
90 }
91
92 pub fn with_num_analysis_threads(self, num_analysis_threads: u32) -> Self {
94 self.with("numAnalysisThreads", num_analysis_threads)
95 }
96
97 pub fn with_num_search_threads_per_analysis_thread(self, num_search_threads: u32) -> Self {
99 self.with("numSearchThreadsPerAnalysisThread", num_search_threads)
100 }
101
102 pub fn with_playout_doubling_advantage(self, playout_doubling_advantage: f64) -> Self {
104 self.with("playoutDoublingAdvantage", playout_doubling_advantage)
105 }
106
107 pub fn with_report_analysis_winrates_as(self, report_analysis_winrates_as: Side) -> Self {
109 self.with("reportAnalysisWinratesAs", report_analysis_winrates_as)
110 }
111
112 pub fn with_root_num_symmetries_to_sample(self, root_num_symmetries_to_sample: u8) -> Self {
114 self.with("rootNumSymmetriesToSample", root_num_symmetries_to_sample)
115 }
116
117 pub fn with_wide_root_noise(self, wide_root_noise: f64) -> Self {
119 self.with("wideRootNoise", wide_root_noise)
120 }
121}
122
123#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
125pub enum Side {
126 Black,
128
129 White,
131
132 SideToMove,
134}
135
136impl From<Side> for Value {
137 fn from(side: Side) -> Self {
138 Value::String(
139 match side {
140 Side::Black => "BLACK",
141 Side::White => "WHITE",
142 Side::SideToMove => "SIDETOMOVE",
143 }
144 .to_string(),
145 )
146 }
147}