Ejemplo n.º 1
0
static int DrawMove(BOARD *board, MOVE move)
{
  MakeMove(board, &move);
  int draw = AssessDraw(board, 0);
  Takeback(board, move);
  return draw != ERRORVALUE;
}
Ejemplo n.º 2
0
static int Quiescent(BOARD *board, int alpha, int beta, int root, CONTROL *control, MOVE killers[][2])
{
    int nmoves, nlegal = 0;
    int val;
    MOVE moves[MAXMOVES];
    
    if(!control->ponder && clock() - control->init_time >= control->max_time*CPMS){
        control->stop = 1;
    }
    
    val = LazyEval(board);
    if(val-LAZYBETA >= beta) return beta;
    if(val+LAZYALPHA < alpha) return alpha;

    val = StaticEval(board);
    UpdateTable(&hash_table, board->zobrist_key, val, 0, 0, HASH_EXACT);

    if (val >= beta) return beta;
    if (val > alpha) alpha = val;
    
    nmoves = CaptureGen(board, moves);
    nmoves = FilterWinning(board, moves, nmoves); 
//   nmoves = SortMoves(board, moves, nmoves, killers[root]);

    for(int i = 0; i < nmoves; i++){
        control->node_count++;
        MakeMove(board, &moves[i]);
        if(!LeftInCheck(board)){
            nlegal++;
            val = -Quiescent(board, -beta, -alpha, root+1, control, killers);
            Takeback(board, moves[i]);
            if(val >= beta){
                return beta;
            }
            if(val > alpha){
                alpha = val;
            }
        }else Takeback(board, moves[i]);
    }
    return alpha;
}
Ejemplo n.º 3
0
/*This works because the replacement scheme ensures shallow PV is not overwritten,
and may fail if the hash table is full.*/
static int RetrievePV(BOARD *board, MOVE *PV, unsigned int depth)
{
    unsigned int PVlen = 0;
    MOVE mov = GetHashMove(&hash_table, board->zobrist_key);
    while(mov && PVlen <= depth && IsLegal(board, &mov)){
        PV[PVlen++] = mov;
        MakeMove(board, &mov);
        mov = GetHashMove(&hash_table, board->zobrist_key);
    }
    for(int i = PVlen; i > 0; i--){
        Takeback(board, PV[i-1]);
    }
    return PVlen;
}
Ejemplo n.º 4
0
static int AlphaBeta(BOARD *board, unsigned int depth, int alpha, int beta,
               int root, CONTROL *control, char skip_null, MOVE killers[][2])
{
    int nmoves, nlegal = 0;
    MOVE moves[MAXMOVES];
    MOVE best_move = 0;
    char str_mov[MVLEN];
    int val = ERRORVALUE;
    char hash_flag = HASH_ALPHA;
    int reduce = 0, LMR = 0;

    if(depth){
        if(root > 0){
            val = GetHashEval(&hash_table, board->zobrist_key, depth, alpha, beta);
            if(val != ERRORVALUE) return val; 
        }
        if(depth > 2 && !InCheck(board, 0)){

            if(!skip_null && board->piece_material[board->white_to_move] != 0){
                MOVE null_mv = NULL_MOVE;
                MakeMove(board, &null_mv);
                val = -AlphaBeta(board, depth-3, -beta, -beta+1, root+1, control, 1, killers);
                Takeback(board, null_mv);
                if(val >= beta) return beta;
            }
            reduce = 1;	/*Try Late Move reductions.*/
        }
        nmoves = MoveGen(board, moves, 1);
        int good = SortMoves(board, moves, nmoves, killers[root]);
        for(int i = 0; i < nmoves; i++){
            MakeMove(board, &moves[i]);
            control->node_count++;
            if(!LeftInCheck(board)){
                if(root == 0){
                    if(!control->best_move) control->best_move = moves[i];    /* Better than nothing. */
                    if(depth > 6 && !control->ponder){
                        MoveToAlgeb(moves[i], str_mov);
                        printf("info depth %i hashfull %i currmove %s currmovenumber %i\n",
                            depth, hash_table.full/(hash_table.size/1000), str_mov, i+1);
                    }
                }
                nlegal++;
                val = AssesDraw(board);
                if(val) {
                    if(best_move){
                        LMR = (reduce && i > good && !CAPTMASK(moves[i]) && !InCheck(board, 0)) ? 1 : 0;
                        val = -AlphaBeta(board, depth-LMR-1, -alpha-1, -alpha, root+1, control, 0, killers);
                        if(val > alpha){
                            val = -AlphaBeta(board, depth-1, -alpha-1, -alpha, root+1, control, 0, killers);
                            if(val > alpha && val < beta){
                                val = -AlphaBeta(board, depth-1, -beta, -alpha, root+1, control, 0, killers);
                            }
                        }
                    }else val = -AlphaBeta(board, depth-1, -beta, -alpha, root+1, control, 0, killers);
                }
                Takeback(board, moves[i]);
                if(!control->ponder && control->stop) return alpha;
                if(val >= beta){
                    UpdateTable(&hash_table, board->zobrist_key, val, moves[i], depth, HASH_BETA);
                    if(CAPTMASK(moves[i]) == 0
                            && killers[root][0] != moves[i]
                            && killers[root][1] != moves[i]){
                        killers[root][1] = killers[root][0];
                        killers[root][0] = moves[i];
                    }
                    return beta;
                }
                if(val > alpha){
                    alpha = val;
                    hash_flag = HASH_EXACT;
                    best_move = moves[i];
                    if(root == 0) control->best_move = best_move;
                }
                if(root == 0 && ((clock() - control->init_time) > control->wish_time*CPMS)){
                /* if short of time, don't search anymore after current move */
                    control->stop = 1;
                    return alpha;
                }
            }else Takeback(board, moves[i]);
        }
        if(nlegal == 0){
            if(InCheck(board, 0)){
/*UpdateTable(&hash_table, board->zobrist_key, MATE_VALUE+root, 0, depth, HASH_EXACT, hash_table.entries);*/
                return MATE_VALUE;
            }else{
/*UpdateTable(&hash_table, board->zobrist_key, DRAW_VALUE, 0, depth, HASH_EXACT, hash_table.entries);*/
                return DRAW_VALUE;    /*Stalemate*/
            }
        }else UpdateTable(&hash_table, board->zobrist_key, alpha, best_move, depth, hash_flag);
        
    }else if(InCheck(board, 0)){
        alpha = AlphaBeta(board, 1, alpha, beta, root+1, control, 1, killers);
    }else{
        alpha = Quiescent(board, alpha, beta, root, control, killers);
    }
    return alpha;
}
Ejemplo n.º 5
0
static int AlphaBeta (BOARD *board, int depth, int alpha, int beta,
               int root, CONTROL *control, char skip_null, MOVE killers[][2])
{
  int nmoves, good = 0, nlegal = 0;
  MOVE moves[MAXMOVES];
  MOVE best_move = 0;
  char str_mov[MVLEN];
  int val = ERRORVALUE;
  char hash_flag = HASH_ALPHA;
  
  int in_check = InCheck(board, 0);

  if (root > control->seldepth) control->seldepth = root;

  if (depth > 0 || in_check) {
    if (root > 0) {
      val = GetHashEval(&hash_table, board->zobrist_key, depth, alpha, beta);
      if (val != ERRORVALUE) return val;
    }
    if (depth > 2 && !in_check) {    
      if (!skip_null && board->piece_material[board->white_to_move] != 0) {
        MOVE null_mv = NULL_MOVE;
        MakeMove(board, &null_mv);
        val = -AlphaBeta(board, depth-3, -beta, -beta+1, root+1, control, 1, killers);
        Takeback(board, null_mv);
        if (val >= beta) return beta;
      }
    }
    nmoves = MoveGen(board, moves, 1);
    good = SortMoves(board, moves, nmoves, killers[root]);
  } else {
    if (!control->ponder && clock() - control->init_time >= control->max_time*CPMS) {
      control->stop = 1;
    }
    val = LazyEval(board);
    if (val-LAZYBETA >= beta) return beta;
    if (val+LAZYALPHA < alpha) return alpha;

    val = StaticEval(board);
    UpdateTable(&hash_table, board->zobrist_key, val, 0, 0, HASH_EXACT);
    if (val >= beta) return beta;
    if (val > alpha) alpha = val;
    
    nmoves = CaptureGen(board, moves);
    nmoves = FilterWinning(board, moves, nmoves);
  }
        
  for (int i = 0; i < nmoves; i++) {
    MakeMove(board, &moves[i]);
    control->node_count++;
    if (LeftInCheck(board)) {
      Takeback(board, moves[i]);
      continue;
    }
    if (root == 0) {
      if (!control->best_move) control->best_move = moves[i];    /* Better than nothing. */
      if (depth > 6 && !control->ponder) {
        MoveToAlgeb(moves[i], str_mov);
        printf("info depth %i seldepth %i hashfull %i currmove %s currmovenumber %i\n",
               depth, control->seldepth, hash_table.full/(hash_table.size/1000), str_mov, i+1);
      }
    }
    nlegal++;
    val = AssessDraw(board, control->contempt);
    if (val == ERRORVALUE) {
      int ext = 0; //InCheck(board, 0) ? 1 : 0;
      if (best_move) {
        int LMR = (depth > 2 && !in_check && i > good &&
                   !CAPTMASK(moves[i]) && !InCheck(board, 0)) ? 1 : 0;
        val = -AlphaBeta(board, depth+ext-LMR-1, -alpha-1, -alpha, root+1, control, 0, killers);
        if (val > alpha) {
          val = -AlphaBeta(board, depth+ext-1, -alpha-1, -alpha, root+1, control, 0, killers);
          if (val > alpha && val < beta) {
            val = -AlphaBeta(board, depth+ext-1, -beta, -alpha, root+1, control, 0, killers);
          }
        }
      } else {
        val = -AlphaBeta(board, depth+ext-1, -beta, -alpha, root+1, control, 0, killers);
      }
    }
    Takeback(board, moves[i]);
    if (!control->ponder && control->stop) return alpha;
    if (val >= beta) {
      UpdateTable(&hash_table, board->zobrist_key, val, moves[i], depth, HASH_BETA);
      if (CAPTMASK(moves[i]) == 0 && killers[root][0] != moves[i] && killers[root][1] != moves[i]) {
        killers[root][1] = killers[root][0];
        killers[root][0] = moves[i];
      }
      return beta;
    }
    if (val > alpha) {
      alpha = val;
      hash_flag = HASH_EXACT;
      best_move = moves[i];
      if (root == 0) control->best_move = best_move;
    }
    if (root == 0 && ((clock() - control->init_time) > control->wish_time*CPMS)) {
    /* if short of time, don't search anymore after current move */
      control->stop = 1;
      return alpha;
    }
  }
  if (nlegal == 0) {
    if (in_check) {
      /*UpdateTable(&hash_table, board->zobrist_key, MATE_VALUE+root, 0, depth, HASH_EXACT, hash_table.entries);*/
      return MATE_VALUE;
    } else if (depth > 0) {
      /*UpdateTable(&hash_table, board->zobrist_key, DRAW_VALUE, 0, depth, HASH_EXACT, hash_table.entries);*/
      return DRAW_VALUE;    /*Stalemate*/
    }
  } else {
    UpdateTable(&hash_table, board->zobrist_key, alpha, best_move, depth, hash_flag);
  }
  return alpha;
}