本文整理汇总了C++中TTEntry类的典型用法代码示例。如果您正苦于以下问题:C++ TTEntry类的具体用法?C++ TTEntry怎么用?C++ TTEntry使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了TTEntry类的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ASSERT_LV3
void RootMove::insert_pv_in_tt(Position& pos) {
StateInfo state[MAX_PLY], *st = state;
bool ttHit;
// 細かいことだがpvのtailから前方に向かって置換表に書き込んでいくほうが、
// pvの前のほうがエントリーの価値が高いので上書きされてしまう場合にわずかに得ではある。
// ただ、現実的にはほとんど起こりえないので気にしないことにする。
for (Move m : pv)
{
// 銀の不成の指し手をcounter moveとして登録して、この位置に角が来ると
// 角の不成の指し手を生成することになるからLEGALではなくLEGAL_ALLで判定しないといけない。
ASSERT_LV3(MoveList<LEGAL_ALL>(pos).contains(m));
TTEntry* tte = TT.probe(pos.state()->key(), ttHit);
// 正しいエントリーは書き換えない。
if (!ttHit || tte->move() != m)
tte->save(pos.state()->key(), VALUE_NONE, BOUND_NONE, DEPTH_NONE,
m,
#ifndef NO_EVAL_IN_TT
VALUE_NONE,
#endif
TT.generation());
pos.do_move(m, *st++);
}
for (size_t i = pv.size(); i > 0; )
pos.undo_move(pv[--i]);
}
示例2: extract_ponder_from_tt
bool RootMove::extract_ponder_from_tt(Position& pos,Move ponder_candidate)
{
StateInfo st;
bool ttHit;
// ASSERT_LV3(pv.size() == 1);
// 詰みの局面が"ponderhit"で返ってくることがあるので、ここでのpv[0] == MOVE_RESIGNであることがありうる。
if (!is_ok(pv[0]))
return false;
pos.check_info_update();
pos.do_move(pv[0], st, pos.gives_check(pv[0]));
TTEntry* tte = TT.probe(pos.state()->key(), ttHit);
Move m;
if (ttHit)
{
m = tte->move(); // SMP safeにするためlocal copy
if (MoveList<LEGAL_ALL>(pos).contains(m))
goto FOUND;
}
// 置換表にもなかったので以前のiteration時のpv[1]をほじくり返す。
m = ponder_candidate;
if (MoveList<LEGAL_ALL>(pos).contains(m))
goto FOUND;
pos.undo_move(pv[0]);
return false;
FOUND:;
pos.undo_move(pv[0]);
pv.push_back(m);
// std::cout << m << std::endl;
return true;
}
示例3: pos
void
TranspositionTable::extractPVMoves(const Position& rootPos, const Move& mFirst, std::vector<Move>& pv) {
Position pos(rootPos);
Move m(mFirst);
UndoInfo ui;
std::vector<U64> hashHistory;
while (true) {
pv.push_back(m);
pos.makeMove(m, ui);
if (contains(hashHistory, pos.zobristHash()))
break;
hashHistory.push_back(pos.zobristHash());
TTEntry ent;
ent.clear();
probe(pos.historyHash(), ent);
if (ent.getType() == TType::T_EMPTY)
break;
ent.getMove(m);
MoveList moves;
MoveGen::pseudoLegalMoves(pos, moves);
MoveGen::removeIllegal(pos, moves);
bool contains = false;
for (int mi = 0; mi < moves.size; mi++)
if (moves[mi].equals(m)) {
contains = true;
break;
}
if (!contains)
break;
}
}
示例4:
void
TranspositionTable::clear() {
hashMask = table.size() - 1;
tbGen.reset();
notUsedCnt = 0;
TTEntry ent;
ent.clear();
for (size_t i = 0; i < table.size(); i++)
ent.store(table[i]);
}
示例5: rateMoves
void MoveOrdering::rateMoves(std::vector<Move>& moveList, std::shared_ptr<Board> board, const unsigned int ply, const bool isSEE)
{
TTEntry* ttEntry = globalTT.probeTT(board->key, 0); // returns non nullpr if key exists and depth is greater
Move hashMove = Move();
if(ttEntry)
{
hashMove = ttEntry->getBestmove();
}
for(Move& move : moveList)
{
unsigned int score=0;
if(move==hashMove)
{
score += 100000;
}
if(move.isPromotion())
{
score += Eval::pieceTypeToValue(move.getPromotedPieceType())-Piece::PAWN_VALUE;
}
if(move.isCapture())
{
if(isSEE)
{
score += board->seeCapture(move, Utils::getOppositeColor(board->getColorToPlay()));
}
else
{
// MVV/LVA
score += Eval::pieceTypeToValue(move.getCapturedPieceType())-move.getPieceType();
}
}
if (move == myKiller1[ply])
{
score += KILLER1_BONUS;
}
if (move == myKiller2[ply])
{
score += KILLER2_BONUS;
}
move.setMoveRating(score);
}
}
示例6: if
// Transposition Table look up + alpha/beta update
TTLookupValue AlphaBeta::TTlookup(const GameState & state, AlphaBetaScore & alpha, AlphaBetaScore & beta, const size_t & depth)
{
TTEntry * entry = _TT->lookupScan(state.calculateHash(0), state.calculateHash(1));
if (entry && (entry->getDepth() == depth))
{
// get the value and type of the entry
AlphaBetaScore TTvalue = entry->getScore();
// set alpha and beta depending on the type of entry in the TT
if (entry->getType() == TTEntry::LOWER)
{
if (TTvalue > alpha)
{
alpha = TTvalue;
}
}
else if (entry->getType() == TTEntry::UPPER)
{
if (TTvalue < beta)
{
beta = TTvalue;
}
}
else
{
printf("LOL\n");
alpha = TTvalue;
beta = TTvalue;
}
if (alpha >= beta)
{
// this will be a cut
_results.ttcuts++;
return TTLookupValue(true, true, entry);
}
else
{
// found but no cut
_results.ttFoundNoCut++;
return TTLookupValue(true, false, entry);
}
}
else if (entry)
{
_results.ttFoundLessDepth++;
return TTLookupValue(true, false, entry);
}
return TTLookupValue(false, false, entry);
}
示例7: while
void
TranspositionTable::printStats(int rootDepth) const {
int unused = 0;
int thisGen = 0;
std::vector<int> depHist;
for (size_t i = 0; i < table.size(); i++) {
TTEntry ent;
ent.load(table[i]);
if (ent.getType() == TType::T_EMPTY) {
unused++;
} else {
if (ent.getGeneration() == generation)
thisGen++;
int d = ent.getDepth();
while ((int)depHist.size() <= d)
depHist.push_back(0);
depHist[d]++;
}
}
double w = 100.0 / table.size();
std::stringstream ss;
ss.precision(2);
ss << std::fixed << "hstat: d:" << rootDepth << " size:" << table.size()
<< " unused:" << unused << " (" << (unused*w) << "%)"
<< " thisGen:" << thisGen << " (" << (thisGen*w) << "%)" << std::endl;
cout << ss.str();
for (size_t i = 0; i < depHist.size(); i++) {
int c = depHist[i];
if (c > 0) {
std::stringstream ss;
ss.precision(2);
ss << std::setw(4) << i
<< ' ' << std::setw(8) << c
<< " " << std::setw(6) << std::fixed << (c*w);
std::cout << "hstat:" << ss.str() << std::endl;
}
}
}
示例8: type
// Transposition Table save
void AlphaBeta::TTsave( GameState & state, const AlphaBetaScore & value, const AlphaBetaScore & alpha, const AlphaBetaScore & beta, const size_t & depth,
const IDType & firstPlayer, const AlphaBetaMove & bestFirstMove, const AlphaBetaMove & bestSecondMove)
{
// IF THE DEPTH OF THE ENTRY IS BIGGER THAN CURRENT DEPTH, DO NOTHING
TTEntry * entry = _TT->lookupScan(state.calculateHash(0), state.calculateHash(1));
bool valid = entry && entry->isValid();
size_t edepth = entry ? entry->getDepth() : 0;
_results.ttSaveAttempts++;
if (valid && (edepth > depth))
{
return;
}
int type(TTEntry::NONE);
if (value <= alpha) type = TTEntry::UPPER;
else if (value >= beta) type = TTEntry::LOWER;
else type = TTEntry::ACCURATE;
// SAVE A NEW ENTRY IN THE TRANSPOSITION TABLE
_TT->save(state.calculateHash(0), state.calculateHash(1), value, depth, type, firstPlayer, bestFirstMove, bestSecondMove);
}
示例9: checkTime
// 基本思考ルーチン::depthMax手読み
int AI::think(LightField &self, LightField &enemy, int depth, int timeLimit)
{
if (calls_count++ > 1000)
{
checkTime();
calls_count = 0;
}
// rootからの手数
int ply = depth_max_ - depth;
#ifdef HASH
TTEntry *tte;
// 同一局面が発生するのは2手目以降しかありえない。
if (ply > 0)
{
bool tt_hit = TT.probe<true>(&self, nullptr, tte);
// 局面が登録されていた
if (tt_hit)
{
assert(tte->depth() >= 0);
// 局面表に登録されている局面が、現在の局面の残り深さ以上
if (tte->depth() >= depth)
{
best_[depth] = tte->move();
// 局面表のスコアは信用できるのでそのまま返す
return tte->score();
}
}
}
#endif
if (depth <= DEPTH_ZERO)
return evalate(self, enemy, depth, timeLimit);
else
{
int score;
int max = -SCORE_INFINITE - 1;
int movenum;
int con_prev[3];
self.saveConnect(con_prev);
Move move[22];// おける場所は最大で22種類なので
// 置く場所なし == 負け
if ((movenum = self.generateMoves(move)) == 0)
return -SCORE_INFINITE;
self.nextPlus();
#if defined(DEBUG)
LightField f = self;// debug
#endif
for (int i = 0; i < movenum; i++)
{
// generateMovesでもとめた場所においてみる
self.doMove<true>(move[i]);
assert(self.key() == self.keyInit());
// 設置にかかる時間を計算
// 落下にかかる時間は、13 - 設置位置のyの小さいほう ちぎりなら、余計に時間がかかる
int takeTime = (13 - std::min(toY(move[i].csq()), toY(move[i].psq()))) * FALLTIME + (move[i].isTigiri() ? TAKETIME_INCLUDETIGIRI : TAKETIME);
if (self.flag(VANISH))// 消えるなら
{
score = evalVanish(self, enemy, depth, timeLimit) - takeTime;
self.clearFlag(VANISH);
}
else// 消えないとき
{
if (timeLimit < takeTime)
{
// 致死量振るときに発火できなければ負け。
if (enemy.scoreMax() >= 30 * RATE || enemy.scoreMax() >= self.deadLine() * RATE)
score = -SCORE_INFINITE;
else
score = think(self, enemy, depth - ONE_PLY, timeLimit - takeTime) - takeTime;
}
else
score = think(self, enemy, depth - ONE_PLY, timeLimit - takeTime) - takeTime;
}
self.undoMove(move[i], con_prev);
if (stop)
return SCORE_ZERO;
if (max < score)
{
max = score;
best_[depth] = move[i];// もっとも評価の高い手を選ぶ
}
#if defined DEBUG
assert(self == f); // debug::きちんともとの局面に戻せているか
#endif
//.........这里部分代码省略.........
示例10: search
Value search(Position& pos, Value alpha, Value beta, Depth depth)
{
ASSERT_LV3(alpha < beta);
// -----------------------
// nodeの種類
// -----------------------
// root nodeであるか
const bool RootNode = NT == Root;
// PV nodeであるか(root nodeはPV nodeに含まれる)
const bool PvNode = NT == PV || NT == Root;
// -----------------------
// 変数宣言
// -----------------------
// 現在のnodeのrootからの手数。これカウンターが必要。
// nanoだとこのカウンター持ってないので適当にごまかす。
const int ply_from_root = (pos.this_thread()->rootDepth - depth / ONE_PLY) + 1;
// -----------------------
// 置換表のprobe
// -----------------------
auto key = pos.state()->key();
bool ttHit; // 置換表がhitしたか
TTEntry* tte = TT.probe(key, ttHit);
// 置換表上のスコア
// 置換表にhitしなければVALUE_NONE
Value ttValue = ttHit ? value_from_tt(tte->value(), ply_from_root) : VALUE_NONE;
auto thisThread = pos.this_thread();
// 置換表の指し手
// 置換表にhitしなければMOVE_NONE
// RootNodeであるなら、指し手は現在注目している1手だけであるから、それが置換表にあったものとして指し手を進める。
Move ttMove = RootNode ? thisThread->rootMoves[thisThread->PVIdx].pv[0]
: ttHit ? tte->move() : MOVE_NONE;
// 置換表の値による枝刈り
if (!PvNode // PV nodeでは置換表の指し手では枝刈りしない(PV nodeはごくわずかしかないので..)
&& ttHit // 置換表の指し手がhitして
&& tte->depth() >= depth // 置換表に登録されている探索深さのほうが深くて
&& ttValue != VALUE_NONE // (VALUE_NONEだとすると他スレッドからTTEntryが読みだす直前に破壊された可能性がある)
&& (ttValue >= beta ? (tte->bound() & BOUND_LOWER)
: (tte->bound() & BOUND_UPPER))
// ttValueが下界(真の評価値はこれより大きい)もしくはジャストな値で、かつttValue >= beta超えならbeta cutされる
// ttValueが上界(真の評価値はこれより小さい)だが、tte->depth()のほうがdepthより深いということは、
// 今回の探索よりたくさん探索した結果のはずなので、今回よりは枝刈りが甘いはずだから、その値を信頼して
// このままこの値でreturnして良い。
)
{
return ttValue;
}
// -----------------------
// 1手ずつ指し手を試す
// -----------------------
pos.check_info_update();
MovePicker mp(pos,ttMove);
Value value;
Move move;
StateInfo si;
// この局面でdo_move()された合法手の数
int moveCount = 0;
Move bestMove = MOVE_NONE;
while (move = mp.nextMove())
{
// root nodeでは、rootMoves()の集合に含まれていない指し手は探索をスキップする。
if (RootNode && !std::count(thisThread->rootMoves.begin() + thisThread->PVIdx,
thisThread->rootMoves.end(), move))
continue;
// legal()のチェック。root nodeだとlegal()だとわかっているのでこのチェックは不要。
if (!RootNode && !pos.legal(move))
continue;
// -----------------------
// 1手進める
// -----------------------
pos.do_move(move, si, pos.gives_check(move));
// do_moveした指し手の数のインクリメント
++moveCount;
// -----------------------
// 再帰的にsearchを呼び出す
// -----------------------
//.........这里部分代码省略.........
示例11: firstEntry
void TranspositionTable::store(const Key posKey, const Score score, const Bound bound, Depth depth,
Move move, const Score evalScore)
{
#ifdef OUTPUT_TRANSPOSITION_EXPIRATION_RATE
++numberOfSaves;
#endif
TTEntry* tte = firstEntry(posKey);
TTEntry* replace = tte;
const u32 posKeyHigh32 = posKey >> 32;
if (depth < Depth0) {
depth = Depth0;
}
for (int i = 0; i < ClusterSize; ++i, ++tte) {
// 置換表が空か、keyが同じな古い情報が入っているとき
if (!tte->key() || tte->key() == posKeyHigh32) {
// move が無いなら、とりあえず古い情報でも良いので、他の指し手を保存する。
if (move.isNone()) {
move = tte->move();
}
tte->save(depth, score, move, posKeyHigh32,
bound, this->generation(), evalScore);
return;
}
int c = (replace->generation() == this->generation() ? 2 : 0);
c += (tte->generation() == this->generation() || tte->type() == BoundExact ? -2 : 0);
c += (tte->depth() < replace->depth() ? 1 : 0);
if (0 < c) {
replace = tte;
}
}
#ifdef OUTPUT_TRANSPOSITION_EXPIRATION_RATE
if (replace->key() != 0 && replace->key() != posKeyHigh32) {
++numberOfCacheExpirations;
}
#endif
replace->save(depth, score, move, posKeyHigh32,
bound, this->generation(), evalScore);
}
示例12: checkTime
Score AI::search(Score alpha, Score beta, LightField& self, LightField& enemy, int depth, int my_remain_time)
{
if (calls_count++ > 100)
{
checkTime();
calls_count = 0;
}
node_searched++;
const bool rootnode = NT == ROOT;
assert(alpha >= -SCORE_INFINITE && alpha < beta && beta <= SCORE_INFINITE);
// ルートからの手数
int ply = depth_max_ - depth;
// 局面表を見る
Move tt_move, best_move;
Score tt_score;
TTEntry* tte;
const Key key = self.key() ^ enemy.key();
const bool tt_hit = TT.probe<false>(&self, &enemy, tte);
if (stop)
return SCORE_ZERO;
// 局面表の指し手
tt_move = tt_hit ? tte->move() :
rootnode ? root_moves[0].pv[0] : Move::moveNone();
// 置換表上のスコア
tt_score = tt_hit ? tte->score() : SCORE_NONE;
// 置換表のスコアが信用に足るならそのまま返す。
// 条件)
// root nodeではない
// 置換表にエントリーがあった
// 置換表のエントリーのdepthが今回の残り探索depth以上である
// 置換表のエントリーのスコアがSCORE_NONEではない。(置換表のアクセス競合のときにのみこの値になりうる)
// 置換表のスコアのboundがBOUND_EXACTなら信用に足るので置換表の指し手をそのまま返す
// non PV nodeであれば置換表の値がbetaを超えているならBOUND_LOWER(真の値はこれより上なのでこのときbeta cutできる)であるか、
// betaを超えていないのであれば、BOUND_UPPER(真の値はこれより下なのでこのときbeta cutが起きないことが確定)である。
if (!rootnode
&& tt_hit
&& tte->depth() >= depth
&& (depth == 0
|| (tte->bound() == BOUND_EXACT
|| (tte->bound() & BOUND_LOWER && tt_score >= beta))))
{
best_[depth] = tte->move();
assert(tte->move().isNone() || tte->move().isLegal(self));
// 局面表のスコアは信用できるのでそのまま返す
return tt_score;
}
// 最大探索深さまでいったら、その局面の点数を返す
if (depth <= DEPTH_ZERO)
{
Score s = evaluateEX(self, enemy, depth, my_remain_time);
// せっかく評価関数を呼び出したので局面表に登録しておく。
tte->save(key, 0, s, 0, BOUND_NONE, TT.generation(), self.player(), my_remain_time, self.ojama() - enemy.ojama());
return s;
}
Move move[23];
int move_max = 0;
Move *pmove = move;
if (!tt_move.isNone())
{
if (tt_move.isLegalAbout(self))
{
// 置換表にある手を手のバッファの先頭に入れる。
*pmove++ = tt_move;
move_max++;
}
}
if ((move_max += self.generateMoves(pmove)) == 0)
{
// 置く場所なし == 負け
return SCORE_MATED;
}
Score score, max = -SCORE_INFINITE;
// お邪魔ぷよが降る場合はenemyのojamaを減らしているので、
// このmoveを調べ終わった後元に戻さなければならない
int enemy_ojama_prev = enemy.ojama();
Flag enemy_flag = enemy.flag();
self.nextPlus();
// TODO:ムーブオーダリングしたい
// 手がある間、すべての手を試す
for (int i = 0; i < move_max; i++)
//.........这里部分代码省略.........
示例13: getIndex
void
TranspositionTable::insert(U64 key, const Move& sm, int type, int ply, int depth, int evalScore) {
if (depth < 0) depth = 0;
size_t idx0 = getIndex(key);
U64 key2 = getStoredKey(key);
TTEntry ent0, ent1;
ent0.load(table[idx0]);
size_t idx = idx0;
TTEntry* ent = &ent0;
if (ent0.getKey() != key2) {
size_t idx1 = idx0 ^ 1;
ent1.load(table[idx1]);
idx = idx1;
ent = &ent1;
if (ent1.getKey() != key2)
if (ent1.betterThan(ent0, generation)) {
idx = idx0;
ent = &ent0;
}
}
bool doStore = true;
if ((ent->getKey() == key2) && (ent->getDepth() > depth) && (ent->getType() == type)) {
if (type == TType::T_EXACT)
doStore = false;
else if ((type == TType::T_GE) && (sm.score() <= ent->getScore(ply)))
doStore = false;
else if ((type == TType::T_LE) && (sm.score() >= ent->getScore(ply)))
doStore = false;
}
if (doStore) {
if ((ent->getKey() != key2) || (sm.from() != sm.to()))
ent->setMove(sm);
ent->setKey(key2);
ent->setScore(sm.score(), ply);
ent->setDepth(depth);
ent->setGeneration((S8)generation);
ent->setType(type);
ent->setEvalScore(evalScore);
ent->store(table[idx]);
}
}