
// sort.cpp

// includes

#include "attack.h"
#include "board.h"
#include "colour.h"
#include "list.h"
#include "move.h"
#include "move_check.h"
#include "move_evasion.h"
#include "move_gen.h"
#include "move_legal.h"
#include "piece.h"
#include "search.h"
#include "see.h"
#include "sort.h"
#include "util.h"
#include "value.h"

#include "YBWCManager.h"
extern YBWCManager* g_pYBWCManagerInstance;

// constants

// kh 02.06.08 Thomas Gaksch 14b5c
//#define MAX(X, Y)  ((X) > (Y) ? (X) : (Y)) // kh 10.04.07 Thomas Gaksch

//static const int KillerNb = 2;

/*
static const int HistorySize = 9*9*12*64*64; // kh 10.04.07 Thomas Gaksch
// static const int HistorySize = 12 * 64;
static const int HistoryMax = 16384;
*/

static const int TransScore   = +32766;
static const int GoodScore    =  +4000;
static const int KillerScore  =     +4;
static const int HistoryScore = -24000;
static const int BadScore     = -28000;

static const int CODE_SIZE = 256;

// macros

#define HISTORY_INC(depth) ((depth)*(depth))

// kh 02.06.08 Thomas Gaksch 14b5c
//#define MIN(X, Y)  ((X) < (Y) ? (X) : (Y)) // kh 10.04.07 Thomas Gaksch

// types

enum gen_t {
   GEN_ERROR,
   GEN_LEGAL_EVASION,
   GEN_TRANS,
   GEN_GOOD_CAPTURE,
   GEN_BAD_CAPTURE,
   GEN_KILLER,
   GEN_QUIET,
   GEN_EVASION_QS,
   GEN_CAPTURE_QS,
   GEN_CHECK_QS,
   GEN_END
};

enum test_t {
   TEST_ERROR,
   TEST_NONE,
   TEST_LEGAL,
   TEST_TRANS_KILLER,
   TEST_GOOD_CAPTURE,
   TEST_BAD_CAPTURE,
   TEST_KILLER,
   TEST_QUIET,
   TEST_CAPTURE_QS,
   TEST_CHECK_QS
};

// variables

static int PosLegalEvasion;
static int PosSEE;

static int PosEvasionQS;
static int PosCheckQS;
static int PosCaptureQS;

static int Code[CODE_SIZE];

// static uint16 Killer[HeightMax][KillerNb];

/*
static uint16 History[HistorySize];
static uint16 HistHit[HistorySize];
static uint16 HistTot[HistorySize];
*/

History* gpHistory = NULL; 

// prototypes

static void note_captures     (list_t * list, const board_t * board);

// kh 02.06.08 Thomas Gaksch 14b5c
static void note_quiet_moves  (list_t * list, const board_t * board); // kh 10.04.07 Thomas Gaksch

static void note_moves_simple (list_t * list, const board_t * board);
static void note_mvv_lva      (list_t * list, const board_t * board);

static int  move_value        (int move, const board_t * board, int height, int trans_killer);
static int  capture_value     (int move, const board_t * board);

// kh 02.06.08 Thomas Gaksch 14b5c
static int  quiet_move_value  (int move, const board_t * board); // kh 10.04.07 Thomas Gaksch

static int  move_value_simple (int move, const board_t * board);

//static int  history_prob      (int move, const board_t * board, int height); // kh 10.04.07 Thomas Gaksch

static bool capture_is_good   (int move, const board_t * board);

static int  mvv_lva           (int move, const board_t * board);

// kh 02.06.08 Thomas Gaksch 14b5c
  static uint16 history_index  (int move, const board_t * board);
//static uint32 history_index  (int move, const board_t * board, int height); // kh 10.04.07 Thomas Gaksch

// functions

void history_alloc (History** ppHistory)
{
  if(g_pYBWCManagerInstance->pFruitConfiguration->bUseSharedMemoryHistoryTable)
  {
    if(g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess)
    {
      ASSERT(!g_pYBWCManagerInstance->pCriticalSectionHistoryTable);

      g_pYBWCManagerInstance->pCriticalSectionHistoryTable = 
        CriticalSection_Construct((CriticalSection*)malloc(sizeof(CriticalSection)), CRITICAL_SECTION_NAME_HISTORY_TABLE); 
    }

    (*ppHistory) = (History*)YBWCManager_InitSharedMem(g_pYBWCManagerInstance, 
                                                       SHARED_MEMORY_KEY_HISTORY_TABLE,
                                                       sizeof(History));
  } // if(g_pYBWCManagerInstance->pFruitConfiguration->bUseSharedMemoryHistoryTable)
  else
  {
    (*ppHistory) = (History*)my_malloc(sizeof(History));
  } // !if(g_pYBWCManagerInstance->pFruitConfiguration->bUseSharedMemoryHistoryTable)
}

void history_free (History* pHistory)
{
  if(g_pYBWCManagerInstance->pFruitConfiguration->bUseSharedMemoryHistoryTable)
  {

    // kh 14.02.08 shared memory free is explicitly handled

  } // if(g_pYBWCManagerInstance->pFruitConfiguration->bUseSharedMemoryHistoryTable)
  else
  {
    my_free(pHistory); 
  } // !if(g_pYBWCManagerInstance->pFruitConfiguration->bUseSharedMemoryHistoryTable)
}


// sort_init()

