NAME

Game::Go::Notation - the two coordinate alphabets, and the gap between them

VERSION

Version 0.01

SYNOPSIS

use Game::Go::Notation;

Game::Go::Notation::to_human(19, 3, 15);    # 'D4'
Game::Go::Notation::from_human(19, 'D4');   # (3, 15)

Game::Go::Notation::to_sgf(19, 3, 15);      # 'dp'
Game::Go::Notation::from_sgf(19, 'dp');     # (3, 15)

DESCRIPTION

Two alphabets for one board, and they are not the same alphabet.

Human notation

What a board edge, a book, a tournament sheet and this distribution's terminal print. Columns are A to T with I omitted:

A B C D E F G H J K L M N O P Q R S T

and rows are numbered from the bottom, so D4 is four up from the bottom edge.

I is skipped because on a printed board it is indistinguishable from J and from the digit 1, and every source in the game skips it.

SGF notation

Two lowercase letters, skipping nothing, with the row counted from the top. From the SGF FF[4] Go specification:

In Go the Stone becomes Point and the Move and Point type are the same: two
lowercase letters.

The first letter designates the column (left to right), the second the row
(top to bottom). The upper left part of the board is used for smaller
boards, e.g. letters "a"-"m" for 13*13.

The trap

On a 19x19 board:

              human    SGF     column index
top left       A19      aa          0
bottom left    A1       as          0
the trap       J10      --          8
the trap       --       jj          9

J10 and jj are one column apart. Both read as "the tenth column, row ten" to somebody not paying attention, and they are different points. That is a silent off-by-one over a third of the board.

So there is no function here that converts between the two alphabets. Everything goes through a column and row pair, where the difference has to be dealt with rather than assumed away.

FUNCTIONS

Every one takes the board size first, because neither alphabet means anything without it: the row origin depends on it in human notation, and the bounds depend on it in both.

to_human, from_human

to_human($size, $col, $row)     # 'D4', or undef off the board
from_human($size, 'D4')         # ($col, $row), or the empty list

to_sgf, from_sgf

to_sgf($size, $col, $row)       # 'dp', or undef off the board
from_sgf($size, 'dp')           # ($col, $row), or the empty list

from_sgf refuses the empty string and tt, which are passes rather than points. Game::Go::SGF is the thing that knows a pass is a move.

col_letter, letter_col

One human column letter to and from its index, I skipped.

transcript

A game's moves as human coordinates, one per move, passes included.

For a log page and for a person reading a diff, never for a replay: a replay hands each event back to the method that made it, and that takes a point.

SEE ALSO

Game::Go::SGF, Game::Go.

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)