virtual inline void DoFutilityPruning01( bool& isContinue, bool& INCHECK, bool& givesCheck, Move& move, Move& ttMove, ScoreIndex& futilityScore, ScoreIndex& futilityBase, Position& pos, ScoreIndex& beta, ScoreIndex& bestScore, const Depth depth )const override { // 非PVノードのとき☆(^q^) if (!INCHECK // 駒打ちは王手回避のみなので、ここで弾かれる。 && !givesCheck && move != ttMove) { futilityScore = futilityBase + PieceScore::GetCapturePieceScore(pos.GetPiece(move.To())); if (move.IsPromotion()) { futilityScore += PieceScore::GetPromotePieceScore(move.GetPieceTypeFrom()); } if (futilityScore < beta) { bestScore = std::max(bestScore, futilityScore); isContinue = true; return; } // todo: MovePicker のオーダリングで SEE してるので、ここで SEE するの勿体無い。 if (futilityBase < beta && depth < Depth0 && ( pos.GetTurn()==Color::Black ? pos.GetSee1<Color::Black,Color::White>(move, beta - futilityBase) : pos.GetSee1<Color::White,Color::Black>(move, beta - futilityBase) ) <= ScoreZero) { bestScore = std::max(bestScore, futilityBase); isContinue = true; return; } } }
Key Book::GetBookKey(const Position& pos) { Key key = 0; Bitboard bb = pos.GetOccupiedBB(); while (bb.Exists1Bit()) { const Square sq = bb.PopFirstOneFromI9(); key ^= m_ZobPiece[pos.GetPiece(sq)][sq]; } const Hand hand = pos.GetHand(pos.GetTurn()); for (HandPiece hp = HPawn; hp < HandPieceNum; ++hp) { key ^= m_ZobHand[hp][hand.NumOf(hp)]; } if (pos.GetTurn() == White) { key ^= m_ZobTurn; } return key; }
MoveAndScoreIndex Book::GetProbe(const Position& position, const std::string& fName, const bool pickBest) { BookEntry entry; u16 best = 0; u32 sum = 0; Move move = g_MOVE_NONE;//該当なしのときに使う値☆ const Key key = this->GetBookKey(position); const ScoreIndex min_book_score = static_cast<ScoreIndex>(static_cast<int>(position.GetRucksack()->m_engineOptions["Min_Book_Score"])); ScoreIndex score = ScoreZero; if (this->m_fileName_ != fName && !this->OpenBook(fName.c_str())) { // 定跡ファイルが開けなかった場合☆ return MoveAndScoreIndex(g_MOVE_NONE, ScoreNone); } Binary_search(key); // 現在の局面における定跡手の数だけループする。 while (read(reinterpret_cast<char*>(&entry), sizeof(entry)), entry.m_key == key && good()) { best = std::max(best, entry.m_count); sum += entry.m_count; // 指された確率に従って手が選択される。 // count が大きい順に並んでいる必要はない。 if (min_book_score <= entry.m_score && ((m_random_.GetRandom() % sum < entry.m_count) || (pickBest && entry.m_count == best))) { const Move tmp = Move(entry.m_fromToPro); const Square to = tmp.To(); if (tmp.IsDrop()) { const PieceType ptDropped = tmp.GetPieceTypeDropped(); move = ConvMove::Convert30_MakeDropMove_da(ConvMove::FROM_PIECETYPE_DA10(ptDropped), to); } else { // 定跡の手(持ち駒以外)を、ムーブの書式に変換している??(^q^)? const Square from = tmp.From(); const Move fromMove = ConvMove::FROM_PIECETYPE_ONBOARD10(ConvPiece::TO_PIECE_TYPE10(position.GetPiece(from))); if (tmp.IsPromotion()) { move = UtilMovePos::BUILD_CARD_CAPTURE_PROMOTE(position,fromMove, from, to); } else { move = UtilMovePos::BUILD_CARD_CAPTURE(position, fromMove, from, to); } } score = entry.m_score; } } return MoveAndScoreIndex(move, score); }