Mr Short likes to play chess. Mr Short is also a very traditional man. Hence, Mr Short is disturbed by the recent trend of using Algebraic notation in modern chess, and he would rather use Descriptive notation, like his father and his father's father before him.


To simplify this challenge, I chose not to deal with disambiguaties (as in, when two pieces can move to the same square, or can capture the same piece.) Also there is no dealing with en passant, promotion, or Castling.

Algebraic notation for the uninitiated

  • The board squares are numbered from a1 at the bottom left to h8 as the top right. The letters represent the files (columns) while the numbers represent the ranks (rows). The white King is placed in the beginning of the game at the square e1.
  • A move consists of the piece that moved + the destination square. For example, a King moving to e2 would be Ke2.
  • If the piece that had moved is a Pawn, the piece letter is omitted. For example, the starting move Pawn to e4 is written as e4.
  • If the move is a capture, then the x letter is inserted between the piece and the destination square. For example, a Queen capturing at f7 is annotated as Qxf7.
  • If the capturing piece is a Pawn, since it moves diagonally, the notation records the file the Pawn originated from. For example, when the Pawn at c4 captures a piece at d5, the move is annotated as cxd5.
  • Piece symbols are K for King, Q for Queen, B for Bishop, N for Knight, and R for Rook. Pawns have no symbols.
  • Other annotations include + for check, and # for checkmate. A Pawn moving to f7 and giving check is f7+. Note lack of space.

Descriptive notation for the uninitiated

  • The files are described by the piece that starts on it. For example, what would be the e file in Algebraic, becomes the King file, or, for short, K. The other files are marked by their side, then the piece. So file h is the King's Rook's file, or KR.
  • The ranks are numbered from the point of view of the moving player. What would be the fourth rank in Algebraic, is the fourth rank for white, but the fifth rank for black.
  • It follows that the square e4 is K4 for the white player and K5 for the black player. The square f7 is KB7 for the white player and KB2 for the black player.
  • A move is annotated by the piece moving, then a dash, then the target square. So a Pawn moving to K4 is P-K4. A Queen moving to KR5 is Q-KR5.
  • A capture is annotated by the capturing piece, then x, then the captured piece. Therefore a Bishop capturing a Pawn is BxP. Usually you need to mark which Pawn is being captured, but ignore this for sake of simplicity.
  • Piece symbols are K for King, Q for Queen, B for Bishop, Kt for Knight (note the different symbol), R for Rook, and P for Pawn.
  • Other annotations include ch for check and mate for checkmate. A Pawn moving to KB7 and giving check is P-KB7 ch. Note the space.


A string of algebraic notation moves, delineated by spaces. There are no move numbers. For example, the Fool's mate goes like this:

f3 e5 g4 Qh4#

Or the game Teed vs Delmar, from the same Wikipedia page:

d4 f5 Bg5 h6 Bf4 g5 Bg3 f4 e3 h5 Bd3 Rh6 Qxh5+ Rxh5 Bg6#

The Immortal game.

e4 e5 f4 exf4 Bc4 Qh4+ Kf1 b5 Bxb5 Nf6 Nf3 Qh6 d3 Nh5 Nh4 Qg5 Nf5 c6 g4 Nf6 Rg1 cxb5 h4 Qg6 h5 Qg5 Qf3 Ng8 Bxf4 Qf6 Nc3 Bc5 Nd5 Qxb2 Bd6 Bxg1 e5 Qxa1+ Ke2 Na6 Nxg7+ Kd8 Qf6+ Nxf6 Be7#

You may assume that input is always a valid game. All moves are in the correct order, and no extraneous data is present. No moves will include disambiguation.

For example, The Evergreen game despite being, obviously, a valid game, is not going to be input due to the 19th move, Rad1.

You may also assume that all input move lists start from the starting position.


A move list, with a similar format, in Descriptive notation.

For example, the Fool's mate:

P-KB3 P-K4 P-KKt4 Q-KR5 mate

Teed vs Delmar:

P-Q4 P-KB4 B-KKt5 P-KR3 B-KB4 P-KKt4 B-KKt3 P-KB5 P-K3 P-KR4 B-Q3 R-KR3 QxP ch RxQ B-KKt6 mate

The Immortal Game:

P-K4 P-K4 P-KB4 PxP B-QB4 Q-KR5 ch K-KB1 P-QKt4 BxP Kt-KB3 Kt-KB3 Q-KR3 P-Q3 Kt-KR4 Kt-KR4 Q-KKt4 Kt-KB5 P-QB3 P-KKt4 Kt-KB4 R-KKt1 PxB P-KR4 Q-KKt3 P-KR5 Q-KKt4 Q-KB3 Kt-KKt1 BxP Q-KB3 Kt-QB3 B-QB4 Kt-Q5 QxP B-Q6 BxR P-K5 QxR ch K-K2 Kt-QR3 KtxP ch K-Q1 Q-KB6 ch KtxQ B-K7 mate

