NAME
Game::RoyalUr::Terminal - the Royal Game of Ur, played in a terminal
VERSION
Version 0.01
SYNOPSIS
use Game::RoyalUr::Terminal;
exit Game::RoyalUr::Terminal->new(rules => 'masters', level => 2)->start;
Or, from a shell, the royalur program that comes with this distribution.
DESCRIPTION
A board drawn in the terminal, the dice shown as they fell, and a game played against the program, between two people at one keyboard, or by the program against itself.
This is the one module in the distribution that reads a keyboard, writes to a screen, asks the time or draws on chance of its own (for a seed, when it is not given one). Everything else is a game that does none of those.
Choosing a move
The roll says how far a piece goes, so a move is a choice of piece and nothing more.
In a terminal, with Term::ReadKey installed, the pieces that can move are walked with the arrow keys, and the board is redrawn for each as it would stand after that move: [ ] where the piece was, ( ) where it lands, and < > round an enemy piece it sends back to its owner's hand. A line under the board says the same in words. Enter makes the move.
Anywhere else, and with picking off, the moves are listed with numbers and a line is read: a number, or a move such as hand-b1 or a2-d2.
What is never left out
A turn lost to the roll is shown, with its dice, and stays on the screen: the last four things that happened are always under the board. A move that is the only one the roll allows is still yours to make.
Marks are shapes
Light and dark pieces differ in shape and not only in colour, a rosette is drawn in its square and stays drawn under a piece, and each of the marks above is its own pair of brackets. Colour goes on top of all of that. With colour off, and in a terminal that has none, nothing is lost.
METHODS
new
my $terminal = Game::RoyalUr::Terminal->new(%options);
Every option is also a method that reads it.
mode-
'bot', a person against the program, the default;'hotseat', two people;'watch', the program against itself. side-
'light'or'dark': the person's side inbotmode.'light'by default. level-
How well the program plays, from 1 to the top of the ladder Game::RoyalUr::Bot has for the rules. The top by default.
rules-
'finkel'or'masters', or anything else "new" in Game::RoyalUr takes. first-
'light'or'dark'to name who moves first, or'roll', the default, to have the two sides throw for it. seed-
Bytes that decide every throw of the dice, so that a game can be played again. Drawn afresh when it is left out.
pace-
Seconds to hold the screen on a lost turn and on the program's move. 1 by default in a terminal, 0 elsewhere.
route-
True to show, under the board, the order in which the side to move visits the squares.
record-
The name of a file to write the game to when the sitting ends.
colour,unicode,picking-
Whether to paint, whether to draw with line and shape characters, and whether to choose with the arrow keys. Each is on in a terminal and off elsewhere unless it is said; colour is also off when the environment has
NO_COLORset. interactive-
Whether the screen is redrawn in place. True when the input is a terminal.
in,out-
The handles read and written. Standard input and output by default.
keysource-
A code reference to take keys from in place of the keyboard. For tests.
sleeper-
A code reference called with a number of seconds in place of waiting that long. For tests.
game-
A Game::RoyalUr to play, in place of a new one.
Croaks on a mode, a side, a first, a level, a pace or rules it does not understand.
start
exit $terminal->start;
Plays until the person leaves or the input ends, and returns 0. It returns; it does not exit.
game
The game being played.
in
out
interactive
colour
unicode
picking
mode
side
level
rules
first
seed
pace
route
record
keysource
sleeper
The options, as they stand. See "new".
candidates
The moves the roll allows, in the order the keys walk them with tab: the game's own legal moves.
steer
my $index = $terminal->steer('right');
Moves the cursor among the candidates and returns where it is: left, right, up and down go to the next piece that way, tab and backtab go round them in order, and a digit goes straight to one.
pick
Runs the arrow-key picker until a move is chosen, and returns it as text; or 'undo', 'new', 'route' or 'quit' for the key that asks for one; or undef when the keys run out.
command
my $leaving = $terminal->command('a2-d2');
Does what a typed line says: a move, a number from the list, or one of help, undo, new, route, moves, record FILE, level N and quit. True when the line asks to leave.
board_lines
my $lines = $terminal->board_lines;
my $lines = $terminal->board_lines($move);
The board as lines of text: as it stands, with each side's last move marked, or as it would stand after a move, with that move's three marks.
screen
my $lines = $terminal->screen('pick');
A whole screen as lines of text: the title, the board, the roll and its dice, what the move under the cursor would do, and the last four things that happened.
show
Writes a screen.
events
Everything that has been said to have happened, oldest first, as a reference to an array of sentences.
help_lines
The keys and the commands, as lines of text.
save
$terminal->save($file) or warn "could not write $file";
Writes the game to a file as a record. True when it was written.
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)