{ 12_hashing.pas -- position hashing.
  Pascal translation of ../examples/12_hashing.c.

  Functions demonstrated:
    SANHashCreate() -- recompute the current position's hash
                       address/signature from scratch
    curr_e.e_mhca / curr_e.e_mhcs -- the position's hash address and
                       signature, normally maintained *incrementally*
                       (updated move by move) rather than recomputed }

program hashing;

uses
  SanKit,
  SysUtils;

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 text: string);
var
  buf: TSanBuf;
  mptr: PMove;
begin
  PascalToSanBuf(text, buf);
  mptr := SANDecodeAux(SanBufPtr(buf));
  SANPlayMove(mptr);
end;

var
  incrementalAddress, incrementalSignature: Int64;

begin
  SANInit;
  optnv[optn_nabd] := 1;
  optnv[optn_namd] := 1;

  Play('d4'); Play('Nf6'); Play('c4'); Play('g6');
  Play('Nc3'); Play('Bg7'); Play('e4'); Play('d6');

  incrementalAddress := curr_e.e_mhca;
  incrementalSignature := curr_e.e_mhcs;

  WriteLn('Incrementally maintained hash:');
  WriteLn('  address:   ', LowerCase(IntToHex(incrementalAddress, 8)));
  WriteLn('  signature: ', LowerCase(IntToHex(incrementalSignature, 8)));

  SANHashCreate;

  WriteLn('Freshly recomputed from the board:');
  WriteLn('  address:   ', LowerCase(IntToHex(curr_e.e_mhca, 8)));
  WriteLn('  signature: ', LowerCase(IntToHex(curr_e.e_mhcs, 8)));

  WriteLn;
  if (incrementalAddress = curr_e.e_mhca) and
     (incrementalSignature = curr_e.e_mhcs) then
    WriteLn('They match: yes')
  else
    WriteLn('They match: no');
end.
