Beispiel #1
0
 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;
 }
Beispiel #2
0
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;
  }