NAME

Game::Sternhalma::Terminal - sternhalma in a terminal, by arrow key or by typed move

VERSION

Version 0.01

SYNOPSIS

use Game::Sternhalma::Terminal;

exit Game::Sternhalma::Terminal->new(seats => 3, bots => [1, 2], level => 2)->start;

Most people want the program, sternhalma, which is this with options.

DESCRIPTION

A game of Game::Sternhalma for two, three, four or six seats, each played by a person at the keyboard or by Game::Sternhalma::Bot.

It plays in one of three ways. On a terminal whose keys it can read one at a time, a move is chosen on the board with the arrow keys. Anywhere else, and whenever it is asked to, it reads a line at a time: a move written out, or a command. And "pipe" answers each move with the position, for a program at the other end.

The board

               a  R
              b  R   R
             c  R   R   R
            d  R   R   R   R
e  .   .   .   .   .   .   .   .   .   .   .   .   .
  f  .   .   .   .   .   .   .   .   .   .   .   .
    g  .   .   .   .   .   .   .   .   .   .   .
      h  .   .   .   .   .   .   .   .   .   .
        i  .   .   .   .   .   .   .   .   .
      j  .   .   .   .   .   .   .   .   .   .
    k  .   .   .   .   .   .   .   .   .   .   .
  l  .   .   .   .   .   .   .   .   .   .   .   .
m  .   .   .   .   .   .   .   .   .   .   .   .   .
            n  B   B   B   B
             o  B   B   B
              p  B   B
               q  B

A hole is named by its row's letter and its place in the row from the left: the top tip is a1, the centre i5. A piece is its seat's letter as well as its seat's colour, so six seats can be told apart without colour: Red, Yellow, Green, Blue, Purple and Orange, clockwise from the top. With colour, each piece is its letter on its colour, and an empty hole in a seat's home is a dot in that seat's colour, so every seat can see where it is going.

A mark is a pair of brackets either side of a hole, and with colour a ground behind them, so that no mark depends on colour and none ever changes the width of a row:

[R]   the cursor
<R>   the piece picked up
(.)   a hole it can reach
{.}   a hole on its way there
:R:   the last move: every hole it went through

Beside the board, each seat: who plays it, and how far it has left to go, or the place it finished in.

Choosing a move with the keys

The cursor walks over the pieces that can move and over no others; the holes the one under it can reach are lit. The arrow keys move it to the nearest such piece that way; Tab goes round them in the order they are drawn. Enter picks the piece up. The cursor then walks the holes it can reach, and the way there, hop by hop, is shown. Enter moves it; on a screen that is redrawn the piece is seen to go, hole by hole. Escape puts it back.

A seat with no move is told so, and Enter passes. h shows the move the program would play, picked up and waiting for Enter or Escape. u takes back your last move and every reply the program made to it; r plays again what u took back.

Typed moves and commands

A move is the hole a piece leaves and the hole it ends in, joined by a hyphen, d4-e5: a chain of hops can be written that way too, or with every hole it lands in, c1:e5:g5. pass when there is no move.

moves        every move you may make
hint         what the program would play
board        draw the board again
undo         take back your last move, and the replies to it
redo         play again what undo took back
level N      how hard the program plays, 1 to 4
new [N]      another game, for N seats if given
save FILE    write the game to a file
load FILE    read one back
resign       give the game up for the seat to move
rules        the rules
help         the keys and the commands
quit         stop

METHODS

new

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

Every option is also an accessor of the same name.

seats

2 (the default), 3, 4 or 6.

pieces

10 (the default), or 15 for two or three seats.

bots

The seats the program plays, as an array reference; every seat but 0 by default. An empty list is a game for people only; every seat is the program playing itself. A seat the game does not have croaks.

level

1 to 4, 3 by default: which of "rungs" in Game::Sternhalma::Bot the program plays at, the weakest first. Anything else croaks.

seed

Which of its equally good moves the program makes: the same seed, the same game.

game

A Game::Sternhalma to carry on with, in place of a new one.

in, out

The filehandles. Standard input and standard output by default.

interactive

Whether out is a screen to be redrawn. True by default when in is a terminal.

colour

Whether to paint. On by default on a terminal, unless NO_COLOR is set.

unicode

Whether an empty hole is a middle dot, or a full stop. It follows colour by default.

picking

Whether moves are chosen with the keys. On by default on a terminal, and turned off when the keys cannot be read one at a time, which needs Term::ReadKey.

Whether "start" first asks for the seats, the people, the level and the pieces. Off by default.

width