void sort_init() 
{
  int i;
  int height;

  int pos;

  // killer

  for(height = 0; height < HeightMax; height++) 
  {
    for(i = 0; i < KillerNb; i++) 
    {
      Killer[height][i] = MoveNone;
    }
  }

  // history

// kh 08.02.07
  if(    g_pYBWCManagerInstance->bRootMaster
      || g_pYBWCManagerInstance->bSyncPositionHistoryTableFirst
    )
  {

// kh 21.02.07 bSyncPositionHistoryTableFirst not used here anymore, see also fruit_actions_for_sync_position_received(... 
    ASSERT(g_pYBWCManagerInstance->bRootMaster || !g_pYBWCManagerInstance->bSyncPositionHistoryTableFirst);

// kh 08.02.07 as a future expansion this could be done more synchronized, e.g. waiting first for all non root master
// acknowledging their fruit_actions_for_sync_position_received (analogous to acknowledging 
// their fruit_actions_for_new_game_received) 
// the hashtablemasters of all non root master can clear the table once in fruit_actions_for_sync_position_received 
// and when all acks are received the root master can clear the history table (he is implicit the hashtable master)
// at the moment "in the startup phase" (e.g. after a uci go from the gui) the history table will be cleared a little bit
// too often and some useful information already contained in the table will be cleared also
    g_pYBWCManagerInstance->bSyncPositionHistoryTableFirst = FALSE;

    if(g_pYBWCManagerInstance->pFruitConfiguration->bUseSharedMemoryHistoryTable)
    {
      if(g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess)
      {
        CriticalSection_Enter(g_pYBWCManagerInstance->pCriticalSectionHistoryTable);
      }
    }

    for(i = 0; i < HistorySize; i++) 
    {
      gpHistory->History[i] = 0;
    }

    for(i = 0; i < HistorySize; i++) 
    {
      gpHistory->HistHit[i] = 1;
      gpHistory->HistTot[i] = 1;
    }

    g_pYBWCManagerInstance->bHistoryTableInitialized = TRUE;

    if(g_pYBWCManagerInstance->pFruitConfiguration->bUseSharedMemoryHistoryTable)
    {
      if(g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess)
      {
        CriticalSection_Leave(g_pYBWCManagerInstance->pCriticalSectionHistoryTable);
      }
    }
  }

  // Code[]

  for(pos = 0; pos < CODE_SIZE; pos++) 
  {
    Code[pos] = GEN_ERROR;
  }

  pos = 0;

  // main search

  PosLegalEvasion = pos;
  Code[pos++] = GEN_LEGAL_EVASION;
  Code[pos++] = GEN_END;

  PosSEE = pos;
  Code[pos++] = GEN_TRANS;
  Code[pos++] = GEN_GOOD_CAPTURE;
  Code[pos++] = GEN_KILLER;
  Code[pos++] = GEN_QUIET;
  Code[pos++] = GEN_BAD_CAPTURE;
  Code[pos++] = GEN_END;

  // quiescence search

  PosEvasionQS = pos;
  Code[pos++] = GEN_EVASION_QS;
  Code[pos++] = GEN_END;

  PosCheckQS = pos;
  Code[pos++] = GEN_CAPTURE_QS;
  Code[pos++] = GEN_CHECK_QS;
  Code[pos++] = GEN_END;

  PosCaptureQS = pos;
  Code[pos++] = GEN_CAPTURE_QS;
  Code[pos++] = GEN_END;

  ASSERT(pos < CODE_SIZE);
}

// sort_init()

void sort_init(sort_t * sort, board_t * board, const attack_t * attack, int depth, int height, int trans_killer) {

   ASSERT(sort!=NULL);
   ASSERT(board!=NULL);
   ASSERT(attack!=NULL);
   ASSERT(depth_is_ok(depth));
   ASSERT(height_is_ok(height));
   ASSERT(trans_killer==MoveNone||move_is_ok(trans_killer));

   sort->board        = board;
   sort->attack       = attack;

   sort->depth        = depth;
   sort->height       = height;

// kh 04.06.08 not really used
// kh 02.06.08 Thomas Gaksch 14b5c
   sort->capture_nb   = 0;

   sort->trans_killer = trans_killer;
   sort->killer_1     = Killer[sort->height][0];
   sort->killer_2     = Killer[sort->height][1];

   if (ATTACK_IN_CHECK(sort->attack)) {

      gen_legal_evasions(sort->list,sort->board,sort->attack);
      note_moves(sort->list,sort->board,sort->height,sort->trans_killer);
      list_sort(sort->list);

      sort->gen = PosLegalEvasion + 1;
      sort->test = TEST_NONE;

   } else { // not in check

      LIST_CLEAR(sort->list);
      sort->gen = PosSEE;
   }

   sort->pos = 0;
}

// sort_next()

