NAME
Game::RoyalUr::Rules - a position of the Royal Game of Ur, and how it changes
VERSION
Version 0.01
SYNOPSIS
use Game::RoyalUr::Rules;
my $game = Game::RoyalUr::Rules->new(rules => 'finkel');
my @moves = $game->moves(3); # what a roll of 3 allows
if (@moves) { $game->apply($moves[0]) }
else { $game->forfeit }
print $game->side, " to move\n"; # asked, never assumed
print $game->winner, " wins\n" if $game->status eq 'won';
$game->undo;
DESCRIPTION
A game without its dice. This class holds a position under a rule set and changes it one move at a time: it says what a roll allows, makes a move, loses a turn, takes either back, says whose turn it is and whether the game is over.
It is handed every roll. It holds no seed and throws nothing, which is what lets a game be scripted from a list of rolls. Game::RoyalUr joins this to the dice, and is what most callers want.
Whose turn it is
Turns do not alternate. A piece that lands on a rosette earns its side another roll, so the same side is to move again; a move anywhere else, a move that takes a piece home, and a turn lost to the roll all pass the turn. side is the only place to find out. Ask it after every apply and every forfeit.
A captured piece
A piece that lands on an enemy piece sends it back to its owner's hand, to start again from the beginning.
How a game ends
A side wins the moment its last piece comes home, on the move that brings it, whatever the other side has left.
A game is drawn when the count of plies reaches a cap. A move is a ply and so is a lost turn. The cap exists because a capture sends a piece back to the start, so nothing else guarantees that a game ends; it is set far above the length of any game play produces.
Once a game is over, moves answers nothing and apply and forfeit refuse.
METHODS
new
my $game = Game::RoyalUr::Rules->new;
my $game = Game::RoyalUr::Rules->new(rules => 'masters', first => 'dark');
my $game = Game::RoyalUr::Rules->new(position => '4xx2/3l4/4xx2 d 6 0 7 0');
rules-
A rule set: a name or a hash reference, as "A RULE SET" in Game::RoyalUr::Engine describes.
'finkel'when it is left out. position-
A position string to start from. Without one the board is empty and every piece is in hand.
first-
'light'or'dark': the side to move, overriding the position's. ply-
The count of plies to start from, 0 when it is left out.
Croaks on a rule set, a position, a side or a count it will not take.
rules
The rule set, spelled out as a hash reference with all five fields. A copy: changing it changes nothing.
side
'light' or 'dark': the side to move.
moves
my @moves = $game->moves($roll);
The Game::RoyalUr::Move objects a roll allows the side to move, a piece entering from the hand first and then the pieces in the order they stand along the route. In scalar context, how many. None for a roll of 0, and none once the game is over.
apply
$game->apply($move) or die;
Makes one of the moves moves returned, and returns it. Returns undef, and changes nothing, when the game is over, when the move belongs to the side not to move, or when the piece it names is not there.
It does not check the move against a roll. That is for whoever holds the dice.
forfeit
$game->forfeit;
Loses the turn: the other side is to move. True when done, false when the game is over.
undo
$game->undo;
Takes back the last apply or forfeit, exactly. True when something was taken back, false when there was nothing left to take.
depth
How many moves and forfeits undo could still take back.
status
'ongoing', 'won' or 'drawn'.
is_over
True when status is not 'ongoing'.
how
'home' when a side has brought its last piece home, 'ply_cap' when the game ran to the cap, and undef while it is still being played.
winner
'light' or 'dark', or undef when nobody has won.
ply
How many moves and forfeits have been made.
position
The position as a string. See "to_string" in Game::RoyalUr::Engine.
key
Twelve hexadecimal characters that stand for the position. See "The key is a hex string, never a number" in Game::RoyalUr::Engine.
hand
my $waiting = $game->hand('light');
How many of a side's pieces have not yet entered the board.
home
my $finished = $game->home('dark');
How many of a side's pieces have come home.
board
A Game::RoyalUr::Engine in the same position. It is a copy: changing it does not change the game.
AUTHOR
LNATION <email@lnation.org>
LICENSE AND COPYRIGHT
This software is Copyright (c) 2026 by LNATION <email@lnation.org>.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)