Skip to main content

nil_core/behavior/
score.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4use derive_more::Into;
5use std::cmp::Ordering;
6use std::fmt::Debug;
7use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
8
9#[derive(Copy, Debug, Into)]
10#[derive_const(Clone)]
11pub struct BehaviorScore(f64);
12
13impl BehaviorScore {
14  pub const MIN: Self = BehaviorScore(0.0);
15  pub const MAX: Self = BehaviorScore(1.0);
16
17  #[inline]
18  pub const fn new(score: f64) -> Self {
19    debug_assert!(score.is_finite());
20    debug_assert!(!score.is_subnormal());
21    Self(score.clamp(Self::MIN.0, Self::MAX.0))
22  }
23
24  #[inline]
25  pub const fn is_within_range(self, other: BehaviorScore, range: f64) -> bool {
26    (self.0 - other.0).abs() < range
27  }
28}
29
30impl const Default for BehaviorScore {
31  fn default() -> Self {
32    Self::MIN
33  }
34}
35
36impl const From<f64> for BehaviorScore {
37  fn from(score: f64) -> Self {
38    Self::new(score)
39  }
40}
41
42impl const PartialEq for BehaviorScore {
43  fn eq(&self, other: &Self) -> bool {
44    matches!(self.0.total_cmp(&other.0), Ordering::Equal)
45  }
46}
47
48impl const Eq for BehaviorScore {}
49
50impl const PartialOrd for BehaviorScore {
51  fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
52    Some(self.cmp(other))
53  }
54}
55
56impl const Ord for BehaviorScore {
57  fn cmp(&self, other: &Self) -> Ordering {
58    self.0.total_cmp(&other.0)
59  }
60}
61
62impl const PartialEq<f64> for BehaviorScore {
63  fn eq(&self, other: &f64) -> bool {
64    self.0.eq(other)
65  }
66}
67
68impl const PartialOrd<f64> for BehaviorScore {
69  fn partial_cmp(&self, other: &f64) -> Option<Ordering> {
70    self.0.partial_cmp(other)
71  }
72}
73
74impl const Add<f64> for BehaviorScore {
75  type Output = BehaviorScore;
76
77  fn add(self, rhs: f64) -> Self::Output {
78    BehaviorScore::new(self.0 + rhs)
79  }
80}
81
82impl const AddAssign<f64> for BehaviorScore {
83  fn add_assign(&mut self, rhs: f64) {
84    *self = *self + rhs;
85  }
86}
87
88impl const Sub<f64> for BehaviorScore {
89  type Output = BehaviorScore;
90
91  fn sub(self, rhs: f64) -> Self::Output {
92    BehaviorScore::new(self.0 - rhs)
93  }
94}
95
96impl const SubAssign<f64> for BehaviorScore {
97  fn sub_assign(&mut self, rhs: f64) {
98    *self = *self - rhs;
99  }
100}
101
102impl const Mul<f64> for BehaviorScore {
103  type Output = BehaviorScore;
104
105  fn mul(self, rhs: f64) -> Self::Output {
106    BehaviorScore::new(self.0 * rhs)
107  }
108}
109
110impl const MulAssign<f64> for BehaviorScore {
111  fn mul_assign(&mut self, rhs: f64) {
112    *self = *self * rhs;
113  }
114}
115
116impl const Div<f64> for BehaviorScore {
117  type Output = BehaviorScore;
118
119  fn div(self, rhs: f64) -> Self::Output {
120    BehaviorScore::new(self.0 / rhs)
121  }
122}
123
124impl const DivAssign<f64> for BehaviorScore {
125  fn div_assign(&mut self, rhs: f64) {
126    *self = *self / rhs;
127  }
128}