Skip to content

Rulesets

The RuleSet is the starting point for solving Rummikub game problems. It defines defines how many tiles are used in the game, how many different tile colours there are, the number of jokers, etc.

ruleset = RuleSet(colours=5, min_len=4, min_initial_value=42, jokers=3)

For a given GameState, with tiles on the rack and / or the table, you can then look for possible set placements:

# A possible legal arrangement of tiles on the table
table_placement = ruleset.arrange_table(game)

# Can you place tiles from the rack on the table?
solution = ruleset.solve(game)

rummikub_solver.RuleSet

RuleSet(
    *,
    numbers: Annotated[int, Interval(ge=2, le=26)] = 13,
    repeats: Annotated[int, Interval(ge=1, le=4)] = 2,
    colours: Annotated[int, Interval(ge=2, le=8)] = 4,
    jokers: Annotated[int, Interval(ge=0, le=4)] = 2,
    min_len: Annotated[int, Interval(ge=2, le=6)] = 3,
    min_initial_value: Annotated[
        int, Interval(ge=1, le=50)
    ] = 30,
    solver_backend: MILPSolver | None = None,
)

Manages all aspects of a specific set of Rummikub rules.

The default settings reflect the rules for a standard (Sabra rules) Rummikub game.

Note that you can't create rulesets where min_len is greater than numbers or colours, because then there are no legal sets possible. All numeric arguments are validated and will result in a ValueError if they do not fall within their specified interval.

Methods:

Name Description
new_game

Create a new game state for this ruleset.

solve

Find the best option for placing tiles from the rack.

arrange_table

Check if the tiles on the table can be arranged into sets.

game_state_valid

Validate a game state against this ruleset.

Attributes:

Name Type Description
backend MILPSolver

The solver backend used for finding sets to place.

numbers Annotated[int, Interval(ge=1, le=26)]

How many number tiles there are for each colour.

repeats Annotated[int, Interval(ge=1, le=4)]

How many duplicates there are of each number tile.

colours Annotated[int, Interval(ge=1, le=8)]

How many tile colours there are.

jokers Annotated[int, Interval(ge=0, le=4)]

How many joker tiles there are.

min_len Annotated[int, Interval(ge=2, le=6)]

The minimum length of a valid set.

min_initial_value Annotated[int, Interval(ge=1, le=50)]

The minimum value of tiles required for a player to make their first move.

tile_count int

Total number of unique tiles.

game_state_key str

Short string uniquely identifying game states that fit this ruleset.

tiles Sequence[Tile]

All valid tiles for this ruleset.

sets Sequence[tuple[Tile, ...]]

All valid sets of tiles for this ruleset.

backend property writable

backend: MILPSolver

The solver backend used for finding sets to place.

This defaults to SCIPY, unless highspy installed, in which case the default is HIGHS.

numbers property

numbers: Annotated[int, Interval(ge=1, le=26)]

How many number tiles there are for each colour.

repeats property

repeats: Annotated[int, Interval(ge=1, le=4)]

How many duplicates there are of each number tile.

colours property

colours: Annotated[int, Interval(ge=1, le=8)]

How many tile colours there are.

jokers property

jokers: Annotated[int, Interval(ge=0, le=4)]

How many joker tiles there are.

min_len property

min_len: Annotated[int, Interval(ge=2, le=6)]

The minimum length of a valid set.

min_initial_value property

min_initial_value: Annotated[int, Interval(ge=1, le=50)]

The minimum value of tiles required for a player to make their first move.

tile_count property

tile_count: int

Total number of unique tiles.

This is equal to numbers * colours + bool(jokers).

game_state_key cached property

game_state_key: str

Short string uniquely identifying game states that fit this ruleset.

This key is useful when persisting game states, where you can then group persisted states by this key, and later on look up these states once a ruleset has been established.

tiles cached property

tiles: Sequence[Tile]

All valid tiles for this ruleset.

Number tiles are arranged in numeric order per colour, with the first numbers entries the number tiles for the first Colour, etc. If this ruleset contains jokers, then the last element of this sequence is the joker tile.

sets cached property

sets: Sequence[tuple[Tile, ...]]

All valid sets of tiles for this ruleset.

new_game

new_game() -> GameState

Create a new game state for this ruleset.

Returns:

Type Description
GameState

An empty game state.

solve

solve(
    state: GameState, mode: SolverMode | None = None
) -> ProposedSolution | None

Find the best option for placing tiles from the rack.

If no mode is selected, uses the game initial state flag to switch between initial and tile-count modes.

When in initial mode, if there are tiles on the table already, adds an extra round of solving if the minimal point threshold has been met, to find additional tiles that can be moved onto the table in the same turn.

Provided the input game state modeled a valid rummikub game with a table that was arrangeable before this move, the tiles used in the solution sets plus any free jokers will equal the tiles on the table plus the tiles the proposed solution moves from the rack to the table.

Parameters:

Name Type Description Default
state GameState

The game state to solve.

required
mode SolverMode | None

Optional solver mode.

None

Returns:

Type Description
ProposedSolution | None

The proposed solution if it is possible to put tiles on the table.

Raises:

Type Description
ValueError

if the given state is not valid.

arrange_table

arrange_table(state: GameState) -> TableArrangement | None

Check if the tiles on the table can be arranged into sets.

Produces a series of sets and how many unattached jokers are available.

Parameters:

Name Type Description Default
state GameState

The game state for which to arrange the table tiles.

required

Returns:

Type Description
TableArrangement | None

The table arrangement if one can be determined.

Raises:

Type Description
ValueError

if the given state is not valid.

game_state_valid

game_state_valid(state: GameState) -> bool

Validate a game state against this ruleset.

Checks if the number of tiles in the game state are still legal within the ruleset; that is, the number of repeated tiles doesn't exceed the ruleset limits.

Parameters:

Name Type Description Default
state GameState

The game state to validate.

required

Returns:

Type Description
bool

Whether or not the state is valid.