// kh 02.06.08 Thomas Gaksch 14b5c
int sort_next(sort_t * sort) { // kh 10.04.07 Thomas Gaksch

   int move;
   int gen;

   ASSERT(sort!=NULL);

   while (true) {

      while (sort->pos < LIST_SIZE(sort->list)) {

         // next move

         move = LIST_MOVE(sort->list,sort->pos);
         sort->value    = 16384; // default score

// kh 04.06.08 not really used
// kh 02.06.08 Thomas Gaksch 14b5c
     		 sort->valuePV  = 16384;

         sort->pos++;

         ASSERT(move!=MoveNone);

         // test

         if (false) {

         } else if (sort->test == TEST_NONE) {

            // no-op

         } else if (sort->test == TEST_TRANS_KILLER) {
            //continue; // kh 14.02.07 temp only, without comment this line disables the killer heuristic for test purposes
            if (!move_is_pseudo(move,sort->board)) continue;
            if (!pseudo_is_legal(move,sort->board)) continue;

         } else if (sort->test == TEST_GOOD_CAPTURE) {

            ASSERT(move_is_tactical(move,sort->board));

            if (move == sort->trans_killer) continue;

            if (!capture_is_good(move,sort->board)) {
               LIST_ADD(sort->bad,move);
               continue;
            }

            if (!pseudo_is_legal(move,sort->board)) continue;

         } else if (sort->test == TEST_BAD_CAPTURE) {

            ASSERT(move_is_tactical(move,sort->board));
            ASSERT(!capture_is_good(move,sort->board));

            ASSERT(move!=sort->trans_killer);
            if(!pseudo_is_legal(move,sort->board)) continue;

// kh 02.06.08 Thomas Gaksch 14b5c
//				  sort->value = history_prob(move, sort->board, height); // kh 10.04.07 Thomas Gaksch

         } else if (sort->test == TEST_KILLER) {

            //continue; // kh 14.02.07 temp only, without comment this line disables the killer heuristic for test purposes
            if (move == sort->trans_killer) continue;
            if (!quiet_is_pseudo(move,sort->board)) continue;
            if (!pseudo_is_legal(move,sort->board)) continue;

            ASSERT(!move_is_tactical(move,sort->board));

         } else if (sort->test == TEST_QUIET) {

            ASSERT(!move_is_tactical(move,sort->board));

            if (move == sort->trans_killer) continue;
            if (move == sort->killer_1) continue;
            if (move == sort->killer_2) continue;
            if (!pseudo_is_legal(move,sort->board)) continue;

            sort->value = history_prob(move, sort->board); // kh 10.04.07 Thomas Gaksch

         } else {

            ASSERT(false);

            return MoveNone;
         }

         ASSERT(pseudo_is_legal(move,sort->board));

         return move;
      }

      // next stage

      gen = Code[sort->gen++];

      if (false) {

      } else if (gen == GEN_TRANS) {

         LIST_CLEAR(sort->list);
         if (sort->trans_killer != MoveNone) LIST_ADD(sort->list,sort->trans_killer);

         sort->test = TEST_TRANS_KILLER;

      } else if (gen == GEN_GOOD_CAPTURE) {

         gen_captures(sort->list,sort->board);

// kh 04.06.08 not really used
// kh 02.06.08 Thomas Gaksch 14b5c
    		 sort->capture_nb = LIST_SIZE(sort->list); 

         note_mvv_lva(sort->list,sort->board);
         list_sort(sort->list);

         LIST_CLEAR(sort->bad);

         sort->test = TEST_GOOD_CAPTURE;

      } else if (gen == GEN_BAD_CAPTURE) {

         list_copy(sort->list,sort->bad);

         sort->test = TEST_BAD_CAPTURE;

      } else if (gen == GEN_KILLER) {

         LIST_CLEAR(sort->list);
         if (sort->killer_1 != MoveNone) LIST_ADD(sort->list,sort->killer_1);
         if (sort->killer_2 != MoveNone) LIST_ADD(sort->list,sort->killer_2);

         sort->test = TEST_KILLER;

      } else if (gen == GEN_QUIET) {

         gen_quiet_moves(sort->list,sort->board);

// kh 02.06.08 Thomas Gaksch 14b5c
         note_quiet_moves(sort->list, sort->board); // kh 10.04.07 Thomas Gaksch
         list_sort(sort->list);

         sort->test = TEST_QUIET;

      } else {

         ASSERT(gen==GEN_END);

         return MoveNone;
      }

      sort->pos = 0;
   }
}

// sort_init_qs()

void sort_init_qs(sort_t * sort, board_t * board, const attack_t * attack, bool check) {

   ASSERT(sort!=NULL);
   ASSERT(board!=NULL);
   ASSERT(attack!=NULL);
   ASSERT(check==true||check==false);

   sort->board = board;
   sort->attack = attack;

   if (ATTACK_IN_CHECK(sort->attack)) {
      sort->gen = PosEvasionQS;
   } else if (check) {
      sort->gen = PosCheckQS;
   } else {
      sort->gen = PosCaptureQS;
   }

   LIST_CLEAR(sort->list);
   sort->pos = 0;
}

// sort_next_qs()

int sort_next_qs(sort_t * sort) {

   int move;
   int gen;

   ASSERT(sort!=NULL);

   while (true) {

      while (sort->pos < LIST_SIZE(sort->list)) {

         // next move

         move = LIST_MOVE(sort->list,sort->pos);
         sort->pos++;

         ASSERT(move!=MoveNone);

         // test

         if (false) {

         } else if (sort->test == TEST_LEGAL) {

            if (!pseudo_is_legal(move,sort->board)) continue;

         } else if (sort->test == TEST_CAPTURE_QS) {

            ASSERT(move_is_tactical(move,sort->board));

            if (!capture_is_good(move,sort->board)) continue;
            if (!pseudo_is_legal(move,sort->board)) continue;

         } else if (sort->test == TEST_CHECK_QS) {

            ASSERT(!move_is_tactical(move,sort->board));
            ASSERT(move_is_check(move,sort->board));

            if (see_move(move,sort->board) < 0) continue;
            if (!pseudo_is_legal(move,sort->board)) continue;

         } else {

            ASSERT(false);

            return MoveNone;
         }

         ASSERT(pseudo_is_legal(move,sort->board));

         return move;
      }

      // next stage

      gen = Code[sort->gen++];

      if (false) {

      } else if (gen == GEN_EVASION_QS) {

         gen_pseudo_evasions(sort->list,sort->board,sort->attack);
         note_moves_simple(sort->list,sort->board);
         list_sort(sort->list);

         sort->test = TEST_LEGAL;

      } else if (gen == GEN_CAPTURE_QS) {

         gen_captures(sort->list,sort->board);
         note_mvv_lva(sort->list,sort->board);
         list_sort(sort->list);

         sort->test = TEST_CAPTURE_QS;

      } else if (gen == GEN_CHECK_QS) {

         gen_quiet_checks(sort->list,sort->board);

         sort->test = TEST_CHECK_QS;

      } else {

         ASSERT(gen==GEN_END);

         return MoveNone;
      }

      sort->pos = 0;
   }
}

// good_move()

