Move pv[PLY_MAX_PLUS_2];
};
- // RootMoveList struct is just a vector of RootMove objects,
- // with an handful of methods above the standard ones.
+ // RootMoveList struct is mainly a std::vector of RootMove objects
struct RootMoveList : public std::vector<RootMove> {
-
- typedef std::vector<RootMove> Base;
-
void init(Position& pos, Move searchMoves[]);
- void sort() { insertion_sort<RootMove, Base::iterator>(begin(), end()); }
- void sort_first(int n) { insertion_sort<RootMove, Base::iterator>(begin(), begin() + n); }
-
int bestMoveChanges;
};
int64_t perft(Position& pos, Depth depth) {
- MoveStack mlist[MAX_MOVES];
StateInfo st;
- Move m;
int64_t sum = 0;
// Generate all legal moves
- MoveStack* last = generate<MV_LEGAL>(pos, mlist);
+ MoveList<MV_LEGAL> ml(pos);
// If we are at the last ply we don't need to do and undo
// the moves, just to count them.
if (depth <= ONE_PLY)
- return int(last - mlist);
+ return ml.size();
// Loop through all legal moves
CheckInfo ci(pos);
- for (MoveStack* cur = mlist; cur != last; cur++)
+ for ( ; !ml.end(); ++ml)
{
- m = cur->move;
- pos.do_move(m, st, ci, pos.move_gives_check(m, ci));
+ pos.do_move(ml.move(), st, ci, pos.move_gives_check(ml.move(), ci));
sum += perft(pos, depth - ONE_PLY);
- pos.undo_move(m);
+ pos.undo_move(ml.move());
}
return sum;
}
NodesSincePoll = 0;
current_search_time(get_system_time());
Limits = limits;
- TimeMgr.init(Limits, pos.full_moves());
+ TimeMgr.init(Limits, pos.startpos_ply_counter());
// Set output steram in normal or chess960 mode
cout << set960(pos.is_chess960());
if (PvNode && thread.maxPly < ss->ply)
thread.maxPly = ss->ply;
- if (SpNode)
+ // Step 1. Initialize node and poll. Polling can abort search
+ if (!SpNode)
+ {
+ ss->currentMove = ss->bestMove = threatMove = (ss+1)->excludedMove = MOVE_NONE;
+ (ss+1)->skipNullMove = false; (ss+1)->reduction = DEPTH_ZERO;
+ (ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE;
+ }
+ else
{
sp = ss->sp;
tte = NULL;
goto split_point_start;
}
- // Step 1. Initialize node and poll. Polling can abort search
- ss->currentMove = ss->bestMove = threatMove = (ss+1)->excludedMove = MOVE_NONE;
- (ss+1)->skipNullMove = false; (ss+1)->reduction = DEPTH_ZERO;
- (ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE;
-
if (pos.thread() == 0 && ++NodesSincePoll > NodesBetweenPolls)
{
NodesSincePoll = 0;
// because all the values but the first are usually set to
// -VALUE_INFINITE and we want to keep the same order for all
// the moves but the new PV that goes to head.
- Rml.sort_first(moveCount);
+ sort<RootMove>(Rml.begin(), Rml.begin() + moveCount);
// Update alpha. In multi-pv we don't use aspiration window, so set
// alpha equal to minimum score among the PV lines searched so far.
bool connected_moves(const Position& pos, Move m1, Move m2) {
Square f1, t1, f2, t2;
- Piece p;
+ Piece p1, p2;
+ Square ksq;
assert(m1 && move_is_ok(m1));
assert(m2 && move_is_ok(m2));
return true;
// Case 3: Moving through the vacated square
- if ( piece_is_slider(pos.piece_on(f2))
+ p2 = pos.piece_on(f2);
+ if ( piece_is_slider(p2)
&& bit_is_set(squares_between(f2, t2), f1))
return true;
// Case 4: The destination square for m2 is defended by the moving piece in m1
- p = pos.piece_on(t1);
- if (bit_is_set(pos.attacks_from(p, t1), t2))
+ p1 = pos.piece_on(t1);
+ if (bit_is_set(pos.attacks_from(p1, t1), t2))
return true;
// Case 5: Discovered check, checking piece is the piece moved in m1
- if ( piece_is_slider(p)
- && bit_is_set(squares_between(t1, pos.king_square(pos.side_to_move())), f2)
- && !bit_is_set(squares_between(t1, pos.king_square(pos.side_to_move())), t2))
+ ksq = pos.king_square(pos.side_to_move());
+ if ( piece_is_slider(p1)
+ && bit_is_set(squares_between(t1, ksq), f2))
{
- // discovered_check_candidates() works also if the Position's side to
- // move is the opposite of the checking piece.
- Color them = opposite_color(pos.side_to_move());
- Bitboard dcCandidates = pos.discovered_check_candidates(them);
-
- if (bit_is_set(dcCandidates, f2))
+ Bitboard occ = pos.occupied_squares();
+ clear_bit(&occ, f2);
+ if (bit_is_set(pos.attacks_from(p1, t1, occ), ksq))
return true;
}
return false;
void RootMoveList::init(Position& pos, Move searchMoves[]) {
- MoveStack mlist[MAX_MOVES];
Move* sm;
-
- clear();
bestMoveChanges = 0;
+ clear();
// Generate all legal moves and add them to RootMoveList
- MoveStack* last = generate<MV_LEGAL>(pos, mlist);
- for (MoveStack* cur = mlist; cur != last; cur++)
+ for (MoveList<MV_LEGAL> ml(pos); !ml.end(); ++ml)
{
- // If we have a searchMoves[] list then verify cur->move
+ // If we have a searchMoves[] list then verify the move
// is in the list before to add it.
- for (sm = searchMoves; *sm && *sm != cur->move; sm++) {}
+ for (sm = searchMoves; *sm && *sm != ml.move(); sm++) {}
- if (searchMoves[0] && *sm != cur->move)
+ if (sm != searchMoves && *sm != ml.move())
continue;
RootMove rm;
- rm.pv[0] = cur->move;
+ rm.pv[0] = ml.move();
rm.pv[1] = MOVE_NONE;
rm.pv_score = -VALUE_INFINITE;
push_back(rm);
while ( (tte = TT.probe(pos.get_key())) != NULL
&& tte->move() != MOVE_NONE
&& pos.move_is_pl(tte->move())
- && pos.pl_move_is_legal(tte->move(), pos.pinned_pieces(pos.side_to_move()))
+ && pos.pl_move_is_legal(tte->move(), pos.pinned_pieces())
&& ply < PLY_MAX
&& (!pos.is_draw<false>() || ply < 2))
{
break;
}
- Rml.sort();
+ sort<RootMove>(Rml.begin(), Rml.end());
}
} // namespace