NAME

Game::Brandubh::Terminal - brandubh in a terminal, with the arrow keys

VERSION

Version 0.03

SYNOPSIS

use Game::Brandubh::Terminal;

exit Game::Brandubh::Terminal->new(human => 'defenders', level => 2)->start;

or, from a shell:

brandubh --side defenders --level 2

DESCRIPTION

A game of brandubh against the program, or between two people at one keyboard, or the program against itself.

In a terminal it draws the board in colour and is played with the arrow keys. Anywhere else, or when asked, it is played by typing moves.

It is the only part of this distribution that reads a keyboard, writes to a screen or opens a file.

Before the game

Run as brandubh with no side and no level given, it first asks which side you will take and how hard the program should play, each chosen with the up and down arrows and enter.

Playing with the arrow keys

Moving a piece is two steps, and the cursor walks the board for both.

First the arrow keys move between the pieces that can move, and the squares the piece under the cursor could go to are marked. Enter picks it up.

Then the arrow keys move between the squares it can go to, and the board is drawn as the move would leave it: the piece on its new square, and every piece the move would capture struck out. A line under the board says the same in words, and says so when the move wins. Enter plays it; escape puts the piece back.

What the program last played stays written above the board until the next move is made.

arrows

The nearest piece, or square, in that direction.

tab

The next one, in order.

enter, space

Pick the piece up; put it down.

escape, backspace

Put the piece back.

h

Show the move the program would play, ready to be played with enter.

1, 2, 3

How hard the program plays.

u, r

Undo and redo. One u takes back your last move and the program's reply to it; between two people at one keyboard it takes back one move. r plays again what u took back, until another move is made. With nothing to take back or play again, a line above the board says so and nothing changes.

R, n, c, q

The rules; a new game; colour on and off; quit.

?

All of this.

:

Type a command.

Resigning and offering a draw are typed, not keyed: a game should not end because a finger slipped.

Playing by typing

A move is the square a piece leaves and the square it goes to, d1d3 or d1 d3. Everything else is a word:

moves       every legal move, and what each would capture
hint        what the program would play here
undo        take back your last move, and the reply to it
redo        play again what undo took back
board       draw the board again
pick        choose moves on the board with the arrow keys
type        go back to typing moves
level N     how hard the program plays, 1 to 3
side WHO    attackers, defenders, both or none
new         start another game
save FILE   write the game to a file
load FILE   read a game back from a file
draw        offer a draw
resign      give the game up
rules       the rules of the game
colour      turn colour on or off
help        this list
quit        stop playing

The board

With colour, the squares are two shades so that a line can be followed by eye, the throne and the corners are a colour of their own, and the three pieces are three shapes as well as three colours: a triangle for an attacker, a disc for a defender and a crown for the king.

Without colour the same board is drawn in letters and lines: A, D and K, # for the throne and X for a corner, with the cursor in square brackets, the square a move would land on in round ones, and a captured piece shown as x.

Colour is on in a terminal unless the environment variable NO_COLOR is set.

Three levels

The program plays at level 1, 2 or 3: see Game::Brandubh::Bot. It plays the defenders a good deal better than it plays the attackers, so somebody new to the game might start by taking the defenders.

METHODS

new

my $terminal = Game::Brandubh::Terminal->new(%options);

Every option is optional.

human

attackers (the default), defenders, both for two people, or none to watch the program play itself.

level

1, 2 or 3. 2 by default.

variant

The rule set, as "new" in Game::Brandubh takes it.

seed

Thirty-two bytes from which the program draws its choices. The same seed plays the same game. A fresh one is made when none is given.

game

A Game::Brandubh to carry on with.

in, out

The handles to read and write. Standard input and output by default.

interactive, colour, unicode, picking

Each is worked out from the handles when left out: a terminal is interactive, an interactive terminal has colour unless NO_COLOR is set, colour brings the drawn pieces with it, and the arrow keys are used when Term::ReadKey is there to read them.

True to ask for the side and the level before the game, when the arrow keys are in use. False by default.

keysource

A code reference that hands over one character a call, in place of the keyboard. For tests.

Croaks on a side or a level that is not one.

options

my $fields = Game::Brandubh::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.

side

One of attackers, defenders, both, none: your side; both is hotseat, none is watching.

level

A whole number from 1 to 3: how hard the program plays.

seed

Text: sixty-four hexadecimal characters; the same seed plays the same game.

run

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

The whole command line program as a class method: parses the options the brandubh 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 loaded, with the reason and the usage on STDERR. --help and --version print to STDOUT and return 0. Given none of --side, --level and --load, and a terminal whose keys it can read, it begins by asking which side, how hard and how to play. Signal handlers are local to the call and the terminal is left in cooked mode 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

Plays until the game is left, and returns 0. It never calls exit; the brandubh program does that with what this returns. The terminal is put back as it was found, an interrupt included.

command

my $stop = $terminal->command('d1d3');

Does what a typed line asks. True when the line was quit.

game

The game being played.

human

Which side is the person's.

level

The level the program plays at.

seed

The seed in use.

variant

The rule set new games are made with.

colour

unicode

picking

interactive

Whether each is on.

in

out

The two handles.

history

The Game::Terminal::Kit::History the turns are kept in, as the game's text. A turn is kept each time the move passes to a person, and when a game ends with a person at the keys; with the program playing both sides nothing is kept. A new game, a loaded game and "start" each begin it again.

The rest

These are the pieces the above is built from, public so that each can be tested on its own. None is needed to play.

turns

bot_plays

bot_move

pick

pick_ended

read_ended

The loop: whose turn it is, the program's move, and the person's.

keys_available

enter_raw

leave_raw

read_key

read_line

Reading the keyboard, a key or a line at a time. A line typed while the keys are read one at a time is drawn under the board, and escape gives it up.

steer

movable

reach

coordinates

Where the cursor can go: the pieces that can move, the squares one can reach, and the nearest of either in a direction.

screen

show

render

board_lines

painted_board

plain_board

marks

special

status_lines

result_lines

table_line

preview_lines

legend

tray

choose

ask_how_to_play

help_lines

rules_lines

page

paint

glyph

who

say

remark

Drawing: the board, what is written round it, and the two pages.

play_text

show_moves

hint_move

show_hint

take_back

play_again

swap

person_turn

new_game

fresh_game

save

load

set_level

set_side

offer_draw

resign

seat_of_human

budget

What the commands do.

keysource

pending

raw

Whether the keyboard is being read a key at a time.

notice

The lines written above the board, as an array reference. The newest eight things said are kept.

focus

chosen

redraw

pause

What the terminal is keeping track of from one key to the next.

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)