Something went wrong. Try again.
HEXWORK - A Lantern in the Deep: 3D ASCII terminal roguelike RPG in Rust.
Entirely designed and built by Muse Spark 1.3 to evaluate if I like the model.
Something went wrong. Try again.
3.4 kB · 106 lines
Rust
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107//! Canonical vocabulary for actions that have crossed the input boundary.
use crate::services::Service;
/// Eight explicit movement directions; invalid deltas cannot enter a journal.#[derive(Clone, Debug, PartialEq, Eq)]pub enum Direction { North, South, West, East, NorthWest, NorthEast, SouthWest, SouthEast,}
impl Direction { /// Horizontal voxel delta for this direction, in the heading convention /// (north is -Y, matching `Heading` bin 0; east is +X; south is +Y). #[must_use] pub const fn delta(&self) -> (i32, i32) { match self { Self::North => (0, -1), Self::South => (0, 1), Self::West => (-1, 0), Self::East => (1, 0), Self::NorthWest => (-1, -1), Self::NorthEast => (1, -1), Self::SouthWest => (-1, 1), Self::SouthEast => (1, 1), } }
/// Stable canonical tag for wire and canonical-hash encoding. Zero is /// reserved for "no direction"; the save wire table delegates here so the /// journal and the pending-action hash cannot drift. #[must_use] pub const fn canonical_tag(&self) -> u8 { match self { Self::North => 1, Self::South => 2, Self::West => 3, Self::East => 4, Self::NorthWest => 5, Self::NorthEast => 6, Self::SouthWest => 7, Self::SouthEast => 8, } }}
/// Typed committed actions. Strings are canonical content/town identifiers,/// never terminal command text.#[derive(Clone, Debug, PartialEq, Eq)]pub enum CommittedAction { Move(Direction), Wait, InspectBoard { town: String }, AcceptContract { id: String }, UseTransition { transition_id: u64 }, ResolveAttack { target_actor: u64 }, Pickup { item_id: u64 }, Drop { item_id: u64 }, Wield { item_id: u64 }, TinkerIdentify { item_id: u64 }, TurnIn { contract_id: String }, UseService { service: Service },}
#[cfg(test)]mod tests { use super::*;
#[test] fn all_direction_deltas_are_explicit() { assert_eq!(Direction::North.delta(), (0, -1)); assert_eq!(Direction::South.delta(), (0, 1)); assert_eq!(Direction::West.delta(), (-1, 0)); assert_eq!(Direction::East.delta(), (1, 0)); assert_eq!(Direction::NorthWest.delta(), (-1, -1)); assert_eq!(Direction::NorthEast.delta(), (1, -1)); assert_eq!(Direction::SouthWest.delta(), (-1, 1)); assert_eq!(Direction::SouthEast.delta(), (1, 1)); }
/// Cardinal deltas must agree with the canonical `Heading` unit vectors so /// the action journal and the locomotion authority cannot drift apart. #[test] fn cardinal_deltas_match_heading_convention() { for (direction, heading) in [ (Direction::North, crate::heading::Heading::NORTH), (Direction::East, crate::heading::Heading::EAST), (Direction::South, crate::heading::Heading::SOUTH), (Direction::West, crate::heading::Heading::WEST), ] { let [x, y] = heading.unit_vector(); let (dx, dy) = direction.delta(); assert_eq!( (i64::from(dx), i64::from(dy)), (x.signum(), y.signum()), "{direction:?} must match its heading unit vector" ); } }}