Announcement: The Bozochess Project

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Bozo's main transposition table

Post by sje »

In Pascal, a record structure may have a packed attribute which will tell the compiler to pack the record's components as much as possible. However, there is nothing in the language definition which says that the compiler actually has to implement the packed attribute. And the Free Pascal compiler does legally ignore the attribute, a fact I determined when coding Bozo's main transposition table. So the program has to revert to the old and clunky way of explicit bit field manipulation.

I installed the main transposition table code yesterday, although I have not yet fully implemented score/bound actions; the table at this point is used only for storing moves. But this is enough to test a lot of code and is helpful with move ordering.

Code: Select all

  const

    { Main transposition table items }

    ttmainslog = 16;               { Log2 of entry count of the main transposition table }
    ttmainslen = 1 shl ttmainslog; { Entry count of the main transposition table }
    ttmainmask = ttmainslen - 1;   { Index mask for the main transposition table }

Code: Select all

  type

    { Transposition table score interpretation mode }

    tsimtype =
      (
        tsimnone,  { Score is missing }
        tsimexact, { Score is exact }
        tsimlower, { Score is a lower bound }
        tsimupper  { Score is an upper bound }
      );

    { Main transposition table entry: flag data }

    { Bits 0 - 0: 0/Free, 1/In use }
    { Bits 1 - 1: 0/WTM, 1/BTM }
    { Bits 3 - 2: tsim }
    { Bits 7 - 4: Unused }

    { Main transposition table entry: move data }

    { Bits  5 -  0: From square }
    { Bits 11 -  6: To square }
    { Bits 14 - 12: msc }
    { Bits 15 - 15: Unused }

    { Main transposition table items }

    ttmainentrytype =
      record
        hash:     hashtype; { Entry signature (from hash and draft) }
        score:    svtype;   { Associated score or bound, if any }
        draft:    si8type;  { Draft of analysis }
        flagdata: ui8type;  { Packed flag data }
        movedata: ui16type  { Packed from-square, to-square, msc }
      end;

    ttmainindextype = 0..ttmainmask; { Main TT storage index }

    ttmainptrtype = ^ttmaintype; { Pointer to main TT storage }

    ttmaintype = array [ttmainindextype] of ttmainentrytype;  { Main TT storage }

Code: Select all

  { ***** Main transposition entry routines ***** }

  procedure TTMainEntryReset(var ttmainentry: ttmainentrytype);
  begin
    with ttmainentry do
      begin
        HashReset(hash);
        score := svbroken;
        draft := -128;
        flagdata := 0;
        movedata := 0
      end
  end; { TTMainEntryReset }

  { ***** Main transposition table routines ***** }

  procedure TTMainReset(var ttmain: ttmaintype);
    var
      ttmainindex: ttmainindextype;
  begin
    for ttmainindex := 0 to ttmainmask do
      TTMainEntryReset(ttmain[ttmainindex]);
  end; { TTMainReset }

  function TTMainNew: ttmainptrtype;
    var
      myresult: ttmainptrtype;
  begin
    New(myresult);
    TTMainReset(myresult^);
    TTMainNew := myresult
  end; { TTMainNew }

  procedure TTMainDispose(ttmainptr: ttmainptrtype);
  begin
    Dispose(ttmainptr)
  end; { TTMainDispose }

  procedure TTMainFetchHintMove(var ttmain: ttmaintype; var pos: postype; var move: movetype);
    var
      ttmainindex: ttmainindextype;
  begin
    ttmainindex := pos.mphc.bits and ttmainmask;
    with ttmain[ttmainindex] do
      if (hash.bits = pos.mphc.bits) and Odd(flagdata) and (((flagdata shr 1) and 1) = pos.good) then
        with move do
          begin
            frsq := movedata and 63;
            tosq := (movedata shr 6) and 63;
            frman := pos.board.sqv[frsq];
            toman := pos.board.sqv[tosq];
            msc := (movedata shr 12) and 7;
            mfset := [];
            sv := svbroken
          end
      else
        move := voidmove
  end; { TTMainFetchHintMove }

  procedure TTMainStashHintMove(var ttmain: ttmaintype; var pos: postype; var move: movetype);
    var
      ttmainindex: ttmainindextype;
  begin
    ttmainindex := pos.mphc.bits and ttmainmask;
    with ttmain[ttmainindex] do
      begin
        hash := pos.mphc;
        score := svbroken;
        draft := -128;
        flagdata := 1 or (pos.good shl 1);
        movedata := move.frsq or (move.tosq shl 6) or (move.msc shl 12)
      end
  end; { TTMainStashHintMove }