weiss_core/
config.rs

1use crate::db::CardId;
2use serde::{Deserialize, Serialize};
3use std::collections::HashSet;
4
5#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, Default)]
6pub enum ErrorPolicy {
7    Strict,
8    #[default]
9    LenientTerminate,
10    LenientNoop,
11}
12
13#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, Default)]
14pub enum ObservationVisibility {
15    #[default]
16    Public,
17    Full,
18}
19
20#[derive(Clone, Debug, Serialize, Deserialize)]
21pub struct RewardConfig {
22    pub terminal_win: f32,
23    pub terminal_loss: f32,
24    pub terminal_draw: f32,
25    pub enable_shaping: bool,
26    pub damage_reward: f32,
27}
28
29impl Default for RewardConfig {
30    fn default() -> Self {
31        Self {
32            terminal_win: 1.0,
33            terminal_loss: -1.0,
34            terminal_draw: 0.0,
35            enable_shaping: false,
36            damage_reward: 0.1,
37        }
38    }
39}
40
41#[derive(Clone, Debug, Serialize, Deserialize)]
42pub struct EnvConfig {
43    pub deck_lists: [Vec<CardId>; 2],
44    pub deck_ids: [u32; 2],
45    pub max_decisions: u32,
46    pub max_ticks: u32,
47    pub reward: RewardConfig,
48    #[serde(default)]
49    pub error_policy: ErrorPolicy,
50    #[serde(default)]
51    pub observation_visibility: ObservationVisibility,
52    #[serde(default)]
53    pub end_condition_policy: EndConditionPolicy,
54}
55
56impl EnvConfig {
57    pub fn config_hash(&self, curriculum: &CurriculumConfig) -> u64 {
58        crate::fingerprint::config_fingerprint(self, curriculum)
59    }
60}
61
62#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, Default)]
63pub enum SimultaneousLossPolicy {
64    ActivePlayerWins,
65    NonActivePlayerWins,
66    #[default]
67    Draw,
68}
69
70#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
71pub struct EndConditionPolicy {
72    #[serde(default)]
73    pub simultaneous_loss: SimultaneousLossPolicy,
74    #[serde(default)]
75    pub allow_draw_on_simultaneous_loss: bool,
76}
77
78impl Default for EndConditionPolicy {
79    fn default() -> Self {
80        Self {
81            simultaneous_loss: SimultaneousLossPolicy::Draw,
82            allow_draw_on_simultaneous_loss: true,
83        }
84    }
85}
86
87#[derive(Clone, Debug, Serialize, Deserialize)]
88pub struct CurriculumConfig {
89    #[serde(default)]
90    pub allowed_card_sets: Vec<String>,
91    #[serde(default = "default_true")]
92    pub allow_character: bool,
93    #[serde(default = "default_true")]
94    pub allow_event: bool,
95    #[serde(default = "default_true")]
96    pub allow_climax: bool,
97    #[serde(default = "default_true")]
98    pub enable_clock_phase: bool,
99    #[serde(default = "default_true")]
100    pub enable_climax_phase: bool,
101    #[serde(default = "default_true")]
102    pub enable_side_attacks: bool,
103    #[serde(default = "default_true")]
104    pub enable_direct_attacks: bool,
105    #[serde(default = "default_true")]
106    pub enable_counters: bool,
107    #[serde(default = "default_true")]
108    pub enable_triggers: bool,
109    #[serde(default = "default_true")]
110    pub enable_trigger_soul: bool,
111    #[serde(default = "default_true")]
112    pub enable_trigger_draw: bool,
113    #[serde(default = "default_true")]
114    pub enable_trigger_shot: bool,
115    #[serde(default = "default_true")]
116    pub enable_trigger_bounce: bool,
117    #[serde(default = "default_true")]
118    pub enable_trigger_treasure: bool,
119    #[serde(default = "default_true")]
120    pub enable_trigger_gate: bool,
121    #[serde(default = "default_true")]
122    pub enable_trigger_standby: bool,
123    #[serde(default = "default_true")]
124    pub enable_on_reverse_triggers: bool,
125    #[serde(default = "default_true")]
126    pub enable_backup: bool,
127    #[serde(default = "default_true")]
128    pub enable_encore: bool,
129    #[serde(default = "default_true")]
130    pub enable_refresh_penalty: bool,
131    #[serde(default = "default_true")]
132    pub enable_level_up_choice: bool,
133    #[serde(default = "default_true")]
134    pub enable_activated_abilities: bool,
135    #[serde(default = "default_true")]
136    pub enable_continuous_modifiers: bool,
137    #[serde(default)]
138    pub enable_priority_windows: bool,
139    #[serde(default)]
140    pub enable_visibility_policies: bool,
141    #[serde(default)]
142    pub use_alternate_end_conditions: bool,
143    #[serde(default = "default_true")]
144    pub priority_autopick_single_action: bool,
145    #[serde(default = "default_true")]
146    pub priority_allow_pass: bool,
147    #[serde(default)]
148    pub strict_priority_mode: bool,
149    #[serde(default)]
150    pub reduced_stage_mode: bool,
151    #[serde(default = "default_true")]
152    pub enforce_color_requirement: bool,
153    #[serde(default = "default_true")]
154    pub enforce_cost_requirement: bool,
155    #[serde(default)]
156    pub allow_concede: bool,
157    #[serde(default = "default_true")]
158    pub memory_is_public: bool,
159    #[serde(skip)]
160    pub allowed_card_sets_cache: Option<HashSet<String>>,
161}
162
163impl Default for CurriculumConfig {
164    fn default() -> Self {
165        Self {
166            allowed_card_sets: Vec::new(),
167            allow_character: true,
168            allow_event: true,
169            allow_climax: true,
170            enable_clock_phase: true,
171            enable_climax_phase: true,
172            enable_side_attacks: true,
173            enable_direct_attacks: true,
174            enable_counters: true,
175            enable_triggers: true,
176            enable_trigger_soul: true,
177            enable_trigger_draw: true,
178            enable_trigger_shot: true,
179            enable_trigger_bounce: true,
180            enable_trigger_treasure: true,
181            enable_trigger_gate: true,
182            enable_trigger_standby: true,
183            enable_on_reverse_triggers: true,
184            enable_backup: true,
185            enable_encore: true,
186            enable_refresh_penalty: true,
187            enable_level_up_choice: true,
188            enable_activated_abilities: true,
189            enable_continuous_modifiers: true,
190            enable_priority_windows: false,
191            enable_visibility_policies: false,
192            use_alternate_end_conditions: false,
193            priority_autopick_single_action: true,
194            priority_allow_pass: true,
195            strict_priority_mode: false,
196            reduced_stage_mode: false,
197            enforce_color_requirement: true,
198            enforce_cost_requirement: true,
199            allow_concede: false,
200            memory_is_public: true,
201            allowed_card_sets_cache: None,
202        }
203    }
204}
205
206impl CurriculumConfig {
207    pub fn rebuild_cache(&mut self) {
208        if self.allowed_card_sets.is_empty() {
209            self.allowed_card_sets_cache = None;
210        } else {
211            self.allowed_card_sets_cache = Some(self.allowed_card_sets.iter().cloned().collect());
212        }
213    }
214}
215
216fn default_true() -> bool {
217    true
218}