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