The width of the window in columns. By default it is asked of the terminal each time the board is drawn. When the board does not fit, a line saying how wide it needs to be is drawn in its place.

pause

Whether a move is seen to go hole by hole, and the program waits a moment between moves when it plays every seat.

quiet

Whether what a command says goes to STDERR, plain, instead of above the board: so it is in "run" with --pipe, whose STDOUT is for a program.

keysource

A code reference called for each character in place of the keyboard, handed a true value when it should wait for one. It returns one character, or undef at the end. This is how the tests press keys.

options

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

The options a person would set before a game, in the order a launcher shows them: seats, pieces, people and level. 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.

run

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

The whole command line program as a class method: parses the options the sternhalma 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 on STDERR. Given none of the options that set up a game, and a terminal whose keys it can read, it begins by asking.

start

my $status = $terminal->start;

Plays until the player stops or the input ends, and returns 0. The keyboard is given back as it was found, on the way out and when interrupted.

pipe

my $status = $terminal->pipe;

Plays for a program at the other end of in and out. It writes start and the position; then reads a move a line and answers each with ok or the flag "play" in Game::Sternhalma gave, and the position after it. Each move the program makes for a seat in "bots" is written as bot, the move and the position. At the end it writes over, how the game ended and every seat's place, joined by commas, and returns 0, as it does when the input ends or reads quit.

command

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

Does one line: a command, or else a move. Returns true when the line asks to stop.

load

$terminal->load('saved.txt') or die;

Replaces the game with the one in the file. Returns false, having said why, when the file cannot be read or is not a game.

pick

my $line = $terminal->pick;

Lets the player choose one move with the keys and plays it. Returns an empty string once a move has been played, a command for "command" when the player asked for one, and undef when the keys ran out.

take_back

Takes back one step of "history", as u and undo do. Returns false, having said so, when there is none.

play_again

Plays one step again, as r and redo do. Returns false, having said so, when there is none.

swap

$terminal->swap($game);

Replaces the game, puts down a piece picked up, and forgets the cursor, the last move and what was written above the board. The history is left as it is.

person_turn

Keeps the game in "history": called each time the move passes to a person, and once a game has ended with a person at the keys.

lit

The holes of the pieces that can move, as an array reference, in the order they are drawn: the top row first, each row from the left.

reach

my $holes = $terminal->reach($hole);

The holes the piece in a hole can reach this turn, in the order they are drawn; the piece picked up when no hole is given.

way

my $path = $terminal->way($from, $to);

Every hole a move goes through, the first and the last too.

steer

my $hole = $terminal->steer($from, 'up', \@holes);

The nearest of the holes in that direction from the first, or the first when there is none.

marks

my ($mark, $pieces) = $terminal->marks($mode);

What a drawing shows: the mark on each marked hole, and the seat of the piece in each hole that has one. The mode is plain, which while a piece is being chosen, where while one is picked up, or pass.

board_lines

my $lines = $terminal->board_lines($mode);

The board as lines of text, with the seats beside it.

column

my $at = $terminal->column($hole);

The column a hole's piece or dot is drawn in, counted from 0.

screen

my $lines = $terminal->screen($mode);

A whole screen as lines of text. As well as the modes above there are ended, thinking, menu, help and rules.

show

Draws "screen" on out, over the last one when interactive is true.

render

Writes the board and whose turn it is, as typed play does before each prompt.

colour_of

my $colour = $terminal->colour_of($seat);

red, yellow, green, blue, purple or orange: the colour of the point the seat starts in.

seat_name

The same, as a name: Red.

is_bot

Whether the program plays a seat.

people

The seats played at the keys.

rung

The Game::Sternhalma::Bot rung the level is.

raw

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

notice

The lines written above the board, as an array reference: the last move, and what a command said. The newest eight are kept.

focus

The hole the cursor is on while a piece is being chosen.

chosen

The hole of the piece picked up, or undef.

target

The hole the cursor is on while a piece is picked up.

last

The last move played here, or after u or r the last move of the game then on the board, as a hash of move and the path it went, and seat when it was played here; undef before one has been.

history

The Game::Terminal::Kit::History the turns are kept in, as the game's log. 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 every seat nothing is kept. A new game, a loaded game and "start" each begin it again.

TABLES

%PIECE, %GROUND, %INK, %GLYPH, %FRAME and %LETTER are package variables holding the colours, the dots, the brackets and the seats' letters, so that a test can measure them. A colour is one of the 240 that every terminal with 256 agrees on, and never one of the first sixteen, which each terminal sets for itself.

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)