void good_move(int move, const board_t * board, int depth, int height)
{

// kh 02.06.08 Thomas Gaksch 14b5c
  uint16  index;
//uint32  index; // kh 10.04.07 Thomas Gaksch

  int     i;

  bool    bOverflow;

  int     nResult;

  ASSERT(move_is_ok(move));
  ASSERT(board != NULL);
  ASSERT(depth_is_ok(depth));
  ASSERT(height_is_ok(height));

// kh 02.06.08 Thomas Gaksch 14b5c
  if(move_is_tactical(move, board)) 
  {
    return;
  }

  // killer

// kh 02.06.08 Thomas Gaksch 14b5c
  if(Killer[height][0] != move) 
  {
    Killer[height][1] = Killer[height][0];
    Killer[height][0] = move;
  }

// kh 02.06.08 Thomas Gaksch 14b5c
// kh 12.04.07 use implication
// ASSERT((Killer[height][0] == move) || move_is_tactical(move, board));

// kh 02.06.08 Thomas Gaksch 14b5c
   ASSERT(Killer[height][0] == move);

// kh 02.06.08 Thomas Gaksch 14b5c
// kh 12.04.07 use implication
// ASSERT((Killer[height][1] != move) || move_is_tactical(move, board));


// kh 02.06.08 Thomas Gaksch 14b5c
   ASSERT(Killer[height][1] != move);

  // history

// kh 02.06.08 Thomas Gaksch 14b5c
  index = history_index(move, board); 

  if(g_pYBWCManagerInstance->pFruitConfiguration->bUseSharedMemoryHistoryTable)
  {

// kh 16.02.07 usually do not lock anything here at the moment
    if(g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess)
    {
      CriticalSection_Enter(g_pYBWCManagerInstance->pCriticalSectionHistoryTable);
    }

    gpHistory->nLockId = g_pYBWCManagerInstance->nRank;

    gpHistory->History[index] += HISTORY_INC(depth);

    bOverflow = false;
    if(gpHistory->History[index] >= HistoryMax) 
    {
      bOverflow = true;

/*
      if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_FORCE_OUTPUT)
      {
        YBWCManager_Printf(g_pYBWCManagerInstance, "INFO good_move(... \"overflow\" in History, adjust History\n");
      }
*/

      for(i = 0; i < HistorySize; i++) 
      {
        gpHistory->History[i] = (gpHistory->History[i] + 1) / 2;
      }
    }

    if(gpHistory->nLockId == g_pYBWCManagerInstance->nRank)
    {
      // kh 08.02.07 this indicates of course not sufficiently no lock conflicts
    }
    else
    {
      ASSERT(!g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess);

      if(bOverflow)
      {
/*
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_FORCE_OUTPUT)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, "WARNING good_move(... mutual unsynchronized shared memory history table access (adjust was also required)\n");
        }
*/
      }
      else
      {
/*
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_FORCE_OUTPUT)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, "WARNING good_move(... mutual unsynchronized shared memory history table access\n");
        }
*/
      }
    }

    if(g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess)
    {
      CriticalSection_Leave(g_pYBWCManagerInstance->pCriticalSectionHistoryTable);
    }
  }
  else
  {
    gpHistory->History[index] += HISTORY_INC(depth);

    if(gpHistory->History[index] >= HistoryMax) 
    {
      for(i = 0; i < HistorySize; i++) 
      {
        gpHistory->History[i] = (gpHistory->History[i] + 1) / 2;
      }
    }
  }

  if(g_pYBWCManagerInstance->bPotentialBroadcastHistoryTable)
  {
    g_pYBWCManagerInstance->nHistoryUpdateCount++;

    g_pYBWCManagerInstance->HistoryTableBuffer[index] += HISTORY_INC(depth);

    if(g_pYBWCManagerInstance->HistoryTableBuffer[index] >= HistoryMax) 
    {
      for(i = 0; i < HistorySize; i++) 
      {
        g_pYBWCManagerInstance->HistoryTableBuffer[i] = (g_pYBWCManagerInstance->HistoryTableBuffer[i] + 1) / 2;
      }
    }

    if(g_pYBWCManagerInstance->nHistoryUpdateCount >= 
       g_pYBWCManagerInstance->pFruitConfiguration->nHistoryTableUpdatesToTriggerBroadcast)
    {
      nResult = YBWCManager_BroadcastHistoryTable(g_pYBWCManagerInstance);

      ASSERT(g_pYBWCManagerInstance->nHistoryUpdateCount == 0);

      if(nResult == MPI_SUCCESS)
      {
      }
      else
      {
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_ERROR_PRIO_1)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, "ERROR good_move(... failed at YBWCManager_BroadcastHistoryTable(..., errorcode = %d\n", nResult);
        }
      }
    } // if(g_pYBWCManagerInstance->nHistoryUpdateCount >= ...
  } // if(g_pYBWCManagerInstance->bPotentialBroadcastHistoryTable)
}

// history_good()

