pub struct Level {
pub name: String,
pub posts: u8,
pub solution: Vec<Placement>,
pub goal: Goal,
pub kind: LevelKind,
/* private fields */
}Fields§
§name: String§posts: u8Signpost inventory for the puzzle.
solution: Vec<Placement>One known solution; validated by tests.
goal: Goal§kind: LevelKindWhat the level is for: a stage to solve alone, or a beach to fight over. The author chooses it in the editor and it decides which of the two lists the level joins.
Implementations§
Source§impl Level
impl Level
pub fn parse(text: &str) -> Result<Level, String>
Sourcepub fn from_board(name: impl Into<String>, posts: u8, board: Board) -> Level
pub fn from_board(name: impl Into<String>, posts: u8, board: Board) -> Level
Wrap an editor-built board as a level. The board is snapshotted as-is
(crabs, gulls, walls, timers included), and the kind is read off it -
call Level::with_kind to say otherwise, which is what the editor’s
toggle does.
Sourcepub fn to_text(&self) -> String
pub fn to_text(&self) -> String
Serialize back to the text format parse reads. Round-trips exactly
for an un-ticked board that parse built (creature sub-tile state
is not representable, by design, since levels describe starting
states). A board edited by hand is a little different: placing a
gull draws twice from the board’s PRNG, and the text carries the
seed, not the stream’s position, so a board that placed and erased
gulls reads back with the survivors rolled afresh. That is why the
editor certifies the text it will save rather than the board it
edited (level_here).
Source§impl Level
impl Level
Sourcepub fn board(&self) -> Board
pub fn board(&self) -> Board
A fresh board for this level. Puzzle levels get fixed-inventory rules
from posts; levels carrying an explicit rule: (recorded versus
matches) keep the rule the match was played under.
An arena that states no rule keeps the board’s own, which is the
versus one. Reading posts: as a rule there gave a table three
signposts each and no way to replace them - the file says how many
the author had to hand, not how a match is played on it.
pub fn crab_count(&self) -> u32
Sourcepub fn with_kind(self, kind: LevelKind) -> Level
pub fn with_kind(self, kind: LevelKind) -> Level
Say what the level is for. The editor’s toggle is authoritative: a level saved as a puzzle stays one however many castles it grew.
Sourcepub fn seats(&self) -> u8
pub fn seats(&self) -> u8
How many seats the beach could hold: one castle each, counted by
owner. What the map dial checks a handmade beach against, and what
tells a level with no kind: line of its own what it must be.
Sourcepub fn play_out(&self, board: &mut Board) -> (PuzzleOutcome, u64)
pub fn play_out(&self, board: &mut Board) -> (PuzzleOutcome, u64)
Run board idle until the goal is decided, and say when it was.
Every caller that wants to know how a board ends wants exactly this
loop, and ten of them once carried their own copy. Level::outcome
is what makes it terminate: every goal loses or wins by the board’s
Level::deadline, so the loop needs no guard of its own, and if
that ever moves there is one place to put it.
Sourcepub fn place_solution(&self, board: &mut Board) -> Result<(), Placement>
pub fn place_solution(&self, board: &mut Board) -> Result<(), Placement>
Place the authored solution on board for seat 0. Err names the
first placement the board refused, which on a shipped level is a
broken level file and never something to shrug off.
Sourcepub fn solved_board(&self) -> Result<Board, Placement>
pub fn solved_board(&self) -> Result<Board, Placement>
A fresh board with the authored solution standing on it.
Sourcepub fn deadline(board: &Board) -> u64
pub fn deadline(board: &Board) -> u64
The tick by which every goal on board is decided: its own round
when it carries one, else PUZZLE_TICK_LIMIT, which stands in for
a stage with no timer, which would otherwise never end. One answer
for the outcome, the solver’s scan and the clock, so a stage that
states a longer round is not cut off at the limit anyway.
Sourcepub fn outcome(&self, board: &Board) -> PuzzleOutcome
pub fn outcome(&self, board: &Board) -> PuzzleOutcome
Win/loss state of a board created by Level::board, judged by the
level’s goal. All goals use banked-count accounting (spec §5.1: a
crab a gull ate is a loss for AllCrabs/Survive, never a quiet
disappearance). Level::deadline is the clock it is judged on.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Level
impl RefUnwindSafe for Level
impl Send for Level
impl Sync for Level
impl Unpin for Level
impl UnsafeUnpin for Level
impl UnwindSafe for Level
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