screeps_utils/math/
gcl.rs

1use screeps::constants::*;
2
3/// Provides the total number of control points needed to achieve a given Global
4/// Control Level
5///
6/// Calculates the total number of control points needed to achieve a given
7/// Global Control Level. The game's API only exposes current level plus
8/// progress toward the next level; this allows you to see how many points
9/// you've spent to achieve your current level
10///
11/// [Code reference](https://github.com/screeps/engine/blob/6d498f2f0db4e0744fa6bf8563836d36b49b6a29/src/game/game.js#L117)
12pub fn control_points_for_gcl(level: u32) -> f64 {
13    ((level - 1) as f64).powf(GCL_POW) * GCL_MULTIPLY as f64
14}
15
16#[cfg(test)]
17mod test {
18    use assert_approx_eq::assert_approx_eq;
19
20    use super::control_points_for_gcl;
21
22    #[test]
23    fn gcl_formula() {
24        // the sanity of these values has been validated up to GCL 33
25        // on the MMO game server
26        assert_approx_eq!(control_points_for_gcl(1), 0.);
27        assert_approx_eq!(control_points_for_gcl(2), 1000000.);
28        assert_approx_eq!(control_points_for_gcl(3), 5278031.643091577);
29        assert_approx_eq!(control_points_for_gcl(4), 13966610.165238237);
30        assert_approx_eq!(control_points_for_gcl(5), 27857618.025475968);
31        assert_approx_eq!(control_points_for_gcl(6), 47591348.46789695);
32        assert_approx_eq!(control_points_for_gcl(7), 73716210.39885189);
33        assert_approx_eq!(control_points_for_gcl(8), 106717414.7996562);
34        assert_approx_eq!(control_points_for_gcl(9), 147033389.43962047);
35        assert_approx_eq!(control_points_for_gcl(10), 195066199.50773603);
36        assert_approx_eq!(control_points_for_gcl(11), 251188643.15095797);
37        assert_approx_eq!(control_points_for_gcl(12), 315749334.8687436);
38        assert_approx_eq!(control_points_for_gcl(13), 389076491.09393656);
39        assert_approx_eq!(control_points_for_gcl(14), 471480836.66525537);
40        assert_approx_eq!(control_points_for_gcl(15), 563257892.1815147);
41        assert_approx_eq!(control_points_for_gcl(16), 664689811.2891247);
42        assert_approx_eq!(control_points_for_gcl(17), 776046882.0533236);
43        assert_approx_eq!(control_points_for_gcl(18), 897588771.9617443);
44        assert_approx_eq!(control_points_for_gcl(19), 1029565573.4994452);
45        assert_approx_eq!(control_points_for_gcl(20), 1172218691.9999762);
46        assert_approx_eq!(control_points_for_gcl(25), 2053558031.5768352);
47        assert_approx_eq!(control_points_for_gcl(30), 3234113036.1951885);
48        assert_approx_eq!(control_points_for_gcl(31), 3508253856.824569);
49        assert_approx_eq!(control_points_for_gcl(32), 3795491867.4194345);
50        assert_approx_eq!(control_points_for_gcl(33), 4095999999.9999986);
51        assert_approx_eq!(control_points_for_gcl(34), 4409947870.045006);
52        assert_approx_eq!(control_points_for_gcl(35), 4737501940.897796);
53        assert_approx_eq!(control_points_for_gcl(40), 6584989046.083984);
54        assert_approx_eq!(control_points_for_gcl(45), 8796024362.57156);
55        assert_approx_eq!(control_points_for_gcl(50), 11388606621.52188);
56        assert_approx_eq!(control_points_for_gcl(100), 61592022749.941284);
57        assert_approx_eq!(control_points_for_gcl(1000), 15810921110646.998);
58        assert_approx_eq!(control_points_for_gcl(u32::MAX), 1.3155388150906982e29);
59    }
60
61    #[test]
62    #[should_panic]
63    fn bad_gcl_formula_input() {
64        // players cannot be GCL 0, and subtracting 1 (as the formula does)
65        // overflows the u32 - this should panic.
66        control_points_for_gcl(0);
67    }
68}