// kh 04.06.08 Thomas Gaksch 14b5c
void history_good(int move, const board_t * board) 
{

// kh 02.06.08 Thomas Gaksch 14b5c
  uint16  index;
//uint32  index; // kh 10.04.07 Thomas Gaksch

  bool    bOverflow;

  int     nResult;

  ASSERT(move_is_ok(move));
  ASSERT(board!=NULL);

// kh 02.06.08 Thomas Gaksch 14b5c
  if(move_is_tactical(move,board)) 
  {
    return;
  }

  // history

// kh 02.06.08 Thomas Gaksch 14b5c
  index = history_index(move, board);

  if(g_pYBWCManagerInstance->pFruitConfiguration->bUseSharedMemoryHistoryTable)
  {

// kh 16.02.07 usually do not lock anything here at the moment
    if(g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess)
    {
      CriticalSection_Enter(g_pYBWCManagerInstance->pCriticalSectionHistoryTable);
    }

    gpHistory->nLockId = g_pYBWCManagerInstance->nRank;

    gpHistory->HistHit[index]++;
    gpHistory->HistTot[index]++;
 
    bOverflow = false;
    if(gpHistory->HistTot[index] >= HistoryMax) 
    {
      bOverflow = true;

/*
      if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_FORCE_OUTPUT)
      {
        YBWCManager_Printf(g_pYBWCManagerInstance, "INFO history_good(... \"overflow\" in HistTot, adjust HistHit and HistTot\n");
      }
*/

      gpHistory->HistHit[index] = (gpHistory->HistHit[index] + 1) / 2;
      gpHistory->HistTot[index] = (gpHistory->HistTot[index] + 1) / 2;
    }

    ASSERT(gpHistory->HistHit[index] <= gpHistory->HistTot[index]);
    ASSERT(gpHistory->HistTot[index] < HistoryMax);

    if(gpHistory->nLockId == g_pYBWCManagerInstance->nRank)
    {
      // kh 08.02.07 this indicates of course not sufficiently no lock conflicts
    }
    else
    {

      ASSERT(!g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess);

      if(bOverflow)
      {
/*
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_FORCE_OUTPUT)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, "WARNING history_good(... mutual unsynchronized shared memory history table access (adjust was also required)\n");
        }
*/
      }
      else
      {
/*
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_FORCE_OUTPUT)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, "WARNING history_good(... mutual unsynchronized shared memory history table access\n");
        }
*/
      }
    }

    if(g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess)
    {
      CriticalSection_Leave(g_pYBWCManagerInstance->pCriticalSectionHistoryTable);
    }
  }
  else
  {
    gpHistory->HistHit[index]++;
    gpHistory->HistTot[index]++;
 
    if(gpHistory->HistTot[index] >= HistoryMax) 
    {
      gpHistory->HistHit[index] = (gpHistory->HistHit[index] + 1) / 2;
      gpHistory->HistTot[index] = (gpHistory->HistTot[index] + 1) / 2;
    }

    ASSERT(gpHistory->HistHit[index] <= gpHistory->HistTot[index]);
    ASSERT(gpHistory->HistTot[index] < HistoryMax);
  }

  if(g_pYBWCManagerInstance->bPotentialBroadcastHistoryTable)
  {
    g_pYBWCManagerInstance->nHistTotUpdateCount++;

    g_pYBWCManagerInstance->HistHitTableBuffer[index]++;
    g_pYBWCManagerInstance->HistTotTableBuffer[index]++;

    if(g_pYBWCManagerInstance->HistTotTableBuffer[index] >= HistoryMax) 
    {
      g_pYBWCManagerInstance->HistHitTableBuffer[index] = (g_pYBWCManagerInstance->HistHitTableBuffer[index] + 1) / 2;
      g_pYBWCManagerInstance->HistTotTableBuffer[index] = (g_pYBWCManagerInstance->HistTotTableBuffer[index] + 1) / 2;
    }

    if(g_pYBWCManagerInstance->nHistTotUpdateCount >= 
       g_pYBWCManagerInstance->pFruitConfiguration->nHistTotTableUpdatesToTriggerBroadcast)
    {
      nResult = YBWCManager_BroadcastHistTotTable(g_pYBWCManagerInstance);

      ASSERT(g_pYBWCManagerInstance->nHistTotUpdateCount == 0);

      if(nResult == MPI_SUCCESS)
      {
      }
      else
      {
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_ERROR_PRIO_1)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, "ERROR history_good(... failed at YBWCManager_BroadcastHistTotTable(..., errorcode = %d\n", nResult);
        }
      }
    } // if(g_pYBWCManagerInstance->nHistTotUpdateCount >= ...
  } // if(g_pYBWCManagerInstance->bPotentialBroadcastHistoryTable)
}

// history_bad()

// kh 04.06.08 Thomas Gaksch 14b5c
void history_bad(int move, const board_t * board) 
{

// kh 02.06.08 Thomas Gaksch 14b5c
  uint16  index;
//uint32  index; // kh 10.04.07 Thomas Gaksch

  bool    bOverflow;

  int     nResult;

  ASSERT(move_is_ok(move));
  ASSERT(board != NULL);

// kh 02.06.08 Thomas Gaksch 14b5c
  if(move_is_tactical(move, board)) 
  {
    return;
  }

  // history

// kh 02.06.08 Thomas Gaksch 14b5c
  index = history_index(move, board);

  if(g_pYBWCManagerInstance->pFruitConfiguration->bUseSharedMemoryHistoryTable)
  {

// kh 16.02.07 usually do not lock anything here at the moment
    if(g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess)
    {
      CriticalSection_Enter(g_pYBWCManagerInstance->pCriticalSectionHistoryTable);
    }

    gpHistory->nLockId = g_pYBWCManagerInstance->nRank;

    gpHistory->HistTot[index]++;

    bOverflow = false;
    if(gpHistory->HistTot[index] >= HistoryMax) 
    {
      bOverflow = true;

/*
      if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_FORCE_OUTPUT)
      {
        YBWCManager_Printf(g_pYBWCManagerInstance, "INFO history_bad(... \"overflow\" in HistTot, adjust HistHit and HistTot\n");
      }
*/

      gpHistory->HistHit[index] = (gpHistory->HistHit[index] + 1) / 2;
      gpHistory->HistTot[index] = (gpHistory->HistTot[index] + 1) / 2;
    }

    ASSERT(gpHistory->HistHit[index] <= gpHistory->HistTot[index]);
    ASSERT(gpHistory->HistTot[index] < HistoryMax);

    if(gpHistory->nLockId == g_pYBWCManagerInstance->nRank)
    {
      // kh 08.02.07 this indicates of course not sufficiently no lock conflicts
    }
    else
    {

      ASSERT(!g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess);

      if(bOverflow)
      {
/*
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_FORCE_OUTPUT)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, "WARNING history_bad(... mutual unsynchronized shared memory history table access (adjust was also required)\n");
        }
*/
      }
      else
      {
/*
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_FORCE_OUTPUT)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, "WARNING history_bad(... mutual unsynchronized shared memory history table access\n");
        }
*/
      }
    }

    if(g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess)
    {
      CriticalSection_Leave(g_pYBWCManagerInstance->pCriticalSectionHistoryTable);
    }
  }
  else
  {
    gpHistory->HistTot[index]++;

    if(gpHistory->HistTot[index] >= HistoryMax) 
    {
      gpHistory->HistHit[index] = (gpHistory->HistHit[index] + 1) / 2;
      gpHistory->HistTot[index] = (gpHistory->HistTot[index] + 1) / 2;
    }

    ASSERT(gpHistory->HistHit[index] <= gpHistory->HistTot[index]);
    ASSERT(gpHistory->HistTot[index] < HistoryMax);
  }

  if(g_pYBWCManagerInstance->bPotentialBroadcastHistoryTable)
  {
    g_pYBWCManagerInstance->nHistTotUpdateCount++;

    g_pYBWCManagerInstance->HistTotTableBuffer[index]++;

    if(g_pYBWCManagerInstance->HistTotTableBuffer[index] >= HistoryMax) 
    {
      g_pYBWCManagerInstance->HistHitTableBuffer[index] = (g_pYBWCManagerInstance->HistHitTableBuffer[index] + 1) / 2;
      g_pYBWCManagerInstance->HistTotTableBuffer[index] = (g_pYBWCManagerInstance->HistTotTableBuffer[index] + 1) / 2;
    }

    if(g_pYBWCManagerInstance->nHistTotUpdateCount >= 
       g_pYBWCManagerInstance->pFruitConfiguration->nHistTotTableUpdatesToTriggerBroadcast)
    {
      nResult = YBWCManager_BroadcastHistTotTable(g_pYBWCManagerInstance);

      ASSERT(g_pYBWCManagerInstance->nHistTotUpdateCount == 0);

      if(nResult == MPI_SUCCESS)
      {
      }
      else
      {
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_ERROR_PRIO_1)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, "ERROR history_bad(... failed at YBWCManager_BroadcastHistTotTable(..., errorcode = %d\n", nResult);
        }
      }
    } // if(g_pYBWCManagerInstance->nHistTotUpdateCount >= ...
  } // if(g_pYBWCManagerInstance->bPotentialBroadcastHistoryTable)
}

