use crate::sim::direction::Direction;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Handedness {
Left,
Right,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum CrabKind {
Common,
Juvenile,
Giant,
Molting,
Golden,
Sparkling,
}
impl CrabKind {
pub const ALL: [CrabKind; 6] = [
CrabKind::Common,
CrabKind::Juvenile,
CrabKind::Giant,
CrabKind::Molting,
CrabKind::Golden,
CrabKind::Sparkling,
];
pub fn token(self) -> &'static str {
match self {
CrabKind::Common => "common",
CrabKind::Juvenile => "juvenile",
CrabKind::Giant => "giant",
CrabKind::Molting => "molting",
CrabKind::Golden => "golden",
CrabKind::Sparkling => "sparkling",
}
}
pub fn from_token(token: &str) -> Option<CrabKind> {
Self::ALL.iter().copied().find(|k| k.token() == token)
}
pub fn speed(self) -> u16 {
match self {
CrabKind::Common | CrabKind::Molting | CrabKind::Sparkling => 12,
CrabKind::Juvenile => 18, CrabKind::Giant => 7, CrabKind::Golden => 15, }
}
pub fn value(self) -> u32 {
match self {
CrabKind::Common => 1,
CrabKind::Juvenile => 2,
CrabKind::Molting => 5,
CrabKind::Giant => 10,
CrabKind::Golden => 50,
CrabKind::Sparkling => 1, }
}
pub(crate) fn id(self) -> u8 {
match self {
CrabKind::Common => 0,
CrabKind::Juvenile => 1,
CrabKind::Giant => 2,
CrabKind::Molting => 3,
CrabKind::Golden => 4,
CrabKind::Sparkling => 5,
}
}
}
#[derive(Clone, Copy, Debug)]
pub struct Crab {
pub id: u32,
pub tile: u16,
pub dir: Direction,
pub progress: u16,
pub prev_tile: u16,
pub prev_progress: u16,
pub prev_dir: Direction,
pub handed: Handedness,
pub kind: CrabKind,
}
impl Handedness {
pub(crate) fn id(self) -> u8 {
match self {
Handedness::Left => 0,
Handedness::Right => 1,
}
}
pub fn token(self) -> &'static str {
match self {
Handedness::Left => "L",
Handedness::Right => "R",
}
}
pub fn from_token(token: &str) -> Option<Handedness> {
match token {
"L" => Some(Handedness::Left),
"R" => Some(Handedness::Right),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use super::{CrabKind, Handedness};
#[test]
fn tokens_round_trip_for_every_kind() {
for kind in CrabKind::ALL {
assert_eq!(CrabKind::from_token(kind.token()), Some(kind));
}
assert_eq!(CrabKind::from_token("hermit"), None);
for handed in [Handedness::Left, Handedness::Right] {
assert_eq!(Handedness::from_token(handed.token()), Some(handed));
}
}
#[test]
fn golden_crab_is_the_jackpot() {
assert_eq!(CrabKind::Golden.value(), 50);
assert!(CrabKind::Golden.speed() > CrabKind::Common.speed());
assert!(CrabKind::Golden.speed() < CrabKind::Juvenile.speed());
}
}