use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CarRacingConfig {
pub track_n_checkpoints: usize,
pub track_turn_rate: f32,
pub track_width: f32,
pub lap_complete_percent: f32,
pub tile_reward: f32,
pub frame_penalty: f32,
pub car_density: f32,
pub friction: f32,
pub seed: u64,
pub max_steps: usize,
pub dt: f32,
pub gravity: f32,
}
impl Default for CarRacingConfig {
fn default() -> Self {
Self {
track_n_checkpoints: 12,
track_turn_rate: 0.31,
track_width: 40.0,
lap_complete_percent: 0.95,
tile_reward: 1000.0 / 200.0, frame_penalty: -0.1,
car_density: 0.001,
friction: 1.0,
seed: 0,
max_steps: 1000,
dt: 1.0 / 50.0,
gravity: 0.0, }
}
}
impl CarRacingConfig {
pub fn builder() -> CarRacingConfigBuilder {
CarRacingConfigBuilder { inner: CarRacingConfig::default() }
}
}
#[derive(Debug, Clone)]
pub struct CarRacingConfigBuilder {
inner: CarRacingConfig,
}
impl CarRacingConfigBuilder {
pub fn seed(mut self, seed: u64) -> Self {
self.inner.seed = seed;
self
}
pub fn track_n_checkpoints(mut self, n: usize) -> Self {
self.inner.track_n_checkpoints = n;
self
}
pub fn max_steps(mut self, n: usize) -> Self {
self.inner.max_steps = n;
self
}
pub fn build(self) -> CarRacingConfig {
self.inner
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default() {
let cfg = CarRacingConfig::default();
assert!(cfg.tile_reward > 0.0);
assert!(cfg.frame_penalty < 0.0);
assert_eq!(cfg.track_n_checkpoints, 12);
}
}