// kh 02.06.08 Thomas Gaksch 14b5c
void history_reset(int move, const board_t * board) 
{
  uint16  index;

  int     nResult;

  ASSERT(move_is_ok(move));
  ASSERT(board != NULL);

  // history

  index = history_index(move, board);

  if(g_pYBWCManagerInstance->pFruitConfiguration->bUseSharedMemoryHistoryTable)
  {

// kh 16.02.07 usually do not lock anything here at the moment
    if(g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess)
    {
      CriticalSection_Enter(g_pYBWCManagerInstance->pCriticalSectionHistoryTable);
    }

    gpHistory->nLockId = g_pYBWCManagerInstance->nRank;

    gpHistory->HistHit[index] = 1; // gpHistory->HistHit[index] = gpHistory->HistHit[index] / 3 + 1;
    gpHistory->HistTot[index] = 1; // gpHistory->HistTot[index] = gpHistory->HistTot[index] / 2 + 1;

    ASSERT(gpHistory->HistHit[index] <= gpHistory->HistTot[index]);
    ASSERT(gpHistory->HistTot[index] < HistoryMax);

    if(gpHistory->nLockId == g_pYBWCManagerInstance->nRank)
    {
      // kh 02.06.08 this indicates of course not sufficiently no lock conflicts
    }
    else
    {

      ASSERT(!g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess);

/*
      if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_FORCE_OUTPUT)
      {
        YBWCManager_Printf(g_pYBWCManagerInstance, "WARNING history_reset(... mutual unsynchronized shared memory history table access\n");
      }
*/

    }

    if(g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess)
    {
      CriticalSection_Leave(g_pYBWCManagerInstance->pCriticalSectionHistoryTable);
    }
  }
  else
  {

    gpHistory->HistHit[index] = 1; // gpHistory->HistHit[index] = gpHistory->HistHit[index] / 3 + 1;
    gpHistory->HistTot[index] = 1; // gpHistory->HistTot[index] = gpHistory->HistTot[index] / 2 + 1;

    ASSERT(gpHistory->HistHit[index] <= gpHistory->HistTot[index]);
    ASSERT(gpHistory->HistTot[index] < HistoryMax);
  }

  if(g_pYBWCManagerInstance->bPotentialBroadcastHistoryTable)
  {
    g_pYBWCManagerInstance->nHistTotUpdateCount++;

    g_pYBWCManagerInstance->HistHitTableBuffer[index] = 1; // g_pYBWCManagerInstance->HistHitTableBuffer[index] = g_pYBWCManagerInstance->HistHitTableBuffer[index] / 3 + 1;
    g_pYBWCManagerInstance->HistTotTableBuffer[index] = 1; // g_pYBWCManagerInstance->HistTotTableBuffer[index] = g_pYBWCManagerInstance->HistTotTableBuffer[index] / 2 + 1;

    if(g_pYBWCManagerInstance->nHistTotUpdateCount >= 
       g_pYBWCManagerInstance->pFruitConfiguration->nHistTotTableUpdatesToTriggerBroadcast)
    {
      nResult = YBWCManager_BroadcastHistTotTable(g_pYBWCManagerInstance);

      ASSERT(g_pYBWCManagerInstance->nHistTotUpdateCount == 0);

      if(nResult == MPI_SUCCESS)
      {
      }
      else
      {
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_ERROR_PRIO_1)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, "ERROR history_reset(... failed at YBWCManager_BroadcastHistTotTable(..., errorcode = %d\n", nResult);
        }
      }
    } // if(g_pYBWCManagerInstance->nHistTotUpdateCount >= ...
  } // if(g_pYBWCManagerInstance->bPotentialBroadcastHistoryTable)
}

// note_moves()

void note_moves(list_t * list, const board_t * board, int height, int trans_killer) 
{
  int  size;

  int  i;
  int  move;

  ASSERT(list_is_ok(list));
  ASSERT(board != NULL);
  ASSERT(height_is_ok(height));
  ASSERT(trans_killer == MoveNone || move_is_ok(trans_killer));

  size = LIST_SIZE(list);

  if(size >= 2) 
  {
    for (i = 0; i < size; i++) 
    {
      move = LIST_MOVE(list, i);
      list->value[i] = move_value(move, board, height, trans_killer);
    }
  }
}

