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
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)