#include <stdio.h>
#include <stdlib.h>

#include "board.h"
#include "movelist.h"
#include "move.h"
#include "piece.h"
#include "atak.h"


// functions

void MoveListFilter (board_t *board,  movelist_t *movelist)
/**************************************************************************
 *
 *  All the illegal moves is the list are removed
 *
 **************************************************************************/
{
   leaf *p;
   int side, xside;
   int check, sq;
   undo_t undo[1];

   side = board->side;
   xside = 1^side;
   sq = board->king[side];
   for (p = movelist->moves; p < movelist->moves+movelist->gencnt; p++) {
     MoveMakeS(board, &p->move, undo);
     if (board->cboard[TOSQ(p->move)] != king){
       check = SqAtakd (board,sq, xside); 
     }else {
       check = SqAtakd (board,TOSQ(p->move), xside); 
     }
     MoveUnMakeS (board, undo);
     if (check)	 { /* its an illegal move */
       --(movelist->gencnt);
       *p=*(movelist->moves+movelist->gencnt);
       --p; 
     } 
   }
   ASSERT(movelist->gencnt>=0);
}

void MoveListAdd(board_t *board, movelist_t *movelist, leaf *p){
    ASSERT(MoveIsPseudoLegal(board,p->move));
    movelist->moves[movelist->gencnt]=*p;
    movelist->gencnt++;
}

void MoveListShow (board_t *board, movelist_t *movelist)
/**************************************************************************
 *
 *  Print out the move list.  
 *
 **************************************************************************/
{
   leaf *node;
   int i = 0;
   char SANmv[SANSZ];
   
   for (node = movelist->moves; node < movelist->moves+movelist->gencnt; node++) {
     ASSERT(MoveIsPseudoLegal(board,node->move));
     MoveToSAN (board,node->move,SANmv); 
     Output("%5s %6d\t", SANmv, node->score);
      if (++i == 5)
      {
         Output("\n"); 
         i = 0;
      }
   }
   Output("\n");
} 

leaf * MoveListPickRandom(movelist_t *movelist){
  int i,k;
  int sum;
  int r;
  sum=0;
  for(i=0;i<movelist->gencnt;i++){
    sum+=movelist->moves[i].score;
  }
  r=rand();
  if(sum==0){
    return NULL;
  }
  k=r%sum;
  sum=0;
  for(i=0;i<movelist->gencnt;i++){
    sum+=movelist->moves[i].score;
    if(sum>k){
      break;
    }
  }
  return &(movelist->moves[i]);
}

leaf * MoveListPickBest(movelist_t *movelist){
  int i;
  int best;
  int ibest;
  best=-1;
  ibest=0;
  for(i=0;i<movelist->gencnt;i++){
    if(movelist->moves[i].score>best){
      best=movelist->moves[i].score;
      ibest=i;
    }
  }
  if(best<=0){
    return NULL;
  }else{
    return movelist->moves+ibest;
  }
}

void MoveListPickSel(movelist_t *movelist, leaf *head)
/***************************************************************************
 *
 *  This pick routine searches the movelist and swap the high score entry
 *  with the one currently at the head.
 *
 ***************************************************************************/
{
   int best;
   leaf *p, *pbest, tmp;

   best = head->score;
   pbest = head;
   for (p = head+1; p < movelist->moves+movelist->gencnt; p++) {
      if (p->score > best) {
         pbest = p;
	 best = p->score;
      }
   }

   /*  Swap pbest with the head  */
   tmp = *head;
   *head = *pbest;
   *pbest = tmp; 
}

