Пример #1
0
// the quiescence search
int Quiece(board_t *brd, int alpha, int beta, searchinfo_t *sinfo)
{
	if(!(sinfo->nodes & 0xfff)) CheckUp(sinfo);

	sinfo->nodes++;

	ASSERT(CheckBrd(brd));

	//if((IsRep(brd) || brd->fifty >= 100) && brd->ply) return 0;
	if(brd->ply >= MAXDEPTH-1) return Eval(brd);

	int score = Eval(brd);

	// we are probably not going to make our position worse by moving so we can say:
	if(score >= beta){	// if we are doing already too good
		return beta;	// we have a beta cutoff and we return
	}
	if(score > alpha){	// if we are better than alpha
		alpha = score;	// then we can set our minimum alpha to the score
	}

	mlist_t list;
	int i;
	score = -INFINITE;

	GenCaps(brd, &list);	// Generate all capture moves

	for(i = 0; i < list.len; i++)	// Loop through the moves
	{
		if(sinfo->stop) return 0;

		SelectNextMove(&list, i);

		if(!MakeMove(brd, list.move[i].move)) continue;

		score = -Quiece(brd, -beta, -alpha, sinfo);

		TakeBack(brd);

		if(score > alpha){
			if(score >= beta){
				return beta;
			}
			alpha = score;
		}
	}

	return alpha;
}
Пример #2
0
// buscamos capturas y jaques y analizamos las posibilidades de escape.
int CPartida::Quiesce(int alpha,int beta)
{
	int value,a;

	
	if(cancelado + (stHistory >> 6)) // si llenamos el pozo lo dejamos en tablas
	{
		return Taux.Evalua();
	}

	IncNodesQ();

	u64 hash = Taux.GetHash();

	int Valor_i;

	Valor_i = Taux.Evalua();
	// Vamos con material de sobra
	if(Valor_i >= beta ) 	{		return Valor_i;	}



	a = alpha;
	if(Valor_i > alpha )		a = Valor_i;
	value = a;	alpha = a;

	SetHashHistory(hash);
	CJugada J;
	int legales = 0;

	CSort Sort;
	Sort.Init(Taux,true);

	for(J = Sort.GetNextQ();J.ToInt();J = Sort.GetNextQ())
	{
		if(cancelado)			break;
		if(J.desglose.captura == rey)
		{
			a = ValorMate(1);
			PopHistory();
			return a;
		}

		if(J.desglose.peso < (PesoCaptura+PesoCapturaBuena))			continue;

		Move(J);
		if(!Taux.EsAtacada(Taux.PosReyes[Taux.ColorJuegan^1],Taux.ColorJuegan^1) )
		{
			legales++;
			value = -Quiesce(-beta, -a);
		}
		TakeBack();
		if(value > a) 
		{
			a = value;
			if(a >= beta ) 
			{
				break;
			}
		}	
	} // for

	PopHistory();
	return ( a );   
}
Пример #3
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;
}
Пример #4
0
int AlphaBeta(board_t *brd, int alpha, int beta, int depth, searchinfo_t *sinfo, int null)
{
	if(depth == 0){
		//return Eval(brd);
		return Quiece(brd, alpha, beta, sinfo);
	}

	if(!(sinfo->nodes & 0xfff)) CheckUp(sinfo);

	sinfo->nodes++;

	ASSERT(CheckBrd(brd));

	// if we are not the root of the tree and we have a repetition
	// or we exceeded the fifty move rule, then we have a draw and return 0
	if((IsRep(brd) || brd->fifty >= 100) && brd->ply) return 0;
	if(brd->ply >= MAXDEPTH-1) return Eval(brd);	// if we are too deep, we return

	// test if we are in check
	int check = SqAttacked(brd, LOCATEBIT(brd->bb[brd->side][King]), brd->side^1);
	if(check) depth++;

	int score = -INFINITE;
	int pvMain = NO_MOVE;
	// check the transposition table if we have searched the current position before
	// if so, return what we found
	if(TestHashTable(brd, &pvMain, &score, alpha, beta, depth)) return score;

	// Before we search, we try how we do if we don't make a move
	// i.e. make a null move
	if( null && !check && brd->ply && depth >= 4 &&
		(brd->all[brd->side]^brd->bb[brd->side][Pawn]^brd->bb[brd->side][King]) )
	{
		MakeMoveNull(brd);
		// We cannot do two null moves in a row so we set the null argument here to false
		score = -AlphaBeta(brd, -beta, -beta + 1, depth-4, sinfo, false);
		TakeBackNull(brd);

		if(sinfo->stop){
			return 0;
		}
		if(score >= beta){
			return beta;
		}
	}

	mlist_t list;
	int i;
	int legal = 0;
	int bestMove = NO_MOVE;
	int bestScore = -INFINITE;
	int oldAlpha = alpha;
	score = -INFINITE;

	GenMoves(brd, &list);

	// we tested our transposition table for the best move 'pvMain'
	// if it exists we will set this move as the first move to be searched
	if(pvMain != NO_MOVE){

		if(MakeMove(brd, pvMain)){
			score = -AlphaBeta(brd, -beta, -alpha, depth-1, sinfo, true);
			TakeBack(brd);

			bestScore = score;
			if(score > alpha){
				if(score >= beta){
					if(!(pvMain & FLAGCAP)){
						brd->betaMoves[1][brd->ply] = brd->betaMoves[0][brd->ply];
						brd->betaMoves[0][brd->ply] = pvMain;
					}
					return beta;
				}
				alpha = score;
				bestMove = pvMain;
			}
		}
		/*/
		for(i = 0; i < list.len; i++){
			if(list.move[i].move == pvMain){
				list.move[i].score = 5000000;
				break;
			}
		}//*/
	}

	for(i = 0; i < list.len; i++) // Loop through all moves
	{
		if(sinfo->stop) return 0;

		SelectNextMove(&list, i);

		if(!MakeMove(brd, list.move[i].move)) continue;

		legal++; // we have found a legal move so we need not check for mate afterwards
		// call AlphaBeta in a negamax fashion
		score = -AlphaBeta(brd, -beta, -alpha, depth-1, sinfo, true);
		TakeBack(brd);

		if(score > bestScore){
			bestScore = score;
			if(score > alpha){
				if(score >= beta){
					if(legal==1) sinfo->fhf++; 	// count the number of beta cutoffs searched first
					sinfo->fh++;				// compared to all beta cutoffs (measure of efficiency)
					if(!(list.move[i].move & FLAGCAP)){
						brd->betaMoves[1][brd->ply] = brd->betaMoves[0][brd->ply];
						brd->betaMoves[0][brd->ply] = list.move[i].move;
					}
					// Store the move in the transposition table as a beta (killer) move
					StorePvMove(brd, bestMove, depth, beta, HFBETA);
					return beta;
				}
				alpha = score;
				bestMove = list.move[i].move;
			}
		}
	}
	if(legal == 0){ // We havn't found a legal move
		if(check){
			// if we are in check it is mate; but we want the shortest path
			// to it so we'll subtract the path length
			return -MATE + brd->ply;
		}
		return 0; // Stalemate
	}

	if(oldAlpha != alpha){
		// Store exact (normal) transposition entry
		StorePvMove(brd, bestMove, depth, bestScore, HFEXACT);
	}
	else {
		// Store alpha cutoff transposition entry
		StorePvMove(brd, bestMove, depth, alpha, HFALPHA);
	}

	return alpha;
}
Пример #5
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;
}