#[cfg(feature = "seasonal-season-1")]
pub mod season_1 {
pub const WALLS_RADIUS: u8 = 5;
pub const SCORE_CONTAINER_SPAWN_CHANCE: f32 = 0.01;
pub const SCORE_CONTAINER_SPAWN_INTERVAL_TICKS: u32 = 250;
pub const SCORE_COLLECTOR_SINK: u32 = 20;
pub const SCORE_COLLECTOR_MAX_CAPACITY: u32 = 20_000;
pub const SCORE_CYCLE_DURATION: u32 = 50_000;
pub const SCORE_CYCLE_BONUS_START: u32 = 45_000;
pub const SCORE_CYCLE_BONUS_END: u32 = 50_000;
pub const SCORE_CYCLE_BONUS_MULTIPLIER: u8 = 2;
pub const SCORE_CYCLE_CRISIS_START: u32 = 10_000;
pub const SCORE_CYCLE_CRISIS_END: u32 = 15_000;
pub const SCORE_CYCLE_CRISIS_MULTIPLIER: u8 = 0;
pub const SCORE_MIN_DECAY: u16 = 500;
pub const SCORE_MAX_DECAY: u16 = 5_000;
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ScoreCycleState {
Normal,
Crisis,
Bonus,
}
impl ScoreCycleState {
pub fn multiplier(&self) -> u8 {
match self {
ScoreCycleState::Normal => 1,
ScoreCycleState::Crisis => SCORE_CYCLE_CRISIS_MULTIPLIER,
ScoreCycleState::Bonus => SCORE_CYCLE_BONUS_MULTIPLIER,
}
}
}
pub const fn score_cycle_at_tick(tick: u32) -> ScoreCycleState {
#[allow(clippy::match_overlapping_arm)]
match tick % SCORE_CYCLE_DURATION {
SCORE_CYCLE_CRISIS_START => ScoreCycleState::Normal,
SCORE_CYCLE_BONUS_START => ScoreCycleState::Normal,
SCORE_CYCLE_CRISIS_START..SCORE_CYCLE_CRISIS_END => ScoreCycleState::Crisis,
SCORE_CYCLE_BONUS_START..SCORE_CYCLE_BONUS_END => ScoreCycleState::Bonus,
_ => ScoreCycleState::Normal,
}
}
pub const fn s7_score_cycle_at_tick(tick: u32) -> ScoreCycleState {
#[allow(clippy::match_overlapping_arm)]
match tick % SCORE_CYCLE_DURATION {
SCORE_CYCLE_CRISIS_START => ScoreCycleState::Normal,
SCORE_CYCLE_BONUS_START => ScoreCycleState::Normal,
SCORE_CYCLE_CRISIS_START..SCORE_CYCLE_CRISIS_END => ScoreCycleState::Bonus,
SCORE_CYCLE_BONUS_START..SCORE_CYCLE_BONUS_END => ScoreCycleState::Crisis,
_ => ScoreCycleState::Normal,
}
}
#[cfg(test)]
mod test {
use super::{s7_score_cycle_at_tick, score_cycle_at_tick, ScoreCycleState};
#[test]
fn s1_score_cycle() {
assert_eq!(score_cycle_at_tick(0), ScoreCycleState::Normal);
assert_eq!(score_cycle_at_tick(10_000), ScoreCycleState::Normal);
assert_eq!(score_cycle_at_tick(10_001), ScoreCycleState::Crisis);
assert_eq!(score_cycle_at_tick(14_999), ScoreCycleState::Crisis);
assert_eq!(score_cycle_at_tick(15_000), ScoreCycleState::Normal);
assert_eq!(score_cycle_at_tick(45_000), ScoreCycleState::Normal);
assert_eq!(score_cycle_at_tick(45_001), ScoreCycleState::Bonus);
assert_eq!(score_cycle_at_tick(49_999), ScoreCycleState::Bonus);
assert_eq!(score_cycle_at_tick(50_000), ScoreCycleState::Normal);
assert_eq!(score_cycle_at_tick(200_000), ScoreCycleState::Normal);
assert_eq!(score_cycle_at_tick(210_000), ScoreCycleState::Normal);
assert_eq!(score_cycle_at_tick(210_001), ScoreCycleState::Crisis);
assert_eq!(score_cycle_at_tick(214_999), ScoreCycleState::Crisis);
assert_eq!(score_cycle_at_tick(215_000), ScoreCycleState::Normal);
assert_eq!(score_cycle_at_tick(245_000), ScoreCycleState::Normal);
assert_eq!(score_cycle_at_tick(245_001), ScoreCycleState::Bonus);
assert_eq!(score_cycle_at_tick(249_999), ScoreCycleState::Bonus);
assert_eq!(score_cycle_at_tick(250_000), ScoreCycleState::Normal);
}
#[test]
fn s7_score_cycle() {
assert_eq!(s7_score_cycle_at_tick(0), ScoreCycleState::Normal);
assert_eq!(s7_score_cycle_at_tick(10_000), ScoreCycleState::Normal);
assert_eq!(s7_score_cycle_at_tick(10_001), ScoreCycleState::Bonus);
assert_eq!(s7_score_cycle_at_tick(14_999), ScoreCycleState::Bonus);
assert_eq!(s7_score_cycle_at_tick(15_000), ScoreCycleState::Normal);
assert_eq!(s7_score_cycle_at_tick(45_000), ScoreCycleState::Normal);
assert_eq!(s7_score_cycle_at_tick(45_001), ScoreCycleState::Crisis);
assert_eq!(s7_score_cycle_at_tick(49_999), ScoreCycleState::Crisis);
assert_eq!(s7_score_cycle_at_tick(50_000), ScoreCycleState::Normal);
assert_eq!(s7_score_cycle_at_tick(200_000), ScoreCycleState::Normal);
assert_eq!(s7_score_cycle_at_tick(210_000), ScoreCycleState::Normal);
assert_eq!(s7_score_cycle_at_tick(210_001), ScoreCycleState::Bonus);
assert_eq!(s7_score_cycle_at_tick(214_999), ScoreCycleState::Bonus);
assert_eq!(s7_score_cycle_at_tick(215_000), ScoreCycleState::Normal);
assert_eq!(s7_score_cycle_at_tick(245_000), ScoreCycleState::Normal);
assert_eq!(s7_score_cycle_at_tick(245_001), ScoreCycleState::Crisis);
assert_eq!(s7_score_cycle_at_tick(249_999), ScoreCycleState::Crisis);
assert_eq!(s7_score_cycle_at_tick(250_000), ScoreCycleState::Normal);
}
}
}
#[cfg(feature = "seasonal-season-2")]
pub mod season_2 {
use crate::constants::ResourceType;
pub const SYMBOLS: [ResourceType; 22] = [
ResourceType::SymbolAleph,
ResourceType::SymbolBeth,
ResourceType::SymbolGimmel,
ResourceType::SymbolDaleth,
ResourceType::SymbolHe,
ResourceType::SymbolWaw,
ResourceType::SymbolZayin,
ResourceType::SymbolHeth,
ResourceType::SymbolTeth,
ResourceType::SymbolYodh,
ResourceType::SymbolKaph,
ResourceType::SymbolLamedh,
ResourceType::SymbolMem,
ResourceType::SymbolNun,
ResourceType::SymbolSamekh,
ResourceType::SymbolAyin,
ResourceType::SymbolPe,
ResourceType::SymbolTsade,
ResourceType::SymbolQoph,
ResourceType::SymbolRes,
ResourceType::SymbolSin,
ResourceType::SymbolTaw,
];
pub const SYMBOL_CONTAINER_SPAWN_CHANCE: f32 = 0.01;
pub const SYMBOL_CONTAINER_SPAWN_INTERVAL_TICKS: u32 = 250;
#[inline]
pub const fn controller_level_score_multiplers(rcl: u32) -> u32 {
match rcl {
4 => 3,
5 => 9,
6 => 27,
7 => 81,
8 => 243,
_ => 1,
}
}
}
#[cfg(feature = "seasonal-season-5")]
pub mod season_5 {
use crate::constants::Density;
pub const REACTOR_THORIUM_CAPACITY: u32 = 1_000;
impl Density {
#[inline]
pub const fn thorium_amount(self) -> u32 {
match self {
Density::Low => 10_000,
Density::Moderate => 22_000,
Density::High => 45_000,
Density::Ultra => 67_000,
}
}
}
pub fn thorium_decay(thorium_amount: u32) -> u32 {
(thorium_amount as f64).log10().floor() as u32
}
pub fn reactor_points_per_tick(continuous_work_ticks: u32) -> u32 {
1 + (continuous_work_ticks as f64).log10().floor() as u32
}
#[cfg(test)]
mod test {
use super::{reactor_points_per_tick, thorium_decay};
#[test]
fn decay_formula() {
assert_eq!(thorium_decay(0), 0);
assert_eq!(thorium_decay(1), 0);
assert_eq!(thorium_decay(9), 0);
assert_eq!(thorium_decay(10), 1);
assert_eq!(thorium_decay(99), 1);
assert_eq!(thorium_decay(100), 2);
assert_eq!(thorium_decay(999), 2);
assert_eq!(thorium_decay(1000), 3);
assert_eq!(thorium_decay(10_000), 4);
}
#[test]
fn score_formula() {
assert_eq!(reactor_points_per_tick(0), 1);
assert_eq!(reactor_points_per_tick(1), 1);
assert_eq!(reactor_points_per_tick(9), 1);
assert_eq!(reactor_points_per_tick(10), 2);
assert_eq!(reactor_points_per_tick(99), 2);
assert_eq!(reactor_points_per_tick(100), 3);
assert_eq!(reactor_points_per_tick(999), 3);
assert_eq!(reactor_points_per_tick(1000), 4);
assert_eq!(reactor_points_per_tick(10_000), 5);
assert_eq!(reactor_points_per_tick(100_000), 6);
}
}
}
#[cfg(feature = "seasonal-season-10")]
pub mod season_10 {
pub const SCORE_SPAWN_CHANCE: f32 = 0.01;
pub const SCORE_SPAWN_INTERVAL_TICKS: u32 = 250;
}