Пример #1
0
Move MoveGen::next()
{
    Move res;
loop:
    switch( *phPtr )
    {
    case mpHash:
        res = killer->hashMove;
        phPtr++;
        if ( !res || !(board.inCheck() ? board.isLegal<1,0>( res, pins() ) : board.isLegal<0,0>( res, pins() ) ) )
            goto loop;

        genMoves[ genMoveCount++ ] = res;
        break;
    case mpKiller1:
        res = killer->killers[0];
        phPtr++;
        if ( !res || alreadyGenerated(res) ||
                !(board.inCheck() ? board.isLegal<1,1>( res, pins() ) : board.isLegal<0,1>( res, pins() ) ) )
            goto loop;
        genMoves[ genMoveCount++ ] = res;
        break;
    case mpKiller2:
        res = killer->killers[1];
        phPtr++;
        if ( !res || alreadyGenerated(res) ||
                !(board.inCheck() ? board.isLegal<1,1>( res, pins() ) : board.isLegal<0,1>( res, pins() ) ) )
            goto loop;
        genMoves[ genMoveCount++ ] = res;
        break;
    case mpCapNoSort:
        count = generateCaptures( board, moveBuf );
        index = 0;
        phPtr++;
        goto loop;
        break;
    case mpCap:
        count = generateCaptures( board, moveBuf );
        index = badCapCount = 0;
        scoreCaptures();
        phPtr++;
        goto loop;
        break;
    case mpBadCap:
        index = 0;
        phPtr++;
        goto loop;
        break;
    case mpQCap:
        count = generateCaptures( board, moveBuf, 0 );
        index = 0;
        scoreCaptures();
        phPtr++;
        goto loop;
        break;
    case mpQChecks:
        count = board.turn() == ctWhite ?
                generateChecks< ctWhite >( moveBuf ) : generateChecks< ctBlack >( moveBuf );
        scoreChecks();
        index = 0;
        phPtr++;
        goto loop;
        break;
    case mpCastling:
        assert( board.canCastle() );
        index = 0;
        count = board.turn() == ctWhite ?
                generateCastling< ctWhite >( board, moveBuf )
                : generateCastling< ctBlack >( board, moveBuf );
        phPtr++;
        goto loop;
        break;
    case mpQuietNoSort:
        count = generateQuiet( board, moveBuf );
        index = 0;
        phPtr++;
        goto loop;
        break;
    case mpQuiet:
        count = generateQuiet( board, moveBuf );
        scoreQuiet();
        index = 0;
        phPtr++;
        goto loop;
        break;
    case mpEvasNoSort:
        count = generateEvasions( board, moveBuf );
        index = 0;
        phPtr++;
        goto loop;
        break;
    case mpEvas:
        count = generateEvasions( board, moveBuf );
        scoreEvasions();
        index = 0;
        phPtr++;
        goto loop;
        break;
    case mpCapBuffer:
        // here we'll ocassionally move to badcaps so it's different
        do
        {
loopcap:
            if ( index >= count )
            {
                phPtr++;
                goto loop;
            }
            res = moveBuf[ index++ ];

            if ( alreadyGenerated(res) )
                goto loopcap;

            // do fast(sign) see
            if ( board.see<1>(res) < 0 )
            {
                // bad capture detected
                assert( badCapCount < maxCaptures );
                badCaps[ badCapCount++ ] = res;
                goto loopcap;
            }
        } while( !board.pseudoIsLegal<0>( res, pin ) );
        break;
    case mpQCapBuffer:
        // here we'll ocassionally move to badcaps so it's different
        do
        {
qloopcap:
            if ( index >= count )
            {
                phPtr++;
                goto loop;
            }
            res = moveBuf[ index++ ];

            if ( alreadyGenerated(res) )
                goto qloopcap;

            // do fast(sign) see
            if ( board.see<1>( res ) < 0 )
                // bad capture detected
                goto qloopcap;
        } while( !board.pseudoIsLegal<0>( res, pin ) );
        break;
    case mpCastlingBuffer:
        if ( index >= count )
        {
            phPtr++;
            goto loop;
        }
        res = moveBuf[ index++ ];
        if ( alreadyGenerated(res) )
            goto loop;
        break;
    case mpCastlingBufferLegal:
        if ( index >= count )
        {
            phPtr++;
            goto loop;
        }
        res = moveBuf[ index++ ];
        break;
    case mpEvasBuffer:
        do
        {
            if ( index >= count )
            {
                phPtr++;
                goto loop;
            }
            res = moveBuf[ index++ ];
        } while ( alreadyGenerated(res) || !board.pseudoIsLegal<1>( res, pin ) );
        break;
    case mpEvasBufferLegal:
        do
        {
            if ( index >= count )
            {
                phPtr++;
                goto loop;
            }
            res = moveBuf[ index++ ];
        } while ( !board.pseudoIsLegal<1>( res, pin ) );
        break;
    case mpBufferLegal:
        do
        {
            if ( index >= count )
            {
                phPtr++;
                goto loop;
            }
            res = moveBuf[ index++ ];
        } while ( !board.pseudoIsLegal<0>( res, pin ) );
        break;
    case mpQuietBuffer:
        do
        {
            if ( index >= count )
            {
                phPtr++;
                goto loop;
            }
            res = moveBuf[ index++ ];
        } while ( alreadyGenerated(res) || !board.pseudoIsLegal<0>( res, pin ) );
        break;
    case mpQChecksBuffer:
        do
        {
checksloop:
            if ( index >= count )
            {
                phPtr++;
                goto loop;
            }
            res = moveBuf[ index++ ];
            if ( alreadyGenerated(res) )
                goto checksloop;
            if ( MovePack::isCastling(res) )
                break;
            if ( board.see<1>( res ) < 0 )
                continue;						// skip bad see checks
        } while ( !board.pseudoIsLegal<0>( res, pin ) );
        assert( board.isCheck( res, dcMask ) );
        break;
    case mpBadCapBuffer:
        do
        {
            if ( index >= badCapCount )
            {
                phPtr++;
                goto loop;
            }
            res = badCaps[ index++ ];
        } while( alreadyGenerated(res) || !board.pseudoIsLegal<0>( res, pin ) );
        break;
    default:			//case mpDone:
        res = mcNone;
        break;
    }
    return res & mmNoScore;				// remove score
}
Пример #2
0
void MovePicker::goNextPhase() {
	currMove_ = firstMove(); // legalMoves_[0] は番兵
	++phase_;

	switch (phase()) {
	case PH_TacticalMoves0: case PH_TacticalMoves1:
		lastMove_ = generateMoves<CapturePlusPro>(currMove(), pos());
		scoreCaptures();
		return;

	case PH_Killers:
		currMove_ = killerMoves_;
		lastMove_ = currMove() + 2;
		return;

	case PH_NonTacticalMoves0:
		lastMove_ = generateMoves<NonCaptureMinusPro>(currMove(), pos());
		scoreNonCapturesMinusPro<false>();
		currMove_ = lastMove();
		lastNonCapture_ = lastMove_ = generateMoves<Drop>(currMove(), pos());
		scoreNonCapturesMinusPro<true>();
		currMove_ = firstMove();
		lastMove_ = std::partition(currMove(), lastNonCapture(), HasPositiveScore());
		// 要素数は10個くらいまでであることが多い。要素数が少ないので、insertionSort() を使用する。
		insertionSort<MoveStack*, true>(currMove(), lastMove());
		return;

	case PH_NonTacticalMoves1:
		currMove_ = lastMove();
		lastMove_ = lastNonCapture();
		if (static_cast<Depth>(3 * OnePly) <= depth_) {
			std::sort(currMove(), lastMove(), std::greater<MoveStack>());
		}
		return;

	case PH_BadCaptures:
		currMove_ = legalMoves_ + MaxLegalMoves - 1;
		lastMove_ = endBadCaptures_;
		return;

	case PH_Evasions:
	case PH_QEvasions:
		lastMove_ = generateMoves<Evasion>(currMove(), pos());
		if (currMove() + 1 < lastMove()) {
			scoreEvasions();
		}
		return;

	case PH_QCaptures0:
		lastMove_ = generateMoves<CapturePlusPro>(firstMove(), pos());
		scoreCaptures();
		return;

	case PH_QCaptures1:
		lastMove_ = generateMoves<Recapture>(firstMove(), pos(), recaptureSquare_);
		scoreCaptures();
		return;

	case EvasionSearch: case QSearch: case QEvasionSearch: case QRecapture: case ProbCut:
		// これが無いと、MainSearch の後に EvasionSearch が始まったりしてしまう。
		phase_ = PH_Stop;

	case PH_Stop:
		lastMove_ = currMove() + 1;
		return;

	default: UNREACHABLE;
	}
}