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 in bot mode. '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_COLOR set.

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)