コード例 #1
0
ファイル: chess.c プロジェクト: komendantyan-artem/chess
int quiescence(int alpha, int beta)
{
    int static_evaluation = evaluate(alpha, beta);
    if(static_evaluation >= beta)
        return beta;
    if(static_evaluation > alpha)
        alpha = static_evaluation;
    
    Move movelist[256];
    int n = generate_captures(movelist);
    sorting_captures(movelist, n);
    for(int i = 0; i < n; i += 1)
    {
        Move i_move = movelist[i];
        make_move(i_move);
        int score = -quiescence(-beta, -alpha);
        unmake_move(i_move);
        
        if(score >= beta)
        {
            return beta;
        }
        if(score > alpha)
        {
            alpha = score;
        }
    }
    return alpha;
}
コード例 #2
0
ファイル: chess.c プロジェクト: komendantyan-artem/chess
int PVS(int alpha, int beta, int depth)
{
    if(is_draw_by_repetition_or_50_moves()) return DRAW;
    
    if(depth == 0) return quiescence(alpha, beta);
    
    Move movelist[256];
    int n = generate_moves(movelist);
    if(n == 0)
    {
        if(!in_check(turn_to_move))
            return DRAW;
        return LOSING + ply - begin_ply;
    }
    sorting_moves(movelist, n);
    
    int bool_search_pv = 1;
    Move bestmove = 0;

    for(int i = 0; i < n; i += 1)
    {
        Move i_move = movelist[i];
        make_move(i_move);
        int score;
        if(bool_search_pv)
        {
            score = -PVS(-beta, -alpha, depth - 1);
        }
        else
        {
            score = -ZWS(-alpha, depth - 1, 1);
            if(score > alpha)
                score = -PVS(-beta, -alpha, depth - 1);
        }
        unmake_move(i_move);
        
        if(score >= beta)
        {
            hash_save_entry(depth, beta, i_move, MORE_THAN_BETA);
            if(!move_broken(i_move))
            {
                history[board[move_from(i_move)]][move_to(i_move)] = depth * depth;
            }
            return beta;
        }
        if(score > alpha)
        {
            bestmove = i_move;
            alpha = score;
        }
        bool_search_pv = 0;
    }
    if(bestmove != 0)
        hash_save_entry(depth, alpha, bestmove, BETWEEN_ALPHA_AND_BETA);
    else
        hash_save_entry(depth, alpha, 0, LESS_THAN_ALPHA);
    return alpha;
}
コード例 #3
0
ファイル: chess.c プロジェクト: komendantyan-artem/chess
int ZWS(int beta, int depth, int can_reduce)
{
    if(is_draw_by_repetition_or_50_moves()) return DRAW;
    
    Entry *entry = hash_get_entry();
    if(entry != NULL && entry->depth >= depth)
    {
        int eval = entry->eval, flag = entry->flag;
        if(flag != LESS_THAN_ALPHA && eval >= beta)
            return beta;
        if(flag != MORE_THAN_BETA && eval < beta)
            return beta - 1;
    }
    
    if(depth == 0) return quiescence(beta - 1, beta);
    
    /*if(depth <= 6 && evaluate(beta - 1, beta) >= beta)
    {
        return beta;
    }*/
    
    if(depth > 2 && can_reduce && !in_check(turn_to_move))
    {
        int R = depth > 6 ? 3: 2;
        make_null_move();
        int score = -ZWS(-beta + 1, depth - R - 1, 0);
        unmake_null_move();
        if(score >= beta) return beta;
    }
    
    Move movelist[256];
    int n = generate_moves(movelist);
    if(n == 0)
    {
        if(!in_check(turn_to_move))
            return DRAW;
        return LOSING + ply - begin_ply;
    }
    sorting_moves(movelist, n);
    for(int i = 0; i < n; i += 1)
    {
        Move i_move = movelist[i];
        make_move(i_move);
        int score = -ZWS(-beta + 1, depth - 1, can_reduce);
        unmake_move(i_move);
        
        if(score >= beta)
        {
            hash_save_entry(depth, beta, i_move, MORE_THAN_BETA);
            return beta;
        }
    }
    hash_save_entry(depth, beta - 1, 0, LESS_THAN_ALPHA);
    return beta - 1;
}
コード例 #4
0
ファイル: search.c プロジェクト: toddsdk/chessdbot
/* Quiescence Search */
move_t quiescence(board_t *b, int32_t alpha, int32_t beta) {
    uint8_t i;
    move_t m, best;
    move_list_t *list;
    
    /* Initialize the best possible move as blank */
    SET_BLANK_MOVE(best);

    m.eval = heuristic(b, onmove);
    if(m.eval >= beta) {
    	best.eval = m.eval;
    	return best;
    } else if(m.eval > alpha) {
    	alpha = m.eval;
    }

    /* Get the next possible Good captures only */
    list = gen_move_list(b, TRUE);

    /*TODO: Re-order the move list (SEE - Static Exchange Eval) */
    /*reorder_move_list(b, list); */

    /* For each possible next move... */
    for(i = 0; i < list->size; i++) {
    	/* Let's see the board after that move... */
    	move(b, list->move[i]);

    	/* Quiescence Search recursion */
    	m = quiescence(b, -beta, -alpha);
    	m.eval = -m.eval;

    	/* Restores the previous board (before the possible move) */
    	unmove(b);

    	/* Beta cutoff */
    	if(m.eval >= beta) {
    	    best = list->move[i];
    	    best.eval = m.eval;
    	    break;
    	/* Alpha cutoff */
    	} else if(m.eval > alpha) {
    	    best = list->move[i];
    	    alpha = best.eval = m.eval;
    	/* Best possible move until now */
    	} else if(i == 0 || m.eval > best.eval) {
    	    best = list->move[i];
    	    best.eval = m.eval;
    	}
    }

    /* Clear temporary information and return */
    clear_move_list(list);
    return best;
}
コード例 #5
0
ファイル: search.cpp プロジェクト: Saulzar/sprangulator
int Board::alphaBeta(int depthLeft, int alpha, int beta, int doNullMove) {
	int check = 0;
	int oldAlpha = alpha;
	int numSearched = 0;
	int bestMove = 0;
	int hashMove = 0;
	int stage;
	int i = currentState->firstMove;
	int result;

	nodes++;
	nodesUntilUpdate--;
	if(nodesUntilUpdate <= 0) {
		switch(game->interfaceUpdate()) {
			case OUT_OF_TIME:

				abortingSearch = 1;
				return 0;
			break;

			case STOP_SEARCH:
				abortingSearch = 1;
				return 0;
			break;
		}

		nodesUntilUpdate = nodesPerUpdate;
	}



	if(isRepetition()) {
		returnMove = 0;
		return DRAW;
	}


	HashEntry *e;
	e = hash->probe(currentState->hashKey);

	if(e!=NULL) {
		hashHits++;
		//Is it useful for replacing this search - otherwise just find a best move
		hashMove = e->bestMove;
		returnMove = hashMove;

#ifndef DISABLE_HASH
		if(depth > 0 && e->depth >= depthLeft) {
			switch(e->flags & 3) {
				case HASH_EXACT:
					return e->score;
				break;

				case HASH_LOWER:
					if(e->score >= beta) return e->score;
					if(e->score > alpha) alpha = e->score;
				break;

				case HASH_UPPER:
					if(e->score <= alpha) return e->score;
					if(e->score < beta) beta = e->score;
				break;
			}

			if(e->flags & HASH_NO_NULL) {
				doNullMove = 0;
			}
		}
#endif
	}

#ifdef DEBUG_HASH
	if(hashMove > 0 && !testLegality(hashMove)) {
		print();
		cout << "Illegal hash move! ";
		printMove(hashMove);
		cout << endl;
	}
#endif


	if(depthLeft == 0) {
		int value =  quiescence(alpha, beta);
		//hash->store(0, value, 0, HASH_EXACT);
		return value;
	}


	check = inCheck();

/*
	if(doNullMove && !check && !nullRisk() && depth >= 2) {
		int nullDepth = depthLeft - 2;

		makeNullMove();

		if(nullDepth > 0) {
			result = alphaBeta(nullDepth, -beta, -beta+1, NO_NULL_MOVE);
		} else {
			result = quiescence(-beta, -beta+1);
		}

		retractNullMove();

		if(nullDepth > 0 && result >= beta) {
			result = alphaBeta(nullDepth, beta-1, beta, DO_NULL_MOVE);
			numMoves = currentState->firstMove;
		}


		if(result >= beta) {
			returnMove = 0;
			return beta;
		}
	}
*/

	if(!hashMove && depthLeft >= 3) {
		result = alphaBeta(depthLeft - 2, alpha, beta, DO_NULL_MOVE);
		numMoves = currentState->firstMove;

		//Failed low so have to research with new bounds
		if(result <= alpha) result = alphaBeta(depthLeft - 2, -MATE, alpha + 1, DO_NULL_MOVE);
		numMoves = currentState->firstMove;

		hashMove = returnMove;
	}

	if(hashMove > 0) {
		stage = HASH_MOVE;
	}	else {
		stage = ALL_MOVES;
	}

	while(stage != FINISHED) {
		switch(stage) {
			case HASH_MOVE:
				moveStack[numMoves++] = hashMove;
				stage = ALL_MOVES;
			break;
			case  ALL_MOVES:
				if(check) {
					generateCheckEvasions();
					sortNonCaptures(i, hashMove);
					stage = FINISHED;
				} else {
					generateCaptures();
					sortCaptures(i, hashMove);
					stage = NON_CAPTURES;
				}
			break;
			case NON_CAPTURES:
				generateNonCaptures();
				sortNonCaptures(i, hashMove);
				stage = FINISHED;
			break;
		}

	for(; i<numMoves; i++) {
			int move = moveStack[i];
			makeMove(move);

#ifdef DEBUG_BITBOARDS
				if(isMessedUp()) {
					printMoves();
					print();
					cout << "Hash move = "; printMove(hashMove); cout << endl;
					cout << "MakeMove" << endl;
					exit(0);
				}
#endif

			if(isLegal())  {
				numSearched++;

				result = -alphaBeta(depthLeft - 1, -beta, -alpha, DO_NULL_MOVE);
				retractMove(move);

				if(abortingSearch) {
					returnMove = bestMove;
					return result;
				}

				if(result > alpha) {
					if(result >= beta) {
						returnMove = move;
						hash->store(move, result, depthLeft, HASH_LOWER);

#ifdef EXTRA_STATS
						cutoffs++;
						if(i == currentState->firstMove) firstCutoffs++;
#endif
						return result;
					}


/*					if(depth == 0) {
						printMove(move);
						cout << " ";
						printScore(result);
						cout << " hashMove: ";
						printMove(hashMove);
						cout << endl;
					}*/

					alpha = result;
					bestMove = move;
				}


			} else { //Illegal move
				retractMove(move);
			}
#ifdef DEBUG_BITBOARDS
			if(isMessedUp()) {
				printMoves();
				print();
				cout << "Hash move = "; printMove(hashMove); cout << endl;
				cout << "RetractMove" << endl;
				exit(0);
			}
#endif
		}
	}		//While we have moves

		//No legal moves..
	if(numSearched ==0) {
		returnMove = 0;

		if(check)	{
			 return -(MATE - depth);
		} else {
			return DRAW;
		}
	}


	if(alpha == oldAlpha) {
		hash->store(bestMove, alpha, depthLeft, HASH_UPPER);

	} else {
		hash->store(bestMove, alpha, depthLeft, HASH_EXACT);
	}

	returnMove = bestMove;
	return alpha;
}
コード例 #6
0
int BOARD::quiescence(int alpha,int beta)
{
	if((info.nodes & 2047) ==0)
	check();

	info.nodes++;
	
	if(repeat() || fifty >=100)
	return 0;

	if(ply >MAXDEPTH -1)
	return evaluate();

	int value=evaluate();
	if(value >= beta)
	return beta;
	
	if(value >alpha)
	alpha=value;
	
	int legal=0;
	int oldalpha=alpha;
	int bestmove=NOMOVE;
	int score=-INFINITE;

	MOVE_LIST moveList;
	moveList.count=0;
	generateAllCap(moveList);
	
	
	std::sort(moveList.l,moveList.l+moveList.count,so);

	for(int i=0;i<moveList.count;i++)
	{
		//pickBest(i,moveList);
		if(!makeMove(moveList.l[i].move))
		continue;
		score=-quiescence(-beta,-alpha);
		unmakeMove();

		if(info.stopped)
		return 0;

		legal++;
		if(score >alpha)
		{
			if(score >=beta)
			{
				if(legal==1)
				info.fhf++;
				info.fh++;
			return beta;	//beta - cutoff
			}
			alpha=score;
			bestmove=moveList.l[i].move;
		}		
	}
	if(alpha != oldalpha)
	storePv(bestmove);
	
	return alpha;	
}
コード例 #7
0
int BOARD::alphabeta(int depth,int alpha,int beta,bool donull)
{
	if(depth==0)
	{ 
		//info.nodes++;
		return quiescence(alpha,beta);
		//return evaluate();
	}

	
	if((info.nodes & 2047) == 0)
	check();
	info.nodes++;
	

	
	if((repeat() || fifty >=100) & ply)
	return 0;

	if(ply >MAXDEPTH -1)
	return evaluate();
	
		bool kingsafe;
		int pos=(int)log2(board[side+4] & -board[side+4]);
		kingsafe=isSafe(pos,side);
		if(!kingsafe)
		depth++;
	
	int score = -INFINITE;
	
/*	if(donull && ply && kingsafe && depth >4 && bigPiece[side] >0)
	{
		makeNullMove();
		score=-alphabeta(depth-4,-beta,-beta+1,false);
		unmakeNullMove();
		if(info.stopped)
		return 0;
		
		if(score>=beta)
		return beta;
	}*/
	
	int legal=0;
	int oldalpha=alpha;
	int bestmove=NOMOVE;
	score=-INFINITE;
	MOVE_LIST moveList;
	moveList.count=0;
	generateAllMoves(moveList);
	

	int pvMove=getPvMove();
	if(pvMove != NOMOVE)
	{
		for(int i=0;i<moveList.count;i++)
		{
			if(moveList.l[i].move == pvMove)
			{
				moveList.l[i].score=2000000;
				break;			
			}
		}
	}

	std::sort(moveList.l,moveList.l+moveList.count,so);

	for(int i=0;i<moveList.count;i++)
	{
		//pickBest(i,moveList);
		if(!makeMove(moveList.l[i].move))
		continue;
		legal++;
		score=-alphabeta(depth-1,-beta,-alpha,donull);
		unmakeMove();

		if(info.stopped)
		return 0;
		
		if(score >alpha)
		{
			if(score >=beta)
			{
				if(legal==1)
				info.fhf++;
				info.fh++;
			if(CAP(moveList.l[i].move) == EMPTY)
			{
				searchKillers[1][depth]=searchKillers[0][depth];
				searchKillers[0][depth]=moveList.l[i].move;				
			}
			return beta;	//beta - cutoff
			}
			alpha=score;
			bestmove=moveList.l[i].move;
			if(CAP(moveList.l[i].move) == EMPTY)
			searchHistory[cboard[FROM(bestmove)]][TO(bestmove)]+=depth;
		}		
	}

	if(legal == 0)
	{
		if(!kingsafe)
		return -MATE + ply;
		else
		return 0;
	}

	if(alpha != oldalpha)
	storePv(bestmove);
	
	return alpha;
}