NAME

Game::RoyalUr::Terminal - the Royal Game of Ur, played in a terminal

VERSION

Version 0.03

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.

Taking a turn back

u, or the typed undo, takes back your last turn and every move the program made after it, however many rosettes and lost turns there were, so the board is as it was when it was last yours to move, with the same roll and the same dice. r, or the typed redo, plays that turn and its replies again. Each goes as far back, or forward, as you like, a turn at a time. Making a move after taking one back forgets whatever could have been played again. In hotseat every move is a turn; in watch there is nothing to take back. With nothing to take back or play again a line says so and the game is unchanged. A new game starts its history afresh. R, or the typed route, shows or hides the route.

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 to anything but the empty string.

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.

history

A Game::Terminal::Kit::History to keep the turns in, as the text "to_text" in Game::RoyalUr writes. One is made when it is not given.

Croaks on a mode, a side, a first, a level, a pace or rules it does not understand.

options

my $fields = Game::RoyalUr::Terminal->options;

The options a person would set before a game, in the order a launcher shows them. Each is a hash reference with a name, a type and a help, and min and max or choices where the type has them. A new list is returned each time.

mode

One of bot, hotseat, watch: you against the program, two people, or the program against itself.

rules

One of finkel, masters: the route and the rules.

level

A whole number from 1 to 4: how well the program plays; the top by default.

side

One of light, dark: your side against the program.

first

One of light, dark, roll: who moves first, or throw the dice for it.

seed

Text: hexadecimal; the same seed throws the same dice.

run

exit Game::RoyalUr::Terminal->run(@ARGV);

The whole command line program as a class method: parses the options the royalur program documents, builds the terminal, plays, and returns the exit status rather than calling exit: 0 when the game was left in the ordinary way, 2 for a bad option, a stray word, a refused value or a file that could not be read or replayed, with the reason and the usage on STDERR. --help and --version print to STDOUT and return 0. Signal handlers are local to the call and the keyboard is given back on every way out, so a launcher such as Game::Terminal can call it in its own process and carry on afterwards. Colour is off under NO_COLOR as well as off a terminal.

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 and stop at the last, tab and back_tab go round them in order, and a digit goes straight to one. The keys are named as Game::Terminal::Kit::Keys names them; backtab is taken as back_tab.

pick

Runs the arrow-key picker until a move is chosen, and returns it as text; or 'undo' for u, 'redo' for r, 'route' for R, 'new' for n or 'quit' for q pressed twice; 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, redo, new, route, moves, record FILE, level N and quit; u is short for undo and r for redo. True when the line asks to leave.

take_back

$terminal->take_back;

Takes back the last turn of the person at the keys and every reply to it, as undo does. True when there was a turn to take back; otherwise a line says so and the game is unchanged.

play_again

$terminal->play_again;

Plays again the turn last taken back, as redo does. True when there was one.

swap

$terminal->swap($game);

Puts another game in place of this one, so that what has already been said of it is not said again, the cursor is on the first candidate and no note is left over.

person_turn

Called when the turn passes to a person at the keys: records the game in "history" as a turn.

history

The Game::Terminal::Kit::History the turns are kept in.

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)