This is not the simplest Descriptive notation possible, since sometimes you don't need to specify which Knight file was moved to (as in, Q-KKt4 could be written as Q-Kt4 since the move Q-QKt4 is impossible.) The move BxP is ambiguous (which pawn: should be BxQKtP), but Mr Short doesn't care about that too much.

You may consider these your test cases.

Note: I wrote these by hand. If you catch any glaring mistakes, please let me know.

Rules and Scoring

  • Standard rules apply : program with output to stdout, or function. Nothing to stderr. Standard loopholes are forbidden.
  • Please link to a site where we can test your code.
  • Code golf: shortest code wins.

In Conclusion

This is my first challenge, so I probably made some noobish errors. Feedback on the question (in the comments, obviously) is appreciated.

  • 3
    \$\begingroup\$ If you really want time to work out the kinks of your challenge and get feedback at the same time without any other issues, you can post it as a proposal in the sandbox. \$\endgroup\$
    – R. Kap
    Aug 5, 2016 at 0:23
  • \$\begingroup\$ Great first challenge \$\endgroup\$
    – edc65
    Aug 5, 2016 at 12:34
  • \$\begingroup\$ I thought descriptive notation would be e2-e4 and Ng1-f3 (for e4 and Nf3 respectively from starting position) \$\endgroup\$
    – ericw31415
    Nov 20, 2017 at 22:48
  • 3
    \$\begingroup\$ What about the reverse, converting Descriptive to Algebraic? It would be of great value with old books!! \$\endgroup\$ Jun 3, 2021 at 17:44
  • \$\begingroup\$ I think for the Immortal game, the move is Kt-KB4 instead of Kt-KB3. \$\endgroup\$
    – user100690
    Jun 4, 2021 at 16:20

2 Answers 2


Batch, 588 bytes

@echo off
for %%r in (a.R b.Kt c.B d.Q e.K f.B g.Kt h.R)do set %%~nr1=%%~xr&set %%~nr8=%%~xr
for %%r in (a b c d e f g h)do set %%r2=.P&set %%r7=.P
set s=
set a=
set m=%1
set c=
for %%r in (ch.+ mate.#) do if .%m:~-1%==%%~xr set c= %%~nr&set m=%m:~,-1%
set p=%m:~0,1%
for %%r in (a b c d e f g h)do if %p%==%%r set p=P
for %%r in (QR.a QKt.b QB.c Q.d K.e KB.f KKt.g KR.h)do if .%m:~-2,1%==%%~xr set d=-%%~nr%b%
if %m:~-3,1%==x call set d=x%%%m:~-2%:~1%%
set %m:~-2%=.%p:N=Kt%
set s=%s% %p:N=Kt%%d%%c%
if not "%1"=="" goto l

s is the output string. m is the current move (moves are taken as command-line parameters). a is the current player (0 for White, 7 for Black). b is the row as seen from the point of view of the current player. c is the ch or mate flag. p is the current piece. If there is no piece (i.e. a lowercase letter a-h) then P is substituted. (The N to Kt substitution is done later to save bytes.) The destination column is then looked up in a dictionary. However if the move is actually a capture then the destination becomes an x followed by the piece previously on that square. Either way the destination square is then set to the piece that just moved there. The moves are accumulated until there are no more parameters and then they are printed.

The variables a1...h8 are used to store the last seen piece. The . prefix is there because of the way I initialise the back row; it's hard to loop over two variables at once in Batch unless I'm allowed to begin one with a ..


JavaScript (Node.js), 473 bytes

(n,c=(X=>[...'abcdefgh'].map(a=>[...'12345678'].map(b=>X[a+b]=a<'c'|a>'f'?a<'b'|a>'g'?['R','Kt',...'BQKB','Kt','R'][--b]:'P':''))&&X)({}),g=s=>s?s=='N'?'Kt':s:'P')=>n.split` `.map((e,i)=>(Q=c[S=e.slice(I=e.search(/[a-h](?!x)/),I+2)],((c[S]=g(e.split(/[a-hx]/)[0]))+(e[Z='includes']`x`?'x'+Q:'-'+((S=e[I])>'d'?'K'+['','B','Kt','R']['efgh'.indexOf(S)]:'Q'+['R','Kt','B','']['abcd'.indexOf(S)])+((Y=e[e.search(/\d/)])&&i%2?9-Y:Y))))+(e[Z]`#`?' mate':e[Z]`+`?' ch':'')).join` `

Try it online!

Output is different to the testcase, but it seems like there is an error the OP made. Only 1 mistake, though.


Quite simple for such a long program. Creates an object, c, which stores the position of every piece. Handling captures is simple, simply overwrite the square. Inside the map function, we assign Q to the target square's piece before overwriting, then refer to it when a capture is seen. If not a capture, then index into an array to find the correct file (correct me if "file" is not the right term as I'm no expert in chess) and determine the number (9-Y if black turn, Y if white term). Also a few simple invocations of includes and a few extra ternaries add the chs and mates at the end.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.