FORCE_INLINE MoveStack* generateBishopOrRookMoves(MoveStack* moveStackList, const Position& pos, const Bitboard& target, const Square /*ksq*/) { Bitboard fromBB = pos.bbOf(PT, US); while (fromBB.isNot0()) { const Square from = fromBB.firstOneFromI9(); const bool fromCanPromote = canPromote(US, makeRank(from)); Bitboard toBB = pos.attacksFrom<PT>(US, from) & target; while (toBB.isNot0()) { const Square to = toBB.firstOneFromI9(); const bool toCanPromote = canPromote(US, makeRank(to)); if (fromCanPromote | toCanPromote) { (*moveStackList++).move = makePromoteMove<MT>(PT, from, to, pos); if (MT == NonEvasion || ALL) (*moveStackList++).move = makeNonPromoteMove<MT>(PT, from, to, pos); } else // 角、飛車は成れるなら成り、不成は生成しない。 (*moveStackList++).move = makeNonPromoteMove<MT>(PT, from, to, pos); } } return moveStackList; }
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); });
// Square の左右だけ変換 inline Square inverseFile(const Square sq) { return makeSquare(inverse(makeFile(sq)), makeRank(sq)); }
inline std::string squareToStringCSA(const Square sq) { const Rank r = makeRank(sq); const File f = makeFile(sq); const char ch[] = {fileToCharCSA(f), rankToCharCSA(r), '\0'}; return std::string(ch); }
ret[retIdx++] = std::make_pair(&r_pe_h[i][jcolor] - &oneArrayKPP[0], MaxWeight() >> (distance+2)); ret[retIdx++] = std::make_pair(&pe[i][jcolor][jto] - &oneArrayKPP[0], MaxWeight() >> (distance+2)); if (E1 < jto) jto = inverseFile(jto); ret[retIdx++] = std::make_pair(&ype[krank][i][jcolor][jto] - &oneArrayKPP[0], MaxWeight() >> (distance+2)); } } else { // i, j 共に盤上 const int ibegin = kppIndexBegin(i); const int jbegin = kppIndexBegin(j); const Piece ipiece = g_kppBoardIndexStartToPiece.value(ibegin); const Piece jpiece = g_kppBoardIndexStartToPiece.value(jbegin); const Square isq = static_cast<Square>(i - ibegin); const Square jsq = static_cast<Square>(j - jbegin); const Rank krank = makeRank(ksq); const File kfile = makeFile(ksq); const Rank irank = makeRank(isq); const File ifile = makeFile(isq); const Rank jrank = makeRank(jsq); const File jfile = makeFile(jsq); File diff_file_ki = kfile - ifile; bool kfile_ifile_is_inversed = false; if (0 < diff_file_ki) { diff_file_ki = -diff_file_ki; kfile_ifile_is_inversed = true; } const File diff_file_kj = static_cast<File>(diff_file_ki == static_cast<File>(0) ? -abs(kfile - jfile) : kfile_ifile_is_inversed ? jfile - kfile : kfile - jfile); if (ipiece == jpiece) {