NAME
Game::Merrills::Notation - moves, positions and whole games as text
VERSION
Version 0.03
SYNOPSIS
use Game::Merrills::Notation;
my $move = Game::Merrills::Notation::parse_move('d2-d3xa1');
# { from => 19, to => 16, remove => 21 }
Game::Merrills::Notation::format_move($move); # 'd2-d3xa1'
my $position = Game::Merrills::Notation::parse_position(
'W..........B............ w 8 8 0 2'
);
my $moves = Game::Merrills::Notation::parse_record("1. d2 f4\n2. d6");
DESCRIPTION
Three things are written down: a move, a position, and a game.
A move
Points are named by their coordinates, a1 to g7, as in Game::Merrills::Points.
d2 a man is placed on d2
d2-d3 the man on d2 moves to d3
d2xa1 a man is placed on d2, closes a mill and takes the man on a1
d2-d3xa1 the man on d2 moves to d3, closes a mill and takes a1
Case does not matter when reading, and spaces around the - and the x are forgiven. What is written is always lower case with no spaces.
A flying move is written like any other move. Whether a man flew is plain from the two points.
A position
One line of six fields, separated by spaces:
W..........B............ w 8 8 0 2
The 24 points in point order,
Wfor a white man,Bfor a black one and.for an empty point.The side to move,
worb.The men white has yet to place.
The men black has yet to place.
The plies played since a mill was last closed, which a draw is counted from.
The plies played in the game so far.
A position holds no history. A game begun from one has no earlier positions to repeat, so a count of repeated positions starts again from nothing.
A game
The moves in order, numbered in pairs, white's move and then black's:
1. d2 f4
2. d6 b4
3. d7
Reading takes the moves in the order they come and ignores the numbers and the line breaks.
A game that did not begin from the empty board says where it began, on a line of its own before the moves:
position WWW.BB..B..W....B..W.B.. w 4 4 0 10
1. d2 f4
A game played without flying says so on a line of its own before the moves, and a game with a draw offer standing, or ended by a resignation, a timeout or an agreed draw, says so on lines of their own after them. Each of the three is written only when it is so:
flying no
1. d2 f4
offer black
result white resign
The result names the winner, or draw, and the reason. Only the endings the moves cannot show are written; the rest come back from playing the moves.
A line that begins with # is a note and is passed over when reading.
FUNCTIONS
None is exported.
parse_move
Reads a move. Returns a hashref with to, and with from and remove when the move has them, each a point number. Returns undef for anything that is not a move, and never dies, so it can be handed whatever a player typed.
A move that names the same point twice is not a move. Whether a move is legal is not asked here.
my $move = Game::Merrills::Notation::parse_move('D2 - D3');
format_move
Writes a move from a hashref of from, to and remove. Dies when there is no to.
Game::Merrills::Notation::format_move({ to => 19 }); # 'd2'
format_position
Writes a position from a hashref of cells, turn, hand, no_mill and ply, the shape "parse_position" returns. The hand and the two counts are taken as 0 when left out. Dies when what it is given could not be a position.
my $text = Game::Merrills::Notation::format_position({
cells => \@cells,
turn => 'white',
hand => { white => 9, black => 9 },
});
parse_position
Reads a position. Returns a hashref of cells (24 values, 1 for white, -1 for black, 0 for empty), turn (white or black), hand (a hashref keyed by side), no_mill and ply. Dies, saying what is wrong, when the text is not a position or gives a side more than nine men.
my $position = Game::Merrills::Notation::parse_position($text);
format_record
Writes a game from an arrayref of moves. Each may be a string, a hashref as "parse_move" returns, or a Game::Merrills::Move. Dies, naming the move, when one of them is not a move. Give position for a game that began somewhere other than the empty board, flying as 0 for a game played without it, offer as the side whose draw offer stands, and result as an arrayref of the winner (undef for a draw) and the reason for a game ended by resign, timeout or agreement. Dies when one of those is not so.
my $text = Game::Merrills::Notation::format_record(\@moves);
my $text = Game::Merrills::Notation::format_record(\@moves, position => $start);
parse_record
Reads a game. Returns an arrayref of moves as "parse_move" returns them. A position line is passed over; "record_position" reads it. The flying, offer and result lines are passed over too; "record_state" reads them. Dies, naming the move by its place in the game, when one cannot be read.
my $moves = Game::Merrills::Notation::parse_record($text);
record_position
The position a written game began from, or undef when it names none and so began from the empty board. Dies when the position line is not a position.
my $position = Game::Merrills::Notation::record_position($text);
record_state
What a written game says beside its moves and its start, as a hashref with flying (1 or 0) when the game names it, offer (a side) when a draw offer stands, and result (an arrayref of the winner, undef for a draw, and the reason) when the game was resigned, timed out or agreed drawn. Dies, saying what is wrong, when one of those lines cannot be read or comes twice.
my $state = Game::Merrills::Notation::record_state($text);
PACKAGE VARIABLES
%CELL,%GLYPH-
The cell value of each board character, and the character of each value.
%TURN,%LETTER-
The side of each side letter, and the letter of each side.
%SIDE-
The two sides,
whiteandblack, each true.
AUTHOR
LNATION, <email at lnation.org>
LICENSE AND COPYRIGHT
This software is Copyright (c) 2026 by LNATION.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)