void do_perft(position_t *pos, scored_move_t *ms, int ply, int depth) { scored_move_t *msbase = ms; uint8 stm = Stm(ply); scored_move_t *mv; if (Checked(stm^1)) return; if (Checked(stm)) { ms = generate_evasions(pos, ms, ply); for (mv = msbase; mv < ms; mv++) if (PieceType(Capture(mv->move)) == KING) return; } else { ms = generate_captures(pos, ms, ply); for (mv = msbase; mv < ms; mv++) if (PieceType(Capture(mv->move)) == KING) return; ms = generate_noncaptures(pos, ms, ply); } for (mv = msbase; mv < ms; mv++) { make_move(pos, mv->move, ply); if (depth - 1) do_perft(pos, ms, ply + 1, depth - 1); else if (!Checked(stm)) total_moves++; unmake_move(pos, mv->move, ply); } }
MoveStack* generate_moves(const Position& pos, MoveStack* mlist, bool pseudoLegal) { assert(pos.is_ok()); MoveStack *last, *cur = mlist; Bitboard pinned = pos.pinned_pieces(pos.side_to_move()); // Generate pseudo-legal moves if (pos.is_check()) last = generate_evasions(pos, mlist); else last = generate_noncaptures(pos, generate_captures(pos, mlist)); if (pseudoLegal) return last; // Remove illegal moves from the list while (cur != last) if (pos.pl_move_is_legal(cur->move, pinned)) cur++; else cur->move = (--last)->move; return last; }
/* * Fill the provided list with all pseudolegal moves in the given position. * Pseudolegal moves are moves which would be legal if we didn't have to worry * about leaving our king in check. */ int generate_pseudo_moves(const position_t* pos, move_t* moves) { if (is_check(pos)) return generate_evasions(pos, moves); move_t* moves_head = moves; moves += generate_pseudo_tactical_moves(pos, moves); moves += generate_pseudo_quiet_moves(pos, moves); return moves-moves_head; }
/* * Generate all pseudolegal moves that should be considered during quiescence * search. Currently this is just captures and promotions to queen. */ int generate_quiescence_moves(const position_t* pos, move_t* moves, bool generate_checks) { if (is_check(pos)) return generate_evasions(pos, moves); move_t* moves_head = moves; moves += generate_pseudo_tactical_moves(pos, moves); if (generate_checks) moves += generate_pseudo_checks(pos, moves); return moves-moves_head; }
/* * Fill the provided list with all legal moves in the given position. */ int generate_legal_moves(position_t* pos, move_t* moves) { if (is_check(pos)) return generate_evasions(pos, moves); int num_pseudo = generate_pseudo_moves(pos, moves); move_t* moves_tail = moves+num_pseudo; move_t* moves_curr = moves; while (moves_curr < moves_tail) { check_pseudo_move_legality(pos, *moves_curr); if (!is_pseudo_move_legal(pos, *moves_curr)) { *moves_curr = *(--moves_tail); *moves_tail = 0; } else { ++moves_curr; } } return moves_tail-moves; }
Move MovePicker::get_next_move() { Move move; while(true) { // If we already have a list of generated moves, pick the best move from // the list, and return it: move = this->pick_move_from_list(); if(move != MOVE_NONE) { assert(move_is_ok(move)); return move; } // Next phase: phaseIndex++; switch(PhaseTable[phaseIndex]) { case PH_TT_MOVE: if(ttMove != MOVE_NONE) { assert(move_is_ok(ttMove)); Move m = generate_move_if_legal(*pos, ttMove, pinned); if(m != MOVE_NONE) { assert(m == ttMove); return m; } } break; case PH_MATE_KILLER: if(mateKiller != MOVE_NONE) { assert(move_is_ok(mateKiller)); Move m = generate_move_if_legal(*pos, mateKiller, pinned); if(m != MOVE_NONE) { assert(m == mateKiller); return m; } } break; case PH_GOOD_CAPTURES: // pinned = pos->pinned_pieces(pos->side_to_move()); numOfMoves = generate_captures(*pos, moves); this->score_captures(); movesPicked = 0; break; case PH_BAD_CAPTURES: badCapturesPicked = 0; break; case PH_NONCAPTURES: numOfMoves = generate_noncaptures(*pos, moves); this->score_noncaptures(); movesPicked = 0; break; case PH_EVASIONS: assert(pos->is_check()); // pinned = pos->pinned_pieces(pos->side_to_move()); numOfMoves = generate_evasions(*pos, moves); this->score_evasions(); movesPicked = 0; break; case PH_QCAPTURES: // pinned = pos->pinned_pieces(pos->side_to_move()); numOfMoves = generate_captures(*pos, moves); this->score_qcaptures(); movesPicked = 0; break; case PH_QCHECKS: numOfMoves = generate_checks(*pos, moves, dc); movesPicked = 0; break; case PH_STOP: return MOVE_NONE; default: assert(false); return MOVE_NONE; } } assert(false); return MOVE_NONE; }