%
% chess.sty
% ---------
% Style for writing about chess games
% Author : Piet Tutelaers (UUCP: rcpt@urc.tue.nl)
% Version: 1.1 (17 Nov 1990)
%    Improvements over version 1.0:
%     -TeX code cleaned up (thanks to TeX-wizzard Victor Eijkhout)
%     -moving a King does not generate a castling move when this 
%      King already moved
%     -renamed internal macro `\\' because LaTeX uses that
%     -better hooks for foreign languages (look for lines marked with
%      %%FOREIGN%%)
%    Torture test:
%      If you change something in the chess.sty style check if everything 
%      else is still working with torture-test.ltx (LaTeX) or 
%      torture-test.tex (plain TeX).
%    Known problems:
%     -The analysis mode can not be used within arguments of macros
%         not: \centerline{|21.N5*f3|}	but: |\centerline{21.N5*f3}|
% Version: 1.0 (5 Jan 1990)
%

\def\@set[#1#2](#3){%arguments: [a-h1-8](<letter>)
    \expandafter\xdef\csname#1#2\endcsname{#3}}

\def\@get#1[#2#3]{%arguments:\cs[a-h1-8]
    \edef#1{\csname#2#3\endcsname}}

\font\Chess=chess20

\newcount\@c % column
\newcount\@r % row
\newcount\@sum % row+column

\def\@col{\ifcase\@c\or a\or b\or c\or d\or e\or f\or g\or h\fi}

\def\@showchar{
   \@get\piece[\@col\the\@r]
   \if\piece E \ifodd\@sum 0\else Z\fi\else
   \if\piece P \ifodd\@sum P\else O\fi\else
   \if\piece p \ifodd\@sum p\else o\fi\else
   \if\piece R \ifodd\@sum R\else S\fi\else
   \if\piece B \ifodd\@sum B\else A\fi\else
   \if\piece N \ifodd\@sum N\else M\fi\else
   \if\piece r \ifodd\@sum r\else s\fi\else
   \if\piece b \ifodd\@sum b\else a\fi\else
   \if\piece n \ifodd\@sum n\else m\fi\else
   \if\piece K \ifodd\@sum K\else J\fi\else
   \if\piece Q \ifodd\@sum Q\else L\fi\else
   \if\piece k \ifodd\@sum k\else j\fi\else
   \if\piece q \ifodd\@sum q\else l\fi\else
   \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}

\def\@showrow#1{
   \@r=#1\@c=1
   \@sum=\@r\advance\@sum by\@c
   \loop
      \@showchar
      \ifnum\@c<8 \advance\@c by1\advance\@sum by1
   \repeat
}

\def\showboard{
\vbox{\offinterlineskip
   \hrule height1pt
   \hbox{\vrule width1pt\Chess
         \vbox{\hbox{\@showrow8}
               \hbox{\@showrow7}
               \hbox{\@showrow6}
               \hbox{\@showrow5}
               \hbox{\@showrow4}
               \hbox{\@showrow3}
               \hbox{\@showrow2}
               \hbox{\@showrow1}}%
         \vrule width1pt}
   \hrule height1pt}
}

% inner loop needs extra { ... }

\def\@emptyboard{
   \@r=1
   \loop
      {\@c=1
       \loop
         \@set[\@col\the\@r](E)
         \ifnum\@c<8 \advance\@c by1
       \repeat}
       \ifnum\@r<8 \advance\@r by 1
   \repeat
}

\def\@initboard{
% empty squares
   \@r=3
   \loop
     {\@c=1
      \loop
         \@set[\@col\the\@r](E)
         \ifnum\@c<8 \advance\@c by1
      \repeat}
      \ifnum\@r<6 \advance\@r by 1
   \repeat
% pawns
   \@c=1
   \loop
      \@set[\@col2](P)\@set[\@col7](p)
      \ifnum\@c<8 \advance\@c by1
   \repeat
% pieces
   \@set[a1](R)\@set[h1](R)
   \@set[a8](r)\@set[h8](r)
   \@set[b1](N)\@set[g1](N)
   \@set[b8](n)\@set[g8](n)
   \@set[c1](B)\@set[f1](B)
   \@set[c8](b)\@set[f8](b)
   \@set[d1](Q)\@set[e1](K)
   \@set[d8](q)\@set[e8](k)
}

%
% The next part defines a user friendly notation for chess moves. 
% Moves works only in chess-environment: \begin{chess} ... \end{chess}
% in LaTeX, or \chess ... \endchess in plain TeX.
% Some examples:  |21. Nf3-e5, Ke8*f8 22. 0-0-0+, Bh8*a1|
%              :  |21.: Ke8*f8 22. Bh8*a1, 0-0|
%              :  |21 Nfe5 K*f8 22 0-0-0! B*a1|
%              :  |21: K*f8 22 B*a1 0-0|
%

\font\Fig=chessfig10

\gdef\@king{{\Fig K}}
\gdef\@queen{{\Fig Q}}
\gdef\@rook{{\Fig R}}
\gdef\@bishop{{\Fig B}}
\gdef\@knight{{\Fig N}}
\gdef\@dash{--}
\gdef\@capt{$\times$}
\gdef\@dots{~$\ldots$,}
\gdef\@dot{\char46}

%%FOREIGN%% change the following character codes to your language of coice
%% English              % English % Dutch   % German   % French   ....
\chardef\king@=`K	% King	  % Koning  % K"onig   % Roi
\chardef\queen@=`Q	% Queen   % Dame    % Dame     % Dame
\chardef\rook@=`R	% Rook    % Toren   % Turm     % Tour
\chardef\bishop@=`B	% Bishop  % Loper   % L"aufer  % Fou
\chardef\knight@=`N	% kNight  % Paard   % Springer % Cavalier
%%FOREIGN%% end

