pub struct Board { /* private fields */ }Expand description
The entire game state. No engine types, no floats, no hash maps: every tick is a pure function of prior state plus one action per seat, so the same seed and input list replays bit-identically on any platform.
Implementations§
Source§impl Board
impl Board
Sourcepub fn spawn_crab(
&mut self,
x: u8,
y: u8,
dir: Direction,
handed: Handedness,
kind: CrabKind,
)
pub fn spawn_crab( &mut self, x: u8, y: u8, dir: Direction, handed: Handedness, kind: CrabKind, )
Place a crab directly (puzzle setups and tests; spawner tiles handle the normal case). The crab immediately wall-resolves so it never starts a tick facing a wall.
Source§impl Board
impl Board
Sourcepub fn force_lure(&mut self, owner: PlayerId)
pub fn force_lure(&mut self, owner: PlayerId)
Apply one tide event’s effects (split from the roulette so each event
is unit-testable in isolation).
Start a lure for owner, as banking a molting crab does.
Same reason as Self::force_tide_event: the dev hook and the
tests need one on demand, and waiting for a molt to turn up and be
banked is not a thing a screenshot can do.
Sourcepub fn force_tide_event(&mut self, event: TideEvent, banker: PlayerId)
pub fn force_tide_event(&mut self, event: TideEvent, banker: PlayerId)
Fire a named tide event outright. The roulette is the only caller in play; this exists for the dev hook that has to show one on demand, and for the tests, which cannot wait for a sparkling crab.
Source§impl Board
impl Board
Sourcepub fn step(&self, tile: u16, dir: Direction) -> Option<u16>
pub fn step(&self, tile: u16, dir: Direction) -> Option<u16>
The tile one step away in dir, if there is one: across the seam on
a wrapping arena, None off the edge otherwise. The public face of
Board::neighbor for callers outside the board: the bot plans on
the same beach the crabs walk, seam included.
Source§impl Board
impl Board
Sourcepub fn spawn_gull(&mut self, x: u8, y: u8, dir: Direction)
pub fn spawn_gull(&mut self, x: u8, y: u8, dir: Direction)
Drop a gull onto the board, walking. Used by level setup and the periodic edge spawner.
Source§impl Board
impl Board
Sourcepub fn state_hash(&self) -> u64
pub fn state_hash(&self) -> u64
Fingerprint of the complete simulation state, in a fixed field order. Two boards fed the same seed and inputs must agree on this after every tick, on every platform: the determinism contract of spec §7.5.
Source§impl Board
impl Board
Sourcepub fn can_place_signpost(&self, player: PlayerId, x: u8, y: u8) -> bool
pub fn can_place_signpost(&self, player: PlayerId, x: u8, y: u8) -> bool
Spec §3.3: signposts go on empty sand only, not on castles, rocks,
spawners, or a tile that already has one. At the cap, the outcome
depends on the board’s CapPolicy: evict the player’s oldest (versus)
or reject the placement (puzzle inventory).
Whether a placement at (x, y) would succeed, without mutating.
Mirrors Board::place_signpost exactly; the UI uses it for instant
denied feedback on a queued (not yet applied) action.
pub fn place_signpost( &mut self, player: PlayerId, x: u8, y: u8, dir: Direction, ) -> bool
Sourcepub fn signpost_fade(&self, sp: &Signpost) -> f32
pub fn signpost_fade(&self, sp: &Signpost) -> f32
Remaining life of a signpost as a 0..=1 fraction (always 1 under puzzle rules, where posts are permanent).
Sourcepub fn newest_signpost_of(&self, player: PlayerId) -> Option<(u8, u8, u64)>
pub fn newest_signpost_of(&self, player: PlayerId) -> Option<(u8, u8, u64)>
Where a player’s most recent signpost stands and when they placed it:
(x, y, tick).
This is the anchor for a bot’s cursor (see crate::sim::bot_action):
the last tile it reached, so the walk to the next one can be charged
for. Reading it from the board keeps the bot a pure function of the
state, so every peer of an online match derives the same move for an
AI seat.
Sourcepub fn signpost_count(&self, player: PlayerId) -> usize
pub fn signpost_count(&self, player: PlayerId) -> usize
How many signposts player currently has on the board.
Sourcepub fn remove_signpost(&mut self, player: PlayerId, x: u8, y: u8) -> bool
pub fn remove_signpost(&mut self, player: PlayerId, x: u8, y: u8) -> bool
Players may only remove their own signposts.
pub fn signpost_at(&self, x: u8, y: u8) -> Option<Signpost>
Sourcepub fn signpost_rule(&self) -> (u8, CapPolicy)
pub fn signpost_rule(&self) -> (u8, CapPolicy)
The current signpost cap rule, for serialization.
Source§impl Board
impl Board
Sourcepub fn new(width: u8, height: u8, seed: u64) -> Board
pub fn new(width: u8, height: u8, seed: u64) -> Board
An empty all-sand board with walled borders (spec §3.1; wrap-around edges are a later, flag-gated variant).
Sourcepub fn set_wall(&mut self, x: u8, y: u8, dir: Direction, present: bool)
pub fn set_wall(&mut self, x: u8, y: u8, dir: Direction, present: bool)
Add or remove the wall on the dir side of tile (x, y). Walls are
stored per-edge, so the neighbouring tile sees the same wall and the
two tiles cannot disagree (spec §7.3).
pub fn set_tile(&mut self, x: u8, y: u8, kind: TileKind)
Sourcepub fn set_signpost_rule(&mut self, cap: u8, policy: CapPolicy)
pub fn set_signpost_rule(&mut self, cap: u8, policy: CapPolicy)
Change the signpost cap and what happens at it. Versus keeps the default (3, evict-oldest); puzzle mode sets (inventory, reject).
Sourcepub fn set_gull_period(&mut self, period: u32)
pub fn set_gull_period(&mut self, period: u32)
Auto-spawn a gull every period ticks (0 disables). Doubled during
the final-scramble surge of a timed round.
pub fn set_round_length(&mut self, ticks: Option<u32>)
Sourcepub fn set_wrap(&mut self, wrap: bool)
pub fn set_wrap(&mut self, wrap: bool)
Open (or close) the board edges. Opening removes the border walls so creatures walk and fly off one side and re-enter on the opposite one.
pub fn wrap(&self) -> bool
Sourcepub fn events_enabled(&self) -> bool
pub fn events_enabled(&self) -> bool
Enable tide events (the sparkling crab’s roulette). Off by default: puzzles and goal-checked challenges stay predictable.
pub fn set_events_enabled(&mut self, enabled: bool)
Sourcepub fn last_event(&self) -> Option<(TideEvent, u64)>
pub fn last_event(&self) -> Option<(TideEvent, u64)>
The most recent tide event and when it fired.
pub fn golden_banked(&self) -> u32
Sourcepub fn set_score(&mut self, player: PlayerId, score: u32)
pub fn set_score(&mut self, player: PlayerId, score: u32)
Preload a score (editor, sandboxes, tests). Not used by live play: scores otherwise change only through banking and gull raids. A seat that does not exist takes no score: the callers that parse untrusted text already refuse it with a message, and this is the backstop.
Sourcepub fn tick(&mut self, actions: &[PlayerAction; 6])
pub fn tick(&mut self, actions: &[PlayerAction; 6])
Advance one fixed 30 Hz step. Order within a tick is fixed and part of
the ruleset: player actions (in the tick’s rotating seat order; on a
same-tile conflict, whoever that order reaches first wins), then
spawners, then crab movement, then gull movement, then gulls eat, in
stable creature order throughout. A signpost placed this tick affects
crabs arriving this tick. Once the tide is in (round_over), the sim
is frozen and ticks are no-ops: scores locked at the wave (spec §3.6).
Sourcepub fn seats_in_play(&self) -> u8
pub fn seats_in_play(&self) -> u8
How many seats this board seats: one past the highest castle owner, so a four-castle beach rotates ties among four however wide the arrays.
Sourcepub fn round_over(&self) -> bool
pub fn round_over(&self) -> bool
The tide has come in: the round is finished and the sim is frozen.
Sourcepub fn remaining_ticks(&self) -> Option<u64>
pub fn remaining_ticks(&self) -> Option<u64>
Ticks left before the wave, if a round timer is set.
Sourcepub fn in_surge(&self) -> bool
pub fn in_surge(&self) -> bool
The final scramble: the last 30 s of a timed round, when gulls spawn at double rate.
pub fn width(&self) -> u8
pub fn height(&self) -> u8
pub fn ticks(&self) -> u64
pub fn crabs(&self) -> &[Crab]
pub fn gulls(&self) -> &[Gull]
pub fn gull_period(&self) -> u32
pub fn round_length(&self) -> Option<u32>
Sourcepub fn remove_crabs_at(&mut self, x: u8, y: u8)
pub fn remove_crabs_at(&mut self, x: u8, y: u8)
Remove every crab standing on tile (x, y) (editor use).
Sourcepub fn remove_gulls_at(&mut self, x: u8, y: u8)
pub fn remove_gulls_at(&mut self, x: u8, y: u8)
Remove every gull standing on tile (x, y) (editor use).
Sourcepub fn lure(&self) -> Option<(PlayerId, u32)>
pub fn lure(&self) -> Option<(PlayerId, u32)>
Active molting lure, if any: (luring player, ticks left).
Sourcepub fn crabs_banked(&self) -> u32
pub fn crabs_banked(&self) -> u32
Crabs banked since the start, all players combined.
Sourcepub fn crabs_spawned(&self) -> u32
pub fn crabs_spawned(&self) -> u32
Crabs ever spawned (initial, spawner-emitted, and castle-spilled).
pub fn scores(&self) -> &[u32; 6]
pub fn tile_at(&self, x: u8, y: u8) -> TileKind
Sourcepub fn tiles(&self) -> impl Iterator<Item = (u8, u8, TileKind)> + '_
pub fn tiles(&self) -> impl Iterator<Item = (u8, u8, TileKind)> + '_
Every tile with its coordinates, in the board’s own row-major order.
Sourcepub fn castle_of(&self, player: PlayerId) -> Option<(u8, u8)>
pub fn castle_of(&self, player: PlayerId) -> Option<(u8, u8)>
Where a seat’s castle stands, if it has one.
Sourcepub fn castle_owners(&self) -> impl Iterator<Item = PlayerId> + '_
pub fn castle_owners(&self) -> impl Iterator<Item = PlayerId> + '_
The highest seat number with a castle on the board: the seat count a recorded board implies.
Sourcepub fn castle_seats(&self) -> u8
pub fn castle_seats(&self) -> u8
How many seats the board has castles for, counted by owner rather than by castle: a beach seats as many players as there are banks to run for. What the map dial measures a handmade beach against.
Sourcepub fn first_signpost_of(&self, player: PlayerId) -> Option<(u8, u8)>
pub fn first_signpost_of(&self, player: PlayerId) -> Option<(u8, u8)>
The first signpost owned by player in reading order (top-left to
bottom-right), as tile coordinates. Drives the “clear one” input.
Sourcepub fn coords_u8(&self, tile: u16) -> (u8, u8)
pub fn coords_u8(&self, tile: u16) -> (u8, u8)
Tile index back to coordinates. Board::coords speaks i32 for
the movement arithmetic; this is the public-facing form.
pub fn wall_at(&self, x: u8, y: u8, dir: Direction) -> bool
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Board
impl RefUnwindSafe for Board
impl Send for Board
impl Sync for Board
impl Unpin for Board
impl UnsafeUnpin for Board
impl UnwindSafe for Board
Blanket Implementations§
Source§impl<T, U> AsBindGroupShaderType<U> for T
impl<T, U> AsBindGroupShaderType<U> for T
Source§fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
T ShaderType for self. When used in AsBindGroup
derives, it is safe to assume that all images in self exist.Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> ConditionalSend for Twhere
T: Send,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<S, T> Duplex<S> for Twhere
T: FromSample<S> + ToSample<S>,
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T> HitDataExtra for T
Source§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more