Movement#

Direction#

class Direction(value)#

Directions of movement.

DOWN = 4#
LEFT = 6#
NORTH_EAST = 1#
NORTH_WEST = 7#
RIGHT = 2#
SOUTH_EAST = 3#
SOUTH_WEST = 5#
UP = 0#
property opposite: Direction#

SolvingMode#

class SolvingMode(value)#

An enumeration.

FORWARD = 0#

Forward solving mode

  • pusher is allowed to push single box at the time

  • pusher can’t pull boxes

  • pusher can’t jump over boxes or walls

REVERSE = 1#

Reverse solving mode

  • pusher is allowed to pull single box at the time

    • if position allows pull that pull is optional (pusher is allowed to move without pull even if pull is possible).

    • default behavior is to always pull boxes but that can be changed any time through Mover.pulls_boxes

  • pusher can’t push boxes

  • pusher is allowed to jump over boxes and walls

    • jumps are allowed only before first pull is done

  • board starts in solved state: positions of boxes and goals are switched

  • when boxes and goals are switched, pusher might end up “standing on box”. In this situation, fist move in game must be jump.

PusherStep#

class PusherStep(direction: Direction = Direction.LEFT, moved_box_id: int = - 1, is_jump: bool = False, is_pusher_selection: bool = False, pusher_id: int = 1, is_current_pos: bool = False)#

Represents single step of pusher movement.

Single step can be:

  • move: pusher moved without pushing box

  • push/pull: pusher pushed or pulled a box

  • jump: pusher jumped

  • pusher selection: pusher was selected among other pushers on board

Parameters
  • direction – direction in which movement was performed.

  • moved_box_id – ID of a box that was pushed or Config.NO_ID. Box usually gets it’s ID from BoardManager.

  • is_jump – flag marking this step as part of pusher jump in reverse solving mode. See Mover for more details about reverse movement.

  • is_pusher_selection – marks this step as part of pusher selecting sequence on boards with multiple pushers (Multiban game variant)

  • pusher_id – ID of pusher that performed movement. Pusher usually gets it’s ID from BoardManager.

  • is_current_pos – flags this step as current position in game snapshot

Raises

ValueError – single step can only be one thing at a time: move, push/pull or jump.

direction: Direction#

Direction of movement

is_current_pos#

flags this step as current position in game snapshot

property is_jump: bool#

True if this move is part of jump sequence in SolvingMode.REVERSE games.

property is_move: bool#

True if pusher didn’t move box, didn’t jump and didn’t select another pusher.

property is_push_or_pull: bool#

True if pusher moved a box.

property is_pusher_selection: bool#

True if this step is part of pusher selection sequence in Multiban games.

property moved_box_id: int#

ID of box that was moved or Config.NO_ID if no box was moved.

When setting box ID on ie. jump, that jump will become push. To change push into move, set box ID to Config.NO_ID.

Setting it to invalid value will silently set it to Config.NO_ID.

property pusher_id: int#

ID of pusher that performed movement.

Pusher ID must always be valid. When setting it to invalid value, PusherStep will silently set pusher ID to Config.DEFAULT_ID.

Mover#

class Mover(board: BoardGraph, solving_mode: SolvingMode = SolvingMode.FORWARD)#

Implements game rules (on-board movement). Supports forward and reverse game solving mode.

History management

Mover only stores last performed move in history and it doesn’t offer redo. Failed moves, undo and non-moves (ie. selecting already selected pusher or jumping on same position pusher is already standing on) clear undo history.

Warning

Mover operates directly on referenced game board. Because of that, this board should not be edited outside of Mover after Mover instance had been attached to it: editing the board will corrupt Mover internal state. For the same reason, there should not be more than one mover attached to the same board.

Raises

NonPlayableBoardError – when attaching mover to non playable board (see BoardManager.is_playable)

property board: BoardGraph#
property solving_mode: SolvingMode#
property board_manager: HashedBoardManager#
property selected_pusher: int#

ID of pusher that will perform next move.

See also

select_pusher()

property pulls_boxes: bool#

Select behavior in SolvingMode.REVERSE mode when pusher is moving away from box.

See also

move()

property last_move: List[PusherStep]#

Sequence of PusherStep that contains most recent movement.

Whenever Mover performs any movement or pusher selection, it puts resulting PusherStep into this sequence in order pusher steps happened.

This is useful for movement animation in GUI. After Mover performs movement, GUI has enough information to know what was performed and to choose which animations to render for that.

It is also possible to set this to some external sequence of moves. In that case, calling undo_last_move() will cause Mover to try to undo that external sequence of pusher steps.

Example:

>>> from sokoenginepy import Direction, Tessellation, Mover, PusherStep, BoardGraph, Puzzle
>>> puzzle = Puzzle(Tessellation.SOKOBAN, board='\n'.join([
...     '    #####',
...     '    #  @#',
...     '    #$  #',
...     '  ###  $##',
...     '  #  $ $ #',
...     '### # ## #   ######',
...     '#   # ## #####  ..#',
...     '# $  $          ..#',
...     '##### ### #@##  ..#',
...     '    #     #########',
...     '    #######'
... ]))
>>> board = BoardGraph(puzzle)
>>> mover = Mover(board)
>>> mover.last_move = [PusherStep(Direction.UP), PusherStep(Direction.RIGHT)]
>>> mover.undo_last_move()
>>> print(mover.board.to_board_str())
    #####
    #   #
    #$@ #
  ###  $##
  #  $ $ #
### # ## #   ######
#   # ## #####  ..#
# $  $          ..#
##### ### #@##  ..#
    #     #########
    #######
>>> mover.last_move
[PusherStep(Direction.LEFT), PusherStep(Direction.DOWN)]

Warning

Subsequent movement overwrites this meaning that Mover can only undo last move performed (it doesn’t keep whole history of movement, only the last performed move).

select_pusher(pusher_id: int)#

Selects pusher that will perform next move. If this pusher is already selected, does nothing.

From current position, generates sequence of steps needed to select pusher_id and stores them into last_move(). Sets internal selected pusher_id to newly selected pusher

Mover initially always selects Config.DEFAULT_ID. This means that for single-pusher boards, single pusher is always automatically selected and this method doesn’t need to be called.

Raises

KeyError – no pusher with ID pusher_id

move(direction: Direction)#

Moves currently selected pusher in direction.

In SolvingMode.FORWARD mode, pushes the box in front of pusher (if there is one).

In SolvingMode.REVERSE mode pulls box together with pusher (if there is one and if pulls_boxes is True).

Raises

IllegalMoveError – for illegal moves

jump(new_position: int)#

Currently selected pusher jumps to new_position.

Fails if

Raises
undo_last_move()#

Takes sequence of moves stored in last_move and tries to undo it.

See also

Mover.last_move

Raises

IllegalMoveError

exception IllegalMoveError#
exception NonPlayableBoardError#