{ cv_gtc_gsv_bug.pas -- a minimal demonstration of a genuine,
  reproducible bug in the original 1994 SAN Kit source: the
  cv_gtc_gsv[] table (sanint.c) maps checkmate the wrong way round.
  Pascal translation of cv_gtc_gsv_bug.c.

    cv_gtc_gsv[gs_wcmt] = gtc_wwin;   // WRONG
    cv_gtc_gsv[gs_bcmt] = gtc_bwin;   // WRONG

  gs_wcmt means "White is checkmated" -- so Black wins -- yet it is
  mapped to gtc_wwin, "White win". gs_bcmt is wrong the same way, in
  the opposite direction.

  This program plays out the two shortest possible checkmates from
  the starting position and prints, side by side, the game's actual
  winner (ordinary chess knowledge, not computed) against what the
  library's own table says. It relies on nothing from the SAN Kit
  except SANStatus() itself (to identify which side got mated) --
  the interpretation of the result is the whole point at issue. }

program cv_gtc_gsv_bug;

uses
  SanKit;

{ copy a Pascal string into a TSanBuf, truncated to sanL - 1
  characters and nul-terminated -- see 03_san_notation.pas }
procedure PascalToSanBuf(const s: string; var buf: TSanBuf);
var
  i, n: Integer;
begin
  FillChar(buf, SizeOf(buf), 0);
  n := Length(s);
  if n > sanL - 1 then
    n := sanL - 1;
  for i := 1 to n do
    buf[i - 1] := s[i];
end;

procedure Play(const san: string);
var
  buf: TSanBuf;
  mptr: PMove;
begin
  PascalToSanBuf(san, buf);
  mptr := SANDecodeAux(SanBufPtr(buf));
  if mptr = nil then
    WriteLn(ErrOutput, 'not a legal move: ', san)
  else
    SANPlayMove(mptr);
end;

procedure Demonstrate(const title: string; const moves: array of string;
                       const correctResult: string);
var
  i, gs: Integer;
begin
  SANInit;
  optnv[optn_nabd] := 1;
  optnv[optn_namd] := 1;

  for i := 0 to High(moves) do
    Play(moves[i]);

  gs := SANStatus;

  WriteLn(title);
  WriteLn('  actual winner (ordinary chess rules): ', correctResult);
  Write('  SANStatus() correctly identifies: ');
  if gs = gs_wcmt then
    WriteLn('gs_wcmt (White is checkmated)')
  else if gs = gs_bcmt then
    WriteLn('gs_bcmt (Black is checkmated)')
  else
    WriteLn('neither -- something is wrong with this example');
  WriteLn('  but the library''s own table, gtcstrv[cv_gtc_gsv[gs]], ',
          'says: "', gtcstrv[cv_gtc_gsv[gs]], '"');
  WriteLn;
end;

begin
  Demonstrate('Fool''s mate: 1.f3 e5 2.g4 Qh4# -- Black delivers mate.',
              ['f3', 'e5', 'g4', 'Qh4'],
              '0-1 (Black wins)');

  Demonstrate('Scholar''s mate: 1.e4 e5 2.Bc4 Nc6 3.Qh5 Nf6 4.Qxf7# -- ' +
              'White delivers mate.',
              ['e4', 'e5', 'Bc4', 'Nc6', 'Qh5', 'Nf6', 'Qxf7'],
              '1-0 (White wins)');
end.