\catcode`|=\active
{\catcode`:=\active\catcode`.=\active\catcode`*=\active\catcode`-=\active
 \catcode\king@=\active\catcode\queen@=\active\catcode\rook@=\active
 \catcode\bishop@=\active\catcode\knight@=\active
 \gdef\@notation{\begingroup\let|=\endgroup
     \catcode`:=\active\catcode`.=\active\catcode`*=\active\catcode`-=\active
     \catcode\king@=\active\catcode\queen@=\active\catcode\rook@=\active
     \catcode\bishop@=\active\catcode\knight@=\active
%%FOREIGN%% choose the same characters as above
     \letK=\@king\letQ=\@queen\letR=\@rook\letB=\@bishop\letN=\@knight
%%Dutch \letK=\@king\letD=\@queen\letT=\@rook\letL=\@bishop\letP=\@knight
%%German\letK=\@king\letD=\@queen\letT=\@rook\letL=\@bishop\letS=\@knight
%%French\letR=\@king\letD=\@queen\letT=\@rook\letF=\@bishop\letC=\@knight
%%FOREIGN%% that's all
     \let-=\@dash\let*=\@capt\let:=\@dots\let.=\@dot
   }
%
% Provide a chess environment in which the `|' character is active, because
% the `|' is used by LaTeX in the `tabular' environment!
%
 \gdef\chess{\catcode`|=\active\let|=\@notation}
 \global\let\endchess\relax
}
\catcode`|=12

%
% Next part provides a ply (half move) generator
%

\newif\ifWhite     \newif\ifFigure    \newif\ifcapture

%
% next newif's needed for castling
%
\newif\ifKnotmoved \newif\ifknotmoved
\newif\ifcastling  \newif\ifoo

%
% Globals for special pawn moves (en passant capture and promotion)
%

\newif\ifenpassant \newif\ifpromotion

\def\@color#1{ %  Color of a piece     0: none, -1: black, 1: white
   \if #1E0\else
   \ifnum`#1=\uccode`#11\else-1\fi\fi}

%
% No checking is done for validity of moves, only legal moves behave well!!
%

\def\@ply#1#2#3#4#5 {% Syntax: [a-h][1-8][a-h][1-8]{QRBN}
   \@get\piece[#1#2]\@get\capture[#3#4]\Figuretrue
   \if\capture E\capturefalse\else\capturetrue\fi
   \ifWhite
      \if\piece P\Figurefalse
         \if#46
             \if\eprow#3\capturetrue\enpassanttrue\fi
             \xdef\eprow{x}
         \else
            \xdef\eprow{x}
            \if#22
               \if#44\xdef\eprow{#3}\fi
            \else
               \if#48\promotiontrue\fi
            \fi
         \fi
      \else
         \if\piece K% check for possible castling
            \ifKnotmoved
               \if#3g\if#41\castlingtrue\ootrue\fi
               \else\if#3c\if#41\castlingtrue\oofalse\fi\fi
               \fi
               \global\Knotmovedfalse
            \fi
         \fi
      \fi
      \ifcastling
          \@set[#1#2](E)\@set[#3#4](K)
          \ifoo 0\@dash0#5\@set[f1](R)\@set[h1](E)
          \else 0\@dash0\@dash0#5\@set[d1](R)\@set[a1](E)\fi
          \castlingfalse
      \else
          \ifFigure{\Fig\piece}\fi
            #1#2\ifcapture\@capt\else\@dash\fi#3#4
            \ifpromotion{\Fig#5}\else#5\fi
          \@set[#1#2](E)
          \ifpromotion\@set[#3#4](#5)\else\@set[#3#4](\piece)\fi
          \ifenpassant\@set[#3#2](E)\enpassantfalse\fi
      \fi
      \global\Whitefalse
   \else
      \if\piece p\Figurefalse
         \if#43
             \if\eprow#3\capturetrue\enpassanttrue\fi
             \xdef\eprow{x}
         \else
            \xdef\eprow{x}
            \if#27
               \if#45\xdef\eprow{#3}\fi
            \else
               \if#41\promotiontrue\fi
            \fi
         \fi
      \else
         \if\piece k
            \ifknotmoved
               \if#3g\if#48\castlingtrue\ootrue\fi
               \else\if#3c\if#48\castlingtrue\oofalse\fi\fi
               \fi
               \global\knotmovedfalse
            \fi
         \fi
      \fi
      \ifcastling
          \@set[#1#2](E)\@set[#3#4](k)
          \ifoo 0\@dash0#5\@set[f8](r)\@set[h8](E)
          \else 0\@dash0\@dash0#5\@set[d8](r)\@set[a8](E)\fi
          \castlingfalse
      \else
          \ifFigure{\Fig\if\piece rR\else\if\piece bB\else\if\piece nN\else
                        \if\piece qQ\else K\fi\fi\fi\fi}\fi%
            #1#2\ifcapture\@capt\else\@dash\fi#3#4
            \ifpromotion{\Fig#5}\else#5\fi
          \@set[#1#2](E)\ifpromotion\@set[#3#4](#5)\else\@set[#3#4](\piece)\fi
          \ifenpassant\@set[#3#2](E)\enpassantfalse\fi
      \fi
      \global\Whitetrue
   \fi
}

\newcount\movecount \movecount=0

\def\move#1 #2 {\frenchspacing
    \ifWhite\advance\movecount by 1\fi
    \hskip1cm\llap{\the\movecount.}\hskip.5cm
    \hbox to 2.3cm{\hfil\@ply#1 \hfil}\hskip.5cm
    \hbox to 2.3cm{\hfil\@ply#2 \hfil}
    \par}

\def\ply#1 {\frenchspacing
    \ifWhite\advance\movecount by 1
       \hskip1cm\llap{\the\movecount.}\hskip.5cm
       \hbox to 2.3cm{\hfil\@ply#1 \hfil}
    \else\hskip1cm\llap{\the\movecount.}\hskip.5cm
       \hbox to 2.3cm{\hfil$\ldots$\hfil}\hskip.5cm
       \hbox to 2.3cm{\hfil\@ply#1 \hfil}
    \fi\par}

\def\newgame{\movecount=0 \@initboard
    \Whitetrue\castlingfalse
    \Knotmovedtrue\knotmovedtrue
    \promotionfalse\enpassantfalse}

\def\@dolist{\afterassignment\@dodolist\let\@next= } % Answer 11.5 TeXbook
\def\@dodolist{\ifx\@next\@endlist \let\@next\relax  % adapted to generate
  \else \@nextitem\let\@next\@dolist \fi             % chess diagrams
  \@next}

\def\@endlist{\@endlist}

\def\@nextitem{%
       \if\@next\space\@set[\@col\the\@r](E)\else
       \if\@next *    \@set[\@col\the\@r](E)\else
       \if\@next P    \@set[\@col\the\@r](P)\else
       \if\@next p    \@set[\@col\the\@r](p)\else
       \if\@next R    \@set[\@col\the\@r](R)\else
       \if\@next r    \@set[\@col\the\@r](r)\else
       \if\@next B    \@set[\@col\the\@r](B)\else
       \if\@next b    \@set[\@col\the\@r](b)\else
       \if\@next N    \@set[\@col\the\@r](N)\else
       \if\@next n    \@set[\@col\the\@r](n)\else
       \if\@next K    \@set[\@col\the\@r](K)\else
       \if\@next k    \@set[\@col\the\@r](k)\else
       \if\@next Q    \@set[\@col\the\@r](Q)\else
       \if\@next q    \@set[\@col\the\@r](q)\else
       \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
       \advance\@c by1}

\def\@initrow#1#2{\@r=#1\@c=1\@dolist#2\@endlist}

%
% For setting up a position
%
\def\board#1#2#3#4#5#6#7#8{
	\@initrow8{#1}
	\@initrow7{#2}
	\@initrow6{#3}
	\@initrow5{#4}
	\@initrow4{#5}
	\@initrow3{#6}
	\@initrow2{#7}
	\@initrow1{#8}}

%
% Next macros for defining chess position (thanks to Victor Eijkhout)
%
\def\White(#1){\def\match{xxx}\xWhite#1,xxx,}
\def\xWhite#1,{\def\temp{#1}
  \ifx\temp\match \else \WhitePieceOrPawn#1XY \expandafter\xWhite \fi}
\def\WhitePieceOrPawn#1#2#3#4Y{%
  \if#3X \@set[#1#2](P)
  \else\ifnum`#1=\king@	 \@set[#2#3](K)\else % King
       \ifnum`#1=\queen@ \@set[#2#3](Q)\else % Queen
       \ifnum`#1=\rook@	 \@set[#2#3](R)\else % Rook
       \ifnum`#1=\bishop@\@set[#2#3](B)\else % Bishop
       \ifnum`#1=\knight@\@set[#2#3](N)\else % kNight
       \fi\fi\fi\fi\fi
  \fi}

\def\Black(#1){\def\match{xxx}\xBlack#1,xxx,}
\def\xBlack#1,{\def\temp{#1}
  \ifx\temp\match \else \BlackPieceOrPawn#1XY \expandafter\xBlack \fi}
\def\BlackPieceOrPawn#1#2#3#4Y{
  \if#3X\@set[#1#2](p)
  \else\ifnum`#1=\king@  \@set[#2#3](k)\else % King
       \ifnum`#1=\queen@ \@set[#2#3](q)\else % Queen
       \ifnum`#1=\rook@  \@set[#2#3](r)\else % Rook
       \ifnum`#1=\bishop@\@set[#2#3](b)\else % Bishop
       \ifnum`#1=\knight@\@set[#2#3](n)\else % kNight
       \fi\fi\fi\fi\fi
  \fi}

\def\position{\begingroup%
    \@emptyboard\movecount=0
    \global\Whitetrue\global\castlingfalse
    \global\Knotmovedtrue\global\knotmovedtrue
    \global\promotionfalse\global\enpassantfalse}
\def\endposition{\endgroup}

