int Search::printDtm() { int side = getSide(); u64 friends = side == WHITE ? getBitmap<WHITE>() : getBitmap<BLACK>(); u64 enemies = side == BLACK ? getBitmap<WHITE>() : getBitmap<BLACK>(); display(); int res = side ? getGtb().getDtm<WHITE, true>(chessboard, chessboard[RIGHT_CASTLE_IDX], 100) : getGtb().getDtm<BLACK, true>(chessboard, chessboard[RIGHT_CASTLE_IDX], 100); cout << " res: " << res; incListId(); generateCaptures(side, enemies, friends); generateMoves(side, friends | enemies); _Tmove *move; u64 oldKey = 0; cout << "\n succ. \n"; int best = -_INFINITE; for (int i = 0; i < getListSize(); i++) { move = &gen_list[listId].moveList[i]; makemove(move, false, false); cout << "\n" << decodeBoardinv(move->type, move->from, getSide()) << decodeBoardinv(move->type, move->to, getSide()) << " "; res = side ? -getGtb().getDtm<BLACK, true>(chessboard, chessboard[RIGHT_CASTLE_IDX], 100) : getGtb().getDtm<WHITE, true>(chessboard, chessboard[RIGHT_CASTLE_IDX], 100); if (res != -INT_MAX) { cout << " res: " << res; } cout << "\n"; takeback(move, oldKey, false); if (res > best) { best = res; } } if (best > 0) { best = _INFINITE - best; } else if (best < 0) { best = -(_INFINITE - best); } cout << endl; decListId(); return best; }
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 }
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; }
Move MoveGen::next() { Move res; loop: switch( *phPtr ) { case mpCapNoSort: count = generateCaptures( board, moveBuf ); 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 mpEvasNoSort: count = generateEvasions( board, moveBuf ); index = 0; phPtr++; goto loop; break; case mpCastlingBuffer: if ( index >= count ) { phPtr++; goto loop; } res = moveBuf[ index++ ]; break; case mpEvasBuffer: do { if ( index >= count ) { phPtr++; goto loop; } res = moveBuf[ index++ ]; } while ( !board.pseudoIsLegal<1>( res, pin ) ); break; case mpCapBufferNoSort: case mpQuietBuffer: do { if ( index >= count ) { phPtr++; goto loop; } res = moveBuf[ index++ ]; } while ( !board.pseudoIsLegal<0>( res, pin ) ); break; default: //case mpDone: res = mcNone; break; } return res & mmNoScore; // remove score }