pinch_points/sim/gull.rs
1use crate::sim::crab::Handedness;
2use crate::sim::direction::Direction;
3use crate::sim::pose::Pose;
4
5/// Gull behaviour state (spec §3.5). Walking is the default and the whole
6/// offensive layer: a walking gull is steerable with signposts. Flight is a
7/// brief, occasional hop that exists so no corner can be permanently safe.
8#[derive(Clone, Copy, PartialEq, Eq, Debug)]
9pub enum GullState {
10 Walking,
11 /// Hopping `remaining` more tiles in the current direction, ignoring
12 /// walls and signposts, eating nothing.
13 Flying {
14 remaining: u8,
15 },
16}
17
18/// One gull. Moves on the grid exactly like a crab while walking (walls,
19/// signposts, handedness), slower than a common crab.
20#[derive(Clone, Copy, Debug)]
21pub struct Gull {
22 /// Stable identity for the render layer; unique within a match.
23 pub id: u32,
24 pub tile: u16,
25 pub dir: Direction,
26 pub progress: u16,
27 /// Last tick's position, for the render layer's interpolation only.
28 pub prev: Pose,
29 pub handed: Handedness,
30 pub state: GullState,
31 /// Ticks of walking left until the next takeoff.
32 pub takeoff_in: u32,
33}
34
35impl Gull {
36 /// The current position as one value, so a tick can save it into
37 /// `prev` in a single assignment.
38 pub fn pose(&self) -> Pose {
39 Pose {
40 tile: self.tile,
41 dir: self.dir,
42 progress: self.progress,
43 }
44 }
45}
46
47/// Walking speed in subunits per tick (spec §4.2: slower than a common crab).
48pub const GULL_WALK_SPEED: u16 = 8;
49/// Flying speed in subunits per tick.
50pub const GULL_FLY_SPEED: u16 = 16;
51/// Gull-eats-crab range: Manhattan distance between sub-tile offsets on the
52/// same tile, in subunits (spec §4.3 suggests 48).
53pub const EAT_RANGE: u16 = 48;
54/// Takeoff timer range in ticks (5–12 s at 30 Hz): keeps gulls walking, and
55/// therefore steerable, roughly 85% of the time (spec §3.5).
56pub const TAKEOFF_MIN: u32 = 150;
57pub const TAKEOFF_MAX: u32 = 360;
58/// Flight length range in tiles (spec §3.5: 2–4).
59pub const FLIGHT_MIN: u8 = 2;
60pub const FLIGHT_MAX: u8 = 4;