Beispiel #1
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;
}
Beispiel #2
0
int Quiescent (int alpha, int beta)
{
    int i = 0;
    int movescnt = 0;
    int score = 0;
    int best = 0;
    MOVE qMovesBuf[200];

    countquiesCalls++;
    nodes++;

    /* Do some housekeeping every 1024 nodes */
    if ((nodes & 1023) == 0)
        checkup(stop_time);
    if (must_stop)
        return 0;

    if (reps() >= 2)
        return 0;

    best = Eval(alpha, beta);
    // --- stand pat cutoff?
    if (best > alpha)
        {
            if (best >= beta)
                return best;
            alpha = best;
        }

    /* As we are in qasearch we generate the captures */
    movescnt = GenCaps (side, qMovesBuf);
    countCapCalls++;

#ifdef SEARCH_DEBUG
            if (movescnt > 200) printf("Too much moves!: %d", movescnt);
#endif

    /* Now the alpha-beta search in quiescent */
    for (i = 0; i < movescnt; ++i)
        {
        MoveOrder(i, movescnt, qMovesBuf);

            if (!MakeMove (qMovesBuf[i]))
            {
                /* If the current move isn't legal, we take it back
                 * and take the next move in the list */
                TakeBack ();
                continue;
            }

            score = -Quiescent (-beta, -alpha);
            TakeBack ();

            if ((nodes & 1023) == 0)
                checkup(stop_time);
            if (must_stop)
                return 0;

            if (score >= beta)
                return beta;
            if (score > alpha)
                alpha = score;
        }
#ifdef SEARCH_DEBUG
    if (alpha > MATE) printf("alpha too high: %d", alpha);
    if (alpha < -MATE) printf("alpha too low: %d", alpha);
#endif

    return alpha;
}
Beispiel #3
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;
}
Beispiel #4
0
int Search (int alpha, int beta, int depth, MOVE * pBestMove, LINE * pline)
{

    /* Vars deffinition */
    int i;
    int value;			/* To store the evaluation */
    int havemove;		/* Either we have or not a legal move available */
    int movecnt;		/* The number of available moves */

//    int score;
    MOVE moveBuf[200];  /* List of movements */
    MOVE tmpMove;
    LINE    line;

    nodes++;
    countSearchCalls++;

    /* Do some housekeeping every 1024 nodes */
    if ((nodes & 1023) == 0)
        checkup(stop_time);
    if (must_stop)
        return 0;

    havemove = 0;		/* is there a move available? */
    pBestMove->type_of_move = MOVE_TYPE_NONE;

    /* If we are in a leaf node we cal quiescence instead of eval */
    if (depth == 0)
        {
            pline->cmove = 0;
            return Quiescent(alpha, beta);
            /* Uncomment nest line if want to make tests avoiding qsearch */
            //return Eval(alpha, beta);
        }

    /* If we're in check we want to search deeper */
    if (IsInCheck(side))
        ++depth;

    /* Static null move prunning */
    if (ply && !IsInCheck(side))
        {
            int ev = Eval(-MATE, MATE);
            int evalua = ev - 150;
            if (evalua >= beta)
                return beta;
        }

    /* Generate and count all moves for current position */
    movecnt = GenMoves (side, moveBuf);

    /* Once we have all the moves available, we loop through the posible
     * moves and apply an alpha-beta search */
    for (i = 0; i < movecnt; ++i)
        {
            /* Here must be called OrderMove, so we have the moves are ordered before
            picking one up from the list*/
            MoveOrder(i, movecnt, moveBuf);

            /* If the current move isn't legal, we take it back
             * and take the next move in the list */
            if (!MakeMove (moveBuf[i]))
                {
                    TakeBack ();
                    continue;
                }

            /* If we've reached this far, then we have a move available */
            havemove = 1;

            value = -Search(-beta, -alpha, depth - 1, &tmpMove, &line);

            /* We've evaluated the position, so we return to the previous position in such a way
               that when we take the next move from moveBuf everything is in order */
            TakeBack ();

            /* Once we have an evaluation, we use it in in an alpha-beta search */
            if (value > alpha)
                {
                    /* Este movimiento causo un cutoff, asi que incrementamos
                    el valor de historia para que sea ordenado antes la
                    proxima vez que se busque */
                    history[moveBuf[i].from][moveBuf[i].dest] += depth;

                    /* This move is so good and caused a cutoff */
                    if (value >= beta)
                        {
                            return beta;
                        }
                    alpha = value;
                    /* So far, current move is the best reaction for current position */
                    *pBestMove = moveBuf[i];

                    /* Update the principal line */
                    pline->argmove[0] = moveBuf[i];
                    memcpy(pline->argmove + 1, line.argmove, line.cmove * sizeof(MOVE));
                    pline->cmove = line.cmove + 1;
                }
        }

    /* Once we've checked all the moves, if we have no legal moves,
     * then that's checkmate or stalemate */
    if (!havemove)
        {
            if (IsInCheck (side))
                return -MATE + ply;	/* add ply to find the longest path to lose or shortest path to win */
            else
                return 0;
        }

    /* 3 vecez la misma posicion */
    if (reps() >= 2)
        return 0;

    if (fifty >= 100) /* 50 jugadas o mas */
        return 0;

    /* Finally we return alpha, the score value */
    return alpha;
}