arknights/cost/
mod.rs

1mod stars;
2
3/// 计算干员升级所需的所有数据
4#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5pub struct LevelUpCostDB {
6    /// 精 0 每升一级需要消耗的资源
7    pub stage0: Vec<usize>,
8    /// 精 1 需要的资源
9    pub elite1: usize,
10    /// 精 1 每升一级需要消耗的资源
11    pub stage1: Vec<usize>,
12    /// 精 2 需要的资源
13    pub elite2: usize,
14    /// 精 2 每升一级需要消耗的资源
15    pub stage2: Vec<usize>,
16}
17
18/// 干员升级所需要的资源
19#[derive(Debug, Clone, PartialEq, Eq, Hash)]
20pub struct LevelUpCost {
21    /// 精 0 阶段升级需要消耗的资源
22    pub stage0: usize,
23    /// 精 1 阶段升级需要消耗的资源
24    pub stage1: usize,
25    /// 精 2 阶段升级需要消耗的资源
26    pub stage2: usize,
27    /// 精 1 消耗的资源
28    pub elite1: usize,
29    /// 精 2 消耗的资源
30    pub elite2: usize,
31}
32
33impl LevelUpCostDB {
34    /// 该干员是否能精1
35    pub fn can_elite1(&self) -> bool {
36        !self.stage1.is_empty()
37    }
38    /// 该干员是否能精2
39    pub fn can_elite2(&self) -> bool {
40        !self.stage2.is_empty()
41    }
42    /// 该干员各阶段的最大等级
43    pub fn max_level(&self) -> [usize; 3] {
44        [self.stage0.len(), self.stage1.len(), self.stage2.len()]
45    }
46    /// 需要花费的资源量
47    pub fn cost(&self, from: (usize, usize), to: (usize, usize)) -> Result<usize, String> {
48        self.cost_detail(from, to).map(|cost| cost.sum())
49    }
50    /// 列出每个阶段需要花费的资源量
51    ///
52    /// ## 带有容错机制
53    /// - 如果等级是 0, 视为 1 级
54    /// - 如果等级上限超出实际上限, 超出部分填 0, 不影响结果
55    pub fn cost_detail(&self, from: (usize, usize), to: (usize, usize)) -> Result<LevelUpCost, String> {
56        if to.0 < from.0 {
57            return Err(format!("目标精英化阶段 `{}` 比其实精英化阶段 `{}` 低", to.0, from.0));
58        }
59        if to.0 > 2 {
60            return Err(format!("目标精英化阶段 `{}` 非法", to.0));
61        }
62        if to.1 < from.1 {
63            return Err(format!("目标等级 `{}` 比起始等级 `{}` 低", to.1, from.1));
64        }
65        let mut cost = LevelUpCost {
66            stage0: 0,
67            stage1: 0,
68            stage2: 0,
69            //
70            elite1: self.elite1 as usize,
71            elite2: self.elite2 as usize,
72        };
73        let delta = to.1 - from.1;
74        let from_index = from.1.saturating_sub(1);
75        let till_index = to.1.saturating_sub(1);
76        match (from.0, to.0) {
77            (0, 0) => {
78                cost.stage0 += self.stage0.iter().skip(from_index).take(delta).cloned().sum::<usize>();
79            }
80            (0, 1) => {
81                cost.stage0 += self.stage0.iter().skip(from_index).cloned().sum::<usize>();
82                cost.stage1 += self.stage1.iter().take(till_index).cloned().sum::<usize>();
83            }
84            (0, 2) => {
85                cost.stage0 += self.stage0.iter().skip(from_index).cloned().sum::<usize>();
86                cost.stage1 += self.stage1.iter().cloned().sum::<usize>();
87                cost.stage2 += self.stage2.iter().take(till_index).cloned().sum::<usize>();
88            }
89            (1, 1) => {
90                cost.stage1 += self.stage1.iter().skip(from_index).take(delta).cloned().sum::<usize>();
91            }
92            (1, 2) => {
93                cost.stage1 += self.stage1.iter().skip(from_index).cloned().sum::<usize>();
94                cost.stage2 += self.stage2.iter().take(till_index).cloned().sum::<usize>();
95            }
96            (2, 2) => {
97                cost.stage2 += self.stage2.iter().skip(from_index).take(till_index).cloned().sum::<usize>();
98            }
99            _ => unreachable!(),
100        }
101        Ok(cost)
102    }
103}
104
105impl LevelUpCost {
106    /// 求出需要的资源总量
107    pub fn sum(&self) -> usize {
108        self.stage0 + self.stage1 + self.stage2 + self.elite1 + self.elite2
109    }
110}