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
impl StaticBoardAnalysis
Sourcepub fn new<I>(
board: I,
size: Size2D,
tessellation: Tessellation,
sokoban_plus: Option<&SokobanPlus>,
) -> Result<Self, BoardSyntaxError>
pub fn new<I>( board: I, size: Size2D, tessellation: Tessellation, sokoban_plus: Option<&SokobanPlus>, ) -> Result<Self, BoardSyntaxError>
Builds a new StaticBoardAnalysis from a board scan.
That way it is decoupled from GameBoard, with no loss of
functionality.
Sourcepub fn flood_fill<F>(
root: Point2D,
is_obstacle: F,
size: Size2D,
tessellation: Tessellation,
) -> Option<BoardArea>
pub fn flood_fill<F>( root: Point2D, is_obstacle: F, size: Size2D, tessellation: Tessellation, ) -> Option<BoardArea>
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
Sourcepub fn tessellation(&self) -> Tessellation
pub fn tessellation(&self) -> Tessellation
Tessellation of the board this analysis was built from.
Sourcepub fn walls_positions(&self) -> &BoardArea
pub fn walls_positions(&self) -> &BoardArea
Positions of walls on the board this analysis was built from.
Sourcepub fn boxes_positions(&self) -> &BoardArea
pub fn boxes_positions(&self) -> &BoardArea
Positions of boxes on the board this analysis was built from.
Sourcepub fn goals_positions(&self) -> &BoardArea
pub fn goals_positions(&self) -> &BoardArea
Positions of goals on the board this analysis was built from.
Sourcepub fn pushers_positions(&self) -> &BoardArea
pub fn pushers_positions(&self) -> &BoardArea
Positions of pushers on the board this analysis was built from.
Sourcepub fn boxes(&self) -> &[Boxbox]
pub fn boxes(&self) -> &[Boxbox]
See also: GameBoard::boxes()
Sourcepub fn goals(&self) -> &[Goal]
pub fn goals(&self) -> &[Goal]
See also: GameBoard::goals()
Sourcepub fn pushers(&self) -> &[Pusher]
pub fn pushers(&self) -> &[Pusher]
See also: GameBoard::pushers()
Sourcepub fn outer_area(&self) -> BoardArea
pub fn outer_area(&self) -> BoardArea
All board positions that are not part of playable area and are not significant walls.
Sourcepub fn playable_area(&self) -> BoardArea
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:

Sourcepub fn is_playable_area_confined(&self) -> bool
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()
Sourcepub fn flood_path<F>(
from: Point2D,
to: Point2D,
is_obstacle: F,
size: Size2D,
tessellation: Tessellation,
) -> Option<Vec<Direction>>
pub fn flood_path<F>( from: Point2D, to: Point2D, is_obstacle: F, size: Size2D, tessellation: Tessellation, ) -> Option<Vec<Direction>>
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.
Sourcepub fn build_box(
maybe_id: usize,
x: usize,
y: usize,
sokoban_plus: Option<&SokobanPlus>,
) -> Result<Boxbox, BoardSyntaxError>
pub fn build_box( maybe_id: usize, x: usize, y: usize, sokoban_plus: Option<&SokobanPlus>, ) -> Result<Boxbox, BoardSyntaxError>
Sourcepub fn build_goal(
maybe_id: usize,
x: usize,
y: usize,
sokoban_plus: Option<&SokobanPlus>,
) -> Result<Goal, BoardSyntaxError>
pub fn build_goal( maybe_id: usize, x: usize, y: usize, sokoban_plus: Option<&SokobanPlus>, ) -> Result<Goal, BoardSyntaxError>
Sourcepub fn build_pusher(
maybe_id: usize,
x: usize,
y: usize,
) -> Result<Pusher, BoardSyntaxError>
pub fn build_pusher( maybe_id: usize, x: usize, y: usize, ) -> Result<Pusher, BoardSyntaxError>
Sourcepub fn significant_walls(&self) -> BoardArea
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§
impl Freeze for StaticBoardAnalysis
impl RefUnwindSafe for StaticBoardAnalysis
impl Send for StaticBoardAnalysis
impl Sync for StaticBoardAnalysis
impl Unpin for StaticBoardAnalysis
impl UnsafeUnpin for StaticBoardAnalysis
impl UnwindSafe for StaticBoardAnalysis
Blanket Implementations§
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> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.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 moreSource§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
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
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
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
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.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
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.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
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.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
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.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
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.
