示例#1
0
void State::makeMove(Move const & move) {
  FromTo const & fromTo = move.fromTo;
  movePiece(fromTo, &board);
  if (move.castle.from.file) {
    movePiece(move.castle, &board);
  }
  if (move.enPassCap.file) {
    getPieceRef(move.enPassCap, &board) = ' ';
  }
  if (move.promPiece) {
    getPieceRef(fromTo.to, &board) = makePiece(move.promPiece, turn);
  }
  turn = (State::WHITE == turn) ? State::BLACK : State::WHITE;
}
//quiescence search
int SimplePVSearch::qSearch(Board& board, SearchInfo& si) {
	if (stop(si)) {
		return 0;
	}
	if	(board.isDraw() || si.ply >= maxSearchPly-1) {
		return drawScore;
	}
	TranspositionTable::HashData hashData;
	MoveIterator::Move hashMove;
	const Key key = board.getKey();
	bool okToPrune=false;
	const int oldAlpha=si.alpha;
	// tt retrieve & prunning
	const bool hashOk = si.nodeType == PV_NODE ?
			agent->hashGet(okToPrune, key, hashData,
					si.ply, si.depth) :
					agent->hashGet(okToPrune, key, hashData,
							si.ply, si.depth, si.allowNullMove, si.alpha, si.beta);
	if (hashOk) {
		hashMove = hashData.move();
		if (okToPrune) {
			return hashData.value();
		}
	}
	const bool isKingAttacked = board.isInCheck();
	bool isLazyEval = false;
	int bestScore = -maxScore;
	int currentScore = -maxScore;
	if (!isKingAttacked) {
		if (hashOk && (hashData.flag() & TranspositionTable::NODE_EVAL)) {
			currentScore = hashData.evalValue();
		} else {
			currentScore=evaluator.evaluate(board,si.alpha,si.beta);
			isLazyEval = evaluator.isLazyEval();
		}
		bestScore=currentScore;
		if(bestScore>=si.beta) {
			if (!hashOk && !isLazyEval) {
				const TranspositionTable::NodeFlag flag = TranspositionTable::NODE_EVAL;
				agent->hashPut(key,bestScore,currentScore,-maxSearchPly,si.ply,flag,emptyMove);
			}
			return bestScore;
		}
		const int delta = board.isPawnPromoting()?getDeltaMargin(si.depth)*2:getDeltaMargin(si.depth);
		if (bestScore < si.alpha - delta && !(si.nodeType==PV_NODE) && hashMove.none() &&
				!isMateScore(si.beta)) {
			if (!hashOk && !isLazyEval) {
				const TranspositionTable::NodeFlag flag = TranspositionTable::NODE_EVAL;
				agent->hashPut(key,si.alpha,currentScore,-maxSearchPly,si.ply,flag,emptyMove);
			}
			return si.alpha;
		}
		if((si.nodeType==PV_NODE) && si.alpha<bestScore) {
			si.alpha = bestScore;
		}
	}
	int moveCounter=0;
	MoveIterator moves = MoveIterator();
	MoveIterator::Move bestMove=emptyMove;
	MoveIterator::Move move;
	const PieceColor sideToMove = board.getSideToMove();
	while (true)  {
		move = selectMove<true>(board, moves, hashMove, si.ply, si.depth);
		if (move.none()) {
			break;
		}
		const bool isHashMove = move.type==MoveIterator::TT_MOVE;
		const bool passedPawn = isPawnPush(board,move.to);
		const bool pawnOn7thRank = move.promotionPiece!=EMPTY;
		const bool allowFutility = !isKingAttacked && !(si.nodeType==PV_NODE) &&
				!isHashMove && !pawnOn7thRank;
		moveCounter++;
		if (move.promotionPiece==makePiece(sideToMove,ROOK) ||
				move.promotionPiece==makePiece(sideToMove,BISHOP)	) {
			continue;
		}
		if (allowFutility) {
			if (si.depth < qsOnlyRecaptureDepth && move.to != si.move.to) {
				continue;
			}
			if (move.type==MoveIterator::BAD_CAPTURE) {
				continue;
			}
		}
		MoveBackup backup;
		board.doMove(move,backup);
		const bool givingCheck = board.setInCheck(board.getSideToMove());
		if (move.promotionPiece==makePiece(sideToMove,KNIGHT) &&
				!givingCheck) {
			board.undoMove(backup);
			continue;
		}
		if (allowFutility && !board.isPawnFinal() && !passedPawn && !givingCheck ) {
			const int gain = materialValues[backup.capturedPiece];
			const int futilityScore = currentScore+gain+getFutilityMargin();
			if (futilityScore<si.alpha) {
				if (futilityScore>bestScore) {
					bestScore=futilityScore;
				}
				board.undoMove(backup);
				continue;
			}
		}
		SearchInfo newSi(false,move,-si.beta,-si.alpha,si.depth-1,
				si.ply+1,si.nodeType,si.splitPoint);
		int score = -qSearch(board, newSi);
		board.undoMove(backup);
		if (stop(si)) {
			return 0;
		}
		nodes++;
		if( score >= si.beta ) {
			const TranspositionTable::NodeFlag flag = currentScore!=-maxScore && !isLazyEval?
					TranspositionTable::LOWER_EVAL:TranspositionTable::LOWER;
			agent->hashPut(key,score,currentScore,si.depth!=0?-1:0,si.ply,flag,move);
			return score;
		}
		if (score>bestScore) {
			bestScore=score;
			if( score>si.alpha ) {
				si.alpha = score;
				bestMove=move;
			}
		}
	}
	if (!moveCounter && isKingAttacked) {
		return -maxScore+si.ply;
	}
	TranspositionTable::NodeFlag flag;
	if (bestScore>oldAlpha) {
		flag = currentScore!=-maxScore && !isLazyEval?
				TranspositionTable::EXACT_EVAL:TranspositionTable::EXACT;
	} else {
		flag = currentScore!=-maxScore && !isLazyEval?
				TranspositionTable::UPPER_EVAL:TranspositionTable::UPPER;
		bestMove=emptyMove;
	}
	agent->hashPut(key,bestScore,currentScore,si.depth!=0?-1:0,si.ply,flag,bestMove);
	return bestScore;
}