// note_captures()

static void note_captures(list_t * list, const board_t * board) {

   int size;
   int i, move;

   ASSERT(list_is_ok(list));
   ASSERT(board!=NULL);

   size = LIST_SIZE(list);

   if (size >= 2) {
      for (i = 0; i < size; i++) {
         move = LIST_MOVE(list,i);
         list->value[i] = capture_value(move,board);
      }
   }
}

// note_quiet_moves()

// kh 02.06.08 Thomas Gaksch 14b5c
static void note_quiet_moves(list_t * list, const board_t * board) // kh 10.04.07 Thomas Gaksch
{
  int size;

  int i;
  int move;

  ASSERT(list_is_ok(list));
  ASSERT(board != NULL);

  size = LIST_SIZE(list);

  if(size >= 2) 
  {
    for(i = 0; i < size; i++) 
    {
      move = LIST_MOVE(list, i);

// kh 02.06.08 Thomas Gaksch 14b5c
      list->value[i] = quiet_move_value(move, board); // kh 10.04.07 Thomas Gaksch
    }
  }
}

// note_moves_simple()

static void note_moves_simple(list_t * list, const board_t * board) {

   int size;
   int i, move;

   ASSERT(list_is_ok(list));
   ASSERT(board!=NULL);

   size = LIST_SIZE(list);

   if (size >= 2) {
      for (i = 0; i < size; i++) {
         move = LIST_MOVE(list,i);
         list->value[i] = move_value_simple(move,board);
      }
   }
}

// note_mvv_lva()

static void note_mvv_lva(list_t * list, const board_t * board) {

   int size;
   int i, move;

   ASSERT(list_is_ok(list));
   ASSERT(board!=NULL);

   size = LIST_SIZE(list);

   if (size >= 2) {
      for (i = 0; i < size; i++) {
         move = LIST_MOVE(list,i);
         list->value[i] = mvv_lva(move,board);
      }
   }
}

// move_value()

static int move_value(int move, const board_t * board, int height, int trans_killer) {

   int value;

   ASSERT(move_is_ok(move));
   ASSERT(board!=NULL);
   ASSERT(height_is_ok(height));
   ASSERT(trans_killer==MoveNone||move_is_ok(trans_killer));

   if (false) {
   } else if (move == trans_killer) { // transposition table killer
      value = TransScore;
   } else if (move_is_tactical(move,board)) { // capture or promote
      value = capture_value(move,board);
   } else if (move == Killer[height][0]) { // killer 1
      value = KillerScore;
   } else if (move == Killer[height][1]) { // killer 2

// kh 02.06.08 Thomas Gaksch 14b5c
      value = KillerScore - 2;
//    value = KillerScore - 1;

   } 
   else 
   { // quiet move

// kh 02.06.08 Thomas Gaksch 14b5c
      value = quiet_move_value(move, board); // kh 10.04.07 Thomas Gaksch
   }

   return value;
}

// capture_value()

static int capture_value(int move, const board_t * board) {

   int value;

   ASSERT(move_is_ok(move));
   ASSERT(board!=NULL);

   ASSERT(move_is_tactical(move,board));

   value = mvv_lva(move,board);

   if (capture_is_good(move,board)) {
      value += GoodScore;
   } else {
      value += BadScore;
   }

   ASSERT(value>=-30000&&value<=+30000);

   return value;
}

// quiet_move_value()

// kh 02.06.08 Thomas Gaksch 14b5c
static int quiet_move_value(int move, const board_t * board) // kh 10.04.07 Thomas Gaksch
{
  int     value;

// kh 02.06.08 Thomas Gaksch 14b5c
  uint16  index;
//uint32  index; // kh 10.04.07 Thomas Gaksch

  ASSERT(move_is_ok(move));
  ASSERT(board != NULL);

  ASSERT(!move_is_tactical(move, board));

// kh 02.06.08 Thomas Gaksch 14b5c
  index = history_index(move, board);

// kh 08.02.07 no synchronization required for this read access (even) if history table is in shared memory
  value = HistoryScore + gpHistory->History[index]; 
  ASSERT(value >= HistoryScore && value <= KillerScore - 4);

  return value;
}

// move_value_simple()

static int move_value_simple(int move, const board_t * board) {

   int value;

   ASSERT(move_is_ok(move));
   ASSERT(board!=NULL);

   value = HistoryScore;
   if (move_is_tactical(move,board)) value = mvv_lva(move,board);

   return value;
}

// history_prob()

