NAME

Game::Snake::Terminal - snake in a terminal

VERSION

Version 0.13

SYNOPSIS

use Game::Snake::Terminal;

my $terminal = Game::Snake::Terminal->new(seed => 'anything');
my $result = $terminal->start;        # returns; never exits

exit Game::Snake::Terminal->run(@ARGV);   # which is all of bin/snake

DESCRIPTION

The playable game on two filehandles. It draws the board, reads the keys and ticks the engine; the rules are Game::Snake's and nothing here knows them. It is a separate module so the engine can be loaded by anything without pulling a terminal in.

Every other terminal game of this author's waits for a key. This one ticks. The one wait in the loop is a timed read of the keyboard: a key ends it early and is acted on, and the deadline passing is the tick. A tick that is late fires once and the schedule restarts, so a stalled machine never hands the snake a burst of moves (Game::Terminal::Kit::Ticker).

The keys need Term::ReadKey, which is recommended and not required. Without it, or without a terminal, the game cannot be played by hand and says so; --watch still works anywhere because it reads nothing.

PROPERTIES

Every one may be given to new; those marked read-write may be set after.

in, out

The handles, read-write, defaulting to STDIN and STDOUT.

cols, rows

The board. Left out, the board is fitted to the window, at most 40 by 28.

seed

The game. Left out, a fresh one is made.

level, watch

The bot's level (1 or 2) and whether it, not you, steers.

quiet, ascii

Draw no frames; use plain characters instead of block glyphs.

ansi, interactive

Given to new only. ansi forces colour on or off, and NO_COLOR in the environment beats it. interactive forces the redrawn-in-place frame on or off; the default follows whether out is a terminal.

max_ticks

Stop the game after that many ticks; 0, the default, plays to the end.

game, ticker

The Game::Snake being played and its Game::Terminal::Kit::Ticker, built in new unless given.

keysource, clock, sleeper, width, height

For tests. keysource is a code reference called with the seconds to wait that returns one character, or undefined when none came in time; clock returns seconds; sleeper is called with seconds to wait when there is nothing to read; width and height stand in for the window's size.

pending

Characters to be read before any others, an array reference.

keyboard, screen

The Game::Terminal::Kit::Keys the keys are read through and the Game::Terminal::Kit::Screen the frames are drawn through, built in new from the handles unless given.

frames, refused, stopped, refusal

After start: frames drawn, turns refused, how it stopped (empty, quit, capped, narrow or keys) and the sentence saying why it could not start.

METHODS

start

Plays the game and returns its Game::Snake::Result, or undefined when it could not start (the window too narrow, or no way to read keys), with refusal saying why. Never calls exit.

options

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

level

A whole number from 1 to 2: the bot's level, for watch.

watch

A switch: watch the bot play.

rows

A whole number from 8 to 28: the board; the default fits the window.

cols

A whole number from 8 to 40: the board; the default fits the window.

seed

Text: the same seed and the same moves are the same game.

run

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

The program. Parses the options, plays, and returns the exit status: 0 when a game ended or was quit, 2 for a bad option or a game that could not start. --help goes to STDOUT; the usage after a bad option, and every refusal, to STDERR.

too_narrow

The sentence to print when the window cannot hold the board, or undefined.

cannot_play

The sentence for a game with no way to read keys.

keys_available, enter_raw, leave_raw, raw

Whether keys can be read; reading a key at a time, giving the terminal back with its cursor, and whether a key at a time is how it is being read now.

read_key

my $key = $terminal->read_key($seconds);

One key by name (up, enter, q, ...) within the wait, or undefined. Undefined seconds block; zero polls. The names are Game::Terminal::Kit::Keys's.

board_lines, frame_lines, status_line, legend

The board as lines, the whole frame, and its two text lines.

ansi, interactive

Whether colour and in-place redrawing are on.

usage

The usage text.

AUTHOR

LNATION, <email at lnation.org>

LICENSE AND COPYRIGHT

This software is Copyright (c) 2024 by LNATION.

This is free software, licensed under:

The Artistic License 2.0 (GPL Compatible)