static Square minAttacker(const Board &board, Bitboard atcks, ColorType side) { if (side == White) { Bitboard retval(atcks & board.pawn_bits[White]); if (!retval.isClear()) return retval.firstOne(); retval = (atcks & board.knight_bits[White]); if (!retval.isClear()) return retval.firstOne(); retval = (atcks & board.bishop_bits[White]); if (!retval.isClear()) return retval.firstOne(); retval = (atcks & board.rook_bits[White]); if (!retval.isClear()) return retval.firstOne(); retval = (atcks & board.queen_bits[White]); if (!retval.isClear()) return retval.firstOne(); if (atcks.isSet(board.kingSquare(White))) return board.kingSquare(White); else return InvalidSquare; } else { Bitboard retval(atcks & board.pawn_bits[Black]); if (!retval.isClear()) return retval.firstOne(); retval = (atcks & board.knight_bits[Black]); if (!retval.isClear()) return retval.firstOne(); retval = (atcks & board.bishop_bits[Black]); if (!retval.isClear()) return retval.firstOne(); retval = (atcks & board.rook_bits[Black]); if (!retval.isClear()) return retval.firstOne(); retval = (atcks & board.queen_bits[Black]); if (!retval.isClear()) return retval.firstOne(); if (atcks.isSet(board.kingSquare(Black))) return board.kingSquare(Black); else return InvalidSquare; } }
MoveStack* generateDropMoves20151211(MoveStack* moveStackList, const Position& pos, const Bitboard& target) { const Hand hand = pos.hand(US); // まず、歩に対して指し手を生成 if (hand.exists<HPawn>()) { Bitboard toBB = target; // 一段目には打てない const Rank TRank9 = (US == Black ? Rank9 : Rank1); toBB.andEqualNot(rankMask<TRank9>()); // 二歩の回避 Bitboard pawnsBB = pos.bbOf(Pawn, US); Square pawnsSquare; foreachBB(pawnsBB, pawnsSquare, [&](const int part) { toBB.set(part, toBB.p(part) & ~squareFileMask(pawnsSquare).p(part)); }); // 打ち歩詰めの回避 const Rank TRank1 = (US == Black ? Rank1 : Rank9); const SquareDelta TDeltaS = (US == Black ? DeltaS : DeltaN); const Square ksq = pos.kingSquare(oppositeColor(US)); // 相手玉が九段目なら、歩で王手出来ないので、打ち歩詰めを調べる必要はない。 if (makeRank(ksq) != TRank1) { const Square pawnDropCheckSquare = ksq + TDeltaS; assert(isInSquare(pawnDropCheckSquare)); if (toBB.isSet(pawnDropCheckSquare) && pos.piece(pawnDropCheckSquare) == Empty) { if (!pos.isPawnDropCheckMate(US, pawnDropCheckSquare)) { // ここで clearBit だけして MakeMove しないことも出来る。 // 指し手が生成される順番が変わり、王手が先に生成されるが、後で問題にならないか? (*moveStackList++).move = makeDropMove(Pawn, pawnDropCheckSquare); } toBB.xorBit(pawnDropCheckSquare); } } Square to; FOREACH_BB(toBB, to, { (*moveStackList++).move = makeDropMove(Pawn, to); });