Skip to main content

StaticBoardAnalysis

Struct StaticBoardAnalysis 

Source
pub struct StaticBoardAnalysis { /* private fields */ }
Expand description

Static analysis of game boards (outer walls, corners, play area…)

Static board features are categories of board positions that don’t change semantics even after pushers and boxes had been moved around board. For example:

  • positions of outer walls
  • position of “corners”
  • active playable area
  • pusher, box and goal IDs in starting position
  • …

This kind of analysis only makes sense when applied to finalized board designs, ie. a GameBoard that is no longer being edited.

§Todo

  • construct and test more pathological cases for Trioban / Hexoban / Octoban (play area, significant walls, corners, …)
  • wall surrounded by walls in play area?
  • in Sokoban this wall should not be marked as playable, neither should floors in same position

Implementations§

Source§

impl StaticBoardAnalysis

Source

pub fn new<I>( board: I, size: Size2D, tessellation: Tessellation, sokoban_plus: Option<&SokobanPlus>, ) -> Result<Self, BoardSyntaxError>
where I: Iterator<Item = TileKind>,

Builds a new StaticBoardAnalysis from a board scan.

That way it is decoupled from GameBoard, with no loss of functionality.

Source

pub fn flood_fill<F>( root: Point2D, is_obstacle: F, size: Size2D, tessellation: Tessellation, ) -> Option<BoardArea>
where F: Fn(Point2D) -> bool,

Flood fill with generic bordering predicate.

None if root is off-board.

§Todo

It should probably return top-left position of found area, as an optimization

Source

pub fn size(&self) -> Size2D

Dimensions of the board this analysis was built from.

Source

pub fn tessellation(&self) -> Tessellation

Tessellation of the board this analysis was built from.

Source

pub fn walls_positions(&self) -> &BoardArea

Positions of walls on the board this analysis was built from.

Source

pub fn boxes_positions(&self) -> &BoardArea

Positions of boxes on the board this analysis was built from.

Source

pub fn goals_positions(&self) -> &BoardArea

Positions of goals on the board this analysis was built from.

Source

pub fn pushers_positions(&self) -> &BoardArea

Positions of pushers on the board this analysis was built from.

Source

pub fn boxes(&self) -> &[Boxbox]

Source

pub fn goals(&self) -> &[Goal]

Source

pub fn pushers(&self) -> &[Pusher]

Source

pub fn outer_area(&self) -> BoardArea

All board positions that are not part of playable area and are not significant walls.

Source

pub fn playable_area(&self) -> BoardArea

All board positions which are part of “active” board area.

Active board area contains any position that is reachable by any of pushers as if there were no boxes and no other pushers on board.

Any tile not included in this area may be replaced by wall. Resulting GameBoard would no longer look exactly the same but will still have exact same solution.

In following image, greyed out squares are the ones that will not be in set returned by this method:

Source

pub fn is_playable_area_confined(&self) -> bool

Is the playable_area() confined by walls alone?

true when no playable position lies on the board’s outer edge. This is what “closed board” means, and it is the only thing it can mean: flood_fill() stops at walls and at the board edge, so the play area is always confined by walls together with the edge. A board is closed exactly when the edge is not doing any of that work.

A board with no Pusher has no play area at all and is vacuously confined, as is the empty board.

See also: GameBoard::enclose()

Source

pub fn flood_path<F>( from: Point2D, to: Point2D, is_obstacle: F, size: Size2D, tessellation: Tessellation, ) -> Option<Vec<Direction>>
where F: Fn(Point2D) -> bool,

Breadth first search for the shortest path from from to to, with generic bordering predicate.

The path-shaped counterpart of flood_fill(), and deliberately the same shape: both take the obstacle predicate, the board size and the Tessellation as arguments rather than reading them off self, so a caller is free to define “obstacle” however its rules require.

Returns Some empty path when from == to, and None when either endpoint is off-board or to cannot be reached.

Source

pub fn corners(&self) -> BoardArea

Corners in playable area.

Source

pub fn build_box( maybe_id: usize, x: usize, y: usize, sokoban_plus: Option<&SokobanPlus>, ) -> Result<Boxbox, BoardSyntaxError>

Helper for GameBoard scanners. Builds a Boxbox for the maybe_id-th box of a scan, tagged from sokoban_plus.

Source

pub fn build_goal( maybe_id: usize, x: usize, y: usize, sokoban_plus: Option<&SokobanPlus>, ) -> Result<Goal, BoardSyntaxError>

Helper for GameBoard scanners. Builds a Goal for the maybe_id-th goal of a scan, tagged from sokoban_plus.

Source

pub fn build_pusher( maybe_id: usize, x: usize, y: usize, ) -> Result<Pusher, BoardSyntaxError>

Helper for GameBoard scanners. Builds a Pusher for the maybe_id-th pusher of a scan.

Source

pub fn significant_walls(&self) -> BoardArea

All board positions that are touching active playable_area().

In following image, tiles that are not greyed out are positions returned by this method. Notice how it also correctly detects a missing wall tile (circled in red).

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.