NAME

Game::Shogi::Terminal - the board on a terminal

SYNOPSIS

my $t = Game::Shogi::Terminal->new(level => 6000, side => 'b');
my $status = $t->start;          # RETURNS the exit status; never exits

Game::Shogi::Terminal->new(ascii => 1)->draw;

exit Game::Shogi::Terminal->run(@ARGV);    # what bin/shogi does

DESCRIPTION

Everything that knows about a screen, and nothing that knows about the rules. in and out default to STDIN and STDOUT, so a test can hand it a pair of in-memory handles and read back exactly what it drew.

start returns and never calls exit. Its return value is the exit status bin/shogi uses: 0 if you won, drew or quit, 1 if you lost.

The pieces

The board is drawn in kanji by default: 歩 香 桂 銀 金 角 飛, 玉 for Black's king and 王 for White's, and the promoted と 杏 圭 全 馬 龍. Where there is colour Black's pieces are red, as the side that moves first is in Xiangqi, and White's are blue, in the hands as on the board. Without colour a White piece has a v before it instead, as the Japanese text board (BOD) marks it. The characters are pinned by codepoint and t/19 checks each against its Unicode name.

ascii => 1 draws the SFEN tokens instead: P a Black pawn, p a White one, +R a Black dragon.

The board is drawn in fixed cells

A square is three columns and the gap between two squares one, so every row of the board is the same width whatever stands on it. The files run 9 to 1 across the top and the ranks a to i down the right side (一 to 九 with kanji_ranks). Playing White turns the board over.

The hands are drawn as a row above the board and a row below it, each piece once with its count after it when there is more than one, in the order R B G S N L P. The hand below is the side at the bottom.

The marks are characters and never colours

The cursor is [ ] round the square or the piece in hand it is on, the piece already chosen is ( ), a square that piece can reach is + (* in ASCII) when it is empty, and x on both sides when there is something to take there. A mark takes a gap, or the spare column in front of a piece, so it sits against the piece and never moves a column of the board.

The picker

With a terminal and Term::ReadKey, start offers the arrow keys instead of a typed move. The cursor walks the pieces that have a legal move and the kinds in your hand that have a drop, the hand being the row below the board. Enter or space picks one up; the cursor then walks the squares it can reach, and enter or space plays. When the move may either promote or not, a prompt asks promote? y or n; a move that must promote is played promoted. Escape puts the piece back.

The cursor only ever stops where a move is: both sets are the board's own legal moves. While the picker runs it is the only thing drawing a board.

d declares the impasse (the entering-king rule) and u and r take your last turn back and play it again.

METHODS

new

Game::Shogi::Terminal->new(in => $fh, out => $fh, game => $g, side => 'b',
                           ascii => 0, kanji_ranks => 0, colour => undef,
                           level => 6000, seed => 'mine');

level is the bot's node budget; left undefined, the seed draws a rung.

in

out

ascii

colour

keysource

pending

Read-write. NO_COLOR in the environment beats colour.

game

Read-write. The Game::Shogi being played.

level

seed

side

kanji_ranks

The bot's budget, the seed its tie-break is drawn from, the side the person plays ('b' or 'w'), and whether the ranks are kanji numerals.

keyboard

screen

history

The kit's Game::Terminal::Kit::Keys, Game::Terminal::Kit::Screen and Game::Terminal::Kit::History. The history keeps each of your turns as the game's to_text.

columns

Game::Shogi::Terminal->columns($text)

The display columns of a string: two for a wide character, colour codes ignored.

board_lines

my @lines = $t->board_lines(position => $board, flip => 1);

The board with both hands as a list of lines, printing nothing. Takes cursor, from and spots for the picker's marks.

draw

The same, printed, turned over when the person plays White.

start

Plays a game against the bot until somebody quits or the game ends, and returns the exit status.

pick_move

One turn of the picker: a USI move, or quit, undo, redo or declare.

origins

targets

choices

step

The picker's sets: the squares and hand kinds with a move, the squares one of them reaches, the moves from one to another (two when it may promote), and the cursor's next place in a set for a key.

piece_name

piece_line

move_line

The words under the board: what is under the cursor, and what a move does.

keys_available

raw

enter_raw

leave_raw

read_key

picking

rewind

The keyboard and the redraw, as the kit gives them.

person_turn

take_back

play_again

swap

Undo and redo: each of your turns is one step.

options

The options a launcher shows, each a hash reference with a name, a type, a help, and min and max or choices.

run

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

The command line: see bin/shogi. --usi hands the session to Game::Shogi::USI.

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)