NAME
Game::Durak::Terminal - a deal of durak at a terminal
VERSION
Version 0.01
SYNOPSIS
my $terminal = Game::Durak::Terminal->new(
seed => $thirty_two_bytes, level => 3, seat => 1,
);
my $result = $terminal->run;
DESCRIPTION
One screen and one line of input. The screen is the trump, the talon and the heap, the bout laid out as attack over answer, and your hand numbered from one; the input is a number, or t to take, d when you are done throwing in, x to exchange the trump six, r to give up and q to leave.
This is the second consumer the distribution exists for, and it is also the fastest way to find a rule that is wrong: three deals by hand against the top rung catch more than a suite does, because a suite only asks the questions somebody thought of.
Everything that prints lives here
No other module in the distribution writes to a handle, and t/18-silent.t is a grep that says so. A library that prints cannot be embedded, and a library that prints only on the paths nobody tested is worse.
out and in are attributes rather than STDOUT and STDIN, so the whole of this module can be driven by a test with two string handles.
One painted table, or a transcript
At a terminal the deal is a single table redrawn in place: Game::Durak::Table builds the screen and this module writes it at the top left. Through a pipe the same deal prints as plain lines, one position after another, because a screen redrawn in place makes a file that is unreadable and a test that can only be read by eye.
The choice follows -t unless paint says otherwise, and both paths go through the same loop and the same sentences.
A card is a letter and a glyph
name_of gives the ASCII pair and the glyph is decoration: --ascii turns the glyphs off for a terminal that has no font for them, and colour follows -t and NO_COLOR unless it is asked for either way.
METHODS
game, out, in, seed, level, seat, ascii, colour, paint, width, height
What the terminal was built with. seat is the seat you play, 1 or 2, and the other one is the bot. width and height are the painted screen's, and default to eighty by twenty-four.
open_screen, position, close_screen
The three moments of a deal: before the first move, at every position that is yours to answer, and after the last. Each one draws whichever way the terminal is running, so run has one loop rather than two.
table_of, frame, show
The Game::Durak::Table this terminal draws with, one screen from a view as a list of strings, and that screen written to the handle at the top left with the cursor left where the answer is typed.
A frame carries colour only when colour is on. The painted screen and the plain one are the same grid either way, which is what makes the whole of it assertable by a test with no terminal in it at all.
headline
The most recent things that happened, newest last, cut to the room the header bar has. It takes the LATEST lines that fit rather than the first, because a bout can produce four events at once and the one that matters is the last.
told
Says something to the player: a line at a time when the terminal is printing plain lines, and into the next frame's header when it is painting.
start
Builds the game from the seed and keeps it. Dies for a seed the engine refuses, because a terminal with no game is not a game.
run
Plays until the deal ends or the reader says so, and returns the result hashref, or undef when somebody quit.
table, hand_line, bout_line, card, card_suit
The screen, in pieces. Each takes what it needs and returns a string, so a test can assert what a person would see without running a deal.
playable
The positions in the hand that can be played right now, counting from one. A prompt that says "a card" and means four of the eleven is a prompt that gets answered wrong, so the numbers are listed rather than the range.
cards
$terminal->cards(1); # '1 card'
One card or several, because "1 cards" is what a first deal at the terminal found and it is the sort of thing nobody fixes later.
prompt_for, move_for
What the seat may do, as a line, and the move a line of input means, or undef when it means nothing. move_for only ever returns a move that is in the view's legal, which is why an illegal move at the terminal is a reprompt and not a refusal.
narration, narrate
What a list of events did, from one seat's side of the table, as a list of strings; and the same, printed. They are separate because the painted screen puts those strings in the header bar rather than printing them, and a sentence that only exists inside a print can be used by exactly one of the two.
say
Prints a line to out. The one place in the distribution that prints.
SEE ALSO
Game::Durak, Game::Durak::Bot.
AUTHOR
LNATION, <email@lnation.org>
LICENSE AND COPYRIGHT
This software is Copyright (c) 2026 by LNATION.
This is free software, licensed under the Artistic License 2.0.