Skip to main content

nil_core/ranking/
score.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4use crate::military::army::Army;
5use crate::military::army::personnel::ArmyPersonnel;
6use crate::military::squad::Squad;
7use nil_num::impl_mul_ceil;
8use nil_util::{ConstDeref, F64Math};
9use serde::{Deserialize, Serialize};
10use std::cmp::Ordering;
11use std::iter::Sum;
12use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};
13
14#[derive(Copy, Debug, Deserialize, Serialize, ConstDeref, F64Math)]
15#[derive_const(Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
16#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
17pub struct Score(u32);
18
19impl Score {
20  pub const ZERO: Score = Score(0);
21
22  #[inline]
23  pub const fn new(value: u32) -> Self {
24    Self(value)
25  }
26}
27
28impl const From<u32> for Score {
29  fn from(value: u32) -> Self {
30    Self::new(value)
31  }
32}
33
34impl const From<Score> for u32 {
35  fn from(value: Score) -> Self {
36    value.0
37  }
38}
39
40impl const From<f64> for Score {
41  fn from(value: f64) -> Self {
42    Self::new(value as u32)
43  }
44}
45
46impl const From<Score> for f64 {
47  fn from(value: Score) -> Self {
48    f64::from(value.0)
49  }
50}
51
52impl const PartialEq<u32> for Score {
53  fn eq(&self, other: &u32) -> bool {
54    self.0.eq(other)
55  }
56}
57
58impl const PartialOrd<u32> for Score {
59  fn partial_cmp(&self, other: &u32) -> Option<Ordering> {
60    self.0.partial_cmp(other)
61  }
62}
63
64impl<'a> Sum<&'a Squad> for Score {
65  fn sum<I>(iter: I) -> Self
66  where
67    I: Iterator<Item = &'a Squad>,
68  {
69    iter.fold(Score::default(), |mut acc, squad| {
70      acc += squad.score();
71      acc
72    })
73  }
74}
75
76impl<'a> Sum<&'a ArmyPersonnel> for Score {
77  fn sum<I>(iter: I) -> Self
78  where
79    I: Iterator<Item = &'a ArmyPersonnel>,
80  {
81    iter.flat_map(ArmyPersonnel::iter).sum()
82  }
83}
84
85impl<'a> Sum<&'a Army> for Score {
86  fn sum<I>(iter: I) -> Self
87  where
88    I: Iterator<Item = &'a Army>,
89  {
90    iter.flat_map(Army::iter).sum()
91  }
92}
93
94impl const Add for Score {
95  type Output = Score;
96
97  fn add(self, rhs: Self) -> Self::Output {
98    Self(self.0.saturating_add(rhs.0))
99  }
100}
101
102impl const AddAssign for Score {
103  fn add_assign(&mut self, rhs: Self) {
104    *self = *self + rhs;
105  }
106}
107
108impl const Add<u32> for Score {
109  type Output = Score;
110
111  fn add(self, rhs: u32) -> Self::Output {
112    Self(self.0.saturating_add(rhs))
113  }
114}
115
116impl const AddAssign<u32> for Score {
117  fn add_assign(&mut self, rhs: u32) {
118    *self = *self + rhs;
119  }
120}
121
122impl const Sub for Score {
123  type Output = Score;
124
125  fn sub(self, rhs: Self) -> Self::Output {
126    Self(self.0.saturating_sub(rhs.0))
127  }
128}
129
130impl const SubAssign for Score {
131  fn sub_assign(&mut self, rhs: Self) {
132    *self = *self - rhs;
133  }
134}
135
136impl const Mul for Score {
137  type Output = Score;
138
139  fn mul(self, rhs: Score) -> Self::Output {
140    Self(self.0.saturating_mul(rhs.0))
141  }
142}
143
144impl const Mul<u32> for Score {
145  type Output = Score;
146
147  fn mul(self, rhs: u32) -> Self::Output {
148    Self(self.0.saturating_mul(rhs))
149  }
150}
151
152impl const MulAssign for Score {
153  fn mul_assign(&mut self, rhs: Self) {
154    *self = *self * rhs;
155  }
156}
157
158impl_mul_ceil!(Score);