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; }
void BOARD::helpFindBestMoves ( int lookAhead, PIECECOLOR moveColor, BOARDMETRIC &metric, BESTMOVES *bestMoves ) { POSITION where; POSITIONLIST moves; BOARDMETRIC testMetric; BOOL metricSet = FALSE; MOVEUNDODATA undoData; int m, compareResult; int origMaterialDiff = metric.materialDiff; MOVETYPE castleType; testMetric.kingSituation[WHITE] = KINGOK; testMetric.kingSituation[BLACK] = KINGOK; // try all possible moves for the given color for (where.row = 0; where.row < NUMROWS; where.row++) for (where.col = 0; where.col < NUMCOLS; where.col++) { if (whatPiece(where)) if (whatPiece(where)->whatColor() == moveColor) { whatPiece(where)->legalMoves(where, *this, moves); for (m = 0; m < moves.nMoves; m++) { testMetric.materialDiff = origMaterialDiff; doMove ( where, moves.end[m], undoData ); if (undoData.capturedPiece) { if (undoData.capturedPiece->whatType() == TYPEKING) { undoMove ( moves.end[m], where, undoData ); metric.kingSituation[OtherColor(moveColor)] = KINGLOST; if (bestMoves) { bestMoves->nMoves = 0; bestMoves->move[0] = PIECEMOVE ( NORMALMOVE, where, moves.end[m] ); } return; } testMetric.materialDiff -= undoData.capturedPiece->signedValue(); } if (canPromote(moves.end[m])) { testMetric.materialDiff -= whatPiece(moves.end[m])->signedValue(); promote(moves.end[m], TYPEQUEEN); testMetric.materialDiff += whatPiece(moves.end[m])->signedValue(); if (lookAhead > 1) helpFindBestMoves ( lookAhead - 1, OtherColor(moveColor), testMetric, (BESTMOVES *) 0 ); compareResult = compareMetric ( testMetric, metric, metricSet, moveColor ); if (compareResult >= 0) { if (compareResult > 0) { metric = testMetric; metricSet = TRUE; if (bestMoves) bestMoves->nMoves = 0; } if (bestMoves) bestMoves->move[bestMoves->nMoves++] = PIECEMOVE ( NORMALMOVE, where, moves.end[m], TYPEQUEEN ); } testMetric.materialDiff -= whatPiece(moves.end[m])->signedValue(); restorePawn(moves.end[m]); promote(moves.end[m], TYPEKNIGHT); testMetric.materialDiff += whatPiece(moves.end[m])->signedValue(); if (lookAhead > 1) helpFindBestMoves ( lookAhead - 1, OtherColor(moveColor), testMetric, (BESTMOVES *) 0 ); compareResult = compareMetric ( testMetric, metric, metricSet, moveColor ); if (compareResult >= 0) { if (compareResult > 0) { metric = testMetric; metricSet = TRUE; if (bestMoves) bestMoves->nMoves = 0; } if (bestMoves) bestMoves->move[bestMoves->nMoves++] = PIECEMOVE ( NORMALMOVE, where, moves.end[m], TYPEKNIGHT ); } restorePawn(moves.end[m]); } else // no promotion { if (lookAhead > 1) helpFindBestMoves ( lookAhead - 1, OtherColor(moveColor), testMetric, (BESTMOVES *) 0 ); compareResult = compareMetric ( testMetric, metric, metricSet, moveColor ); if (compareResult >= 0) { if (compareResult > 0) { metric = testMetric; metricSet = TRUE; if (bestMoves) bestMoves->nMoves = 0; } if (bestMoves) bestMoves->move[bestMoves->nMoves++] = PIECEMOVE ( NORMALMOVE, where, moves.end[m] ); } } undoMove ( moves.end[m], where, undoData ); } // end of for loop over each legal move for piece } } // end of double for loop over each board position // only try castling moves if look ahead move than one, since // nothing can be captured by doing a castling move if (lookAhead > 1) { castleType = QUEENSIDECASTLE; for ( ; ; ) { if (canCastle(castleType, moveColor)) { testMetric.materialDiff = origMaterialDiff; castle(castleType, moveColor, undoData); helpFindBestMoves ( lookAhead - 1, OtherColor(moveColor), testMetric, (BESTMOVES *) 0 ); compareResult = compareMetric ( testMetric, metric, metricSet, moveColor ); if (compareResult >= 0) { if (compareResult > 0) { metric = testMetric; metricSet = TRUE; if (bestMoves) bestMoves->nMoves = 0; } if (bestMoves) bestMoves->move[bestMoves->nMoves++] = PIECEMOVE(castleType); } undoCastle(castleType, moveColor, undoData); } if (castleType == KINGSIDECASTLE) break; castleType = KINGSIDECASTLE; } // see if the loss of the king is the result of a stalemate // instead of check mate if (metric.kingSituation[moveColor] == KINGLOST) { helpFindBestMoves ( 1, OtherColor(moveColor), testMetric, (BESTMOVES *) 0 ); if (testMetric.kingSituation[moveColor] != KINGLOST) // king will be lost on next move, but is not in check metric.kingSituation[moveColor] = STALEMATE; } } return; }