// kh 02.06.08 Thomas Gaksch 14b5c
int history_prob(int move, const board_t * board) // kh 10.04.07 Thomas Gaksch
{
  int     value;

// kh 02.06.08 Thomas Gaksch 14b5c
  uint16  index;
//uint32  index; // kh 10.04.07 Thomas Gaksch

  int     nHistTot;

  ASSERT(move_is_ok(move));
  ASSERT(board != NULL);

// kh 12.04.07 assertion does not hold any longer for toga
//ASSERT(!move_is_tactical(move, board));

// kh 02.06.08 Thomas Gaksch 14b5c
  index = history_index(move, board);

  if(g_pYBWCManagerInstance->pFruitConfiguration->bUseSharedMemoryHistoryTable)
  {

// kh 16.02.07 usually do not lock anything here at the moment
    if(g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess)
    {
      CriticalSection_Enter(g_pYBWCManagerInstance->pCriticalSectionHistoryTable);
    }

    gpHistory->nLockId = g_pYBWCManagerInstance->nRank;

    ASSERT(gpHistory->HistHit[index] <= gpHistory->HistTot[index]);
    ASSERT(gpHistory->HistTot[index] < HistoryMax);

    if(g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess)
    {
      ASSERT(gpHistory->HistHit[index] <= gpHistory->HistTot[index]);
      ASSERT(gpHistory->HistTot[index] < HistoryMax);

      value = (gpHistory->HistHit[index] * 16384) / gpHistory->HistTot[index];
    } // if(g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess)
    else
    {

// kh 08.02.07 make the assignment more defensive as long as the shared memory access is not synchronized
//  value = (gpHistory->HistHit[index] * 16384) / gpHistory->HistTot[index];

      value     = gpHistory->HistHit[index] * 16384;
      nHistTot  = gpHistory->HistTot[index];
      if(nHistTot > 0)
      {
        value = value / nHistTot;
      }

      if(value > 16384)
      {

//      ASSERT(!g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess); // kh 16.02.07 redundant here

        value = 16384;
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_WARNING_PRIO_1)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, "WARNING history_prob(... value forced limited to 16384\n");
        }

// kh 22.02.07 $$$ test only
        gpHistory->HistHit[index] = (gpHistory->HistHit[index] + 1) / 2;
        gpHistory->HistTot[index] = (gpHistory->HistTot[index] + 1) / 2;

      }
    } // !if(g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess)

    ASSERT(value >= 0 && value <= 16384);

    if(gpHistory->nLockId == g_pYBWCManagerInstance->nRank)
    {
      // kh 08.02.07 this indicates of course not sufficiently no lock conflicts
    }
    else
    {

      ASSERT(!g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess);

/*
      if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_FORCE_OUTPUT)
      {
        YBWCManager_Printf(g_pYBWCManagerInstance, "WARNING history_prob(... mutual unsynchronized shared memory history table access\n");
      }
*/
    }

    if(g_pYBWCManagerInstance->pFruitConfiguration->bSynchronizeHistoryTableAccess)
    {
      CriticalSection_Leave(g_pYBWCManagerInstance->pCriticalSectionHistoryTable);
    }
  }
  else
  {
    ASSERT(gpHistory->HistHit[index] <= gpHistory->HistTot[index]);
    ASSERT(gpHistory->HistTot[index] < HistoryMax);

    value = (gpHistory->HistHit[index] * 16384) / gpHistory->HistTot[index];
    ASSERT(value >= 0 && value <= 16384);
  }

  return value;
}

// capture_is_good()

static bool capture_is_good(int move, const board_t * board) {

   int piece, capture;

   ASSERT(move_is_ok(move));
   ASSERT(board!=NULL);

   ASSERT(move_is_tactical(move,board));

   // special cases

   if (MOVE_IS_EN_PASSANT(move)) return true;
   if (move_is_under_promote(move)) return false; // REMOVE ME?

   // captures and queen promotes

   capture = board->square[MOVE_TO(move)];

   if (capture != Empty) {

      // capture

      ASSERT(move_is_capture(move,board));

      if (MOVE_IS_PROMOTE(move)) return true; // promote-capture

      piece = board->square[MOVE_FROM(move)];
      if (VALUE_PIECE(capture) >= VALUE_PIECE(piece)) return true;
   }

   return see_move(move,board) >= 0;
}

// mvv_lva()

static int mvv_lva(int move, const board_t * board) {

   int piece, capture, promote;
   int value;

   ASSERT(move_is_ok(move));
   ASSERT(board!=NULL);

   ASSERT(move_is_tactical(move,board));

   if (MOVE_IS_EN_PASSANT(move)) { // en-passant capture

      value = 5; // PxP

   } else if ((capture = board->square[MOVE_TO(move)]) != Empty) { // normal capture

      piece = board->square[MOVE_FROM(move)];

      value = PIECE_ORDER(capture) * 6 - PIECE_ORDER(piece) + 5;
      ASSERT(value>=0&&value<30);

   } else { // promote

      ASSERT(MOVE_IS_PROMOTE(move));

      promote = move_promote(move);

      value = PIECE_ORDER(promote) - 5;
      ASSERT(value>=-4&&value<0);
   }

   ASSERT(value>=-4&&value<+30);

   return value;
}

// history_index()

// kh 02.06.08 Thomas Gaksch 14b5c
static uint16 history_index(int move, const board_t * board)
{

// kh 10.04.07 Thomas Gaksch
//int     p;

// kh 02.06.08 Thomas Gaksch 14b5c
  uint16  index;
//uint32  index; // kh 10.04.07 Thomas Gaksch

  ASSERT(move_is_ok(move));
  ASSERT(board != NULL);

// kh 12.04.07 assertion does not hold any longer for toga
//ASSERT(!move_is_tactical(move, board));

// kh 19.03.08 reenabled again
// kh 10.04.07 start Thomas Gaksch
  index = PIECE_TO_12(board->square[MOVE_FROM(move)]) * 64 + SQUARE_TO_64(MOVE_TO(move));

// kh 19.03.08 disabled
/*
   //index = p * (12*64*64) + PIECE_TO_12(board->square[MOVE_FROM(move)]) * (64*64) + SQUARE_TO_64(MOVE_FROM(move)) * 64 + SQUARE_TO_64(MOVE_TO(move));
   index = board->pawn_size[White] * (9*12*64*64) +
			  board->pawn_size[Black] * (12*64*64) + 
			  PIECE_TO_12(board->square[MOVE_FROM(move)]) * (64*64) +
			  SQUARE_TO_64(MOVE_FROM(move)) * 64 +
			  SQUARE_TO_64(MOVE_TO(move)); 
	/*index = MIN(board->piece_size[White],8) * (9*9*9*12*64) +
			  MIN(board->piece_size[Black],8) * (9*9*12*64) + 
			  board->pawn_size[White] * (9*12*64) +
			  board->pawn_size[Black] * (12*64) + 
			  PIECE_TO_12(board->square[MOVE_FROM(move)]) * (64) +
			  SQUARE_TO_64(MOVE_TO(move));* /
	//index = MIN(height, 63) * (12*64) + PIECE_TO_12(board->square[MOVE_FROM(move)]) * (64) + SQUARE_TO_64(MOVE_TO(move));
// kh 10.04.07 end Thomas Gaksch
*/

  ASSERT(index >= 0 && index < HistorySize);

  return index;
}

// end of sort.cpp
