示例#1
0
 public override void GenerateSpecialMoves(MoveList list, bool capturesOnly, int ply)
 {
     if (!capturesOnly)
     {
         int priv = ply == 1 ? gameHistory[Game.GameMoveNumber] : privs[ply - 1];
         if (Game.CurrentSide == 0 && (priv & 1) == 1)
         {
             foreach (int direction in directions)
             {
                 int square = Board.NextSquare(direction, kingSquare[0]);
                 if (square >= 0 && Board[square] == null)
                 {
                     list.BeginMoveAdd(MoveType.StandardMove, kingSquare[0], square);
                     Piece king = list.AddPickup(kingSquare[0]);
                     list.AddDrop(king, square);
                     list.EndMoveAdd(500);
                 }
             }
         }
         else if (Game.CurrentSide == 1 && (priv & 2) == 2)
         {
             foreach (int direction in directions)
             {
                 int square = Board.NextSquare(direction, kingSquare[1]);
                 if (square >= 0 && Board[square] == null)
                 {
                     list.BeginMoveAdd(MoveType.StandardMove, kingSquare[1], square);
                     Piece king = list.AddPickup(kingSquare[1]);
                     list.AddDrop(king, square);
                     list.EndMoveAdd(500);
                 }
             }
         }
     }
 }
 public override void GenerateSpecialMoves(MoveList list, bool capturesOnly, int ply)
 {
     if (!capturesOnly)
     {
         int king = Board.GetPieceTypeBitboard(Game.CurrentSide, kingType.TypeNumber).LSB;
         if (!IsSquareAttacked(king, Game.CurrentSide ^ 1))
         {
             for (int dir = 0; dir < 8; dir++)
             {
                 int nextSquare = Board.NextSquare(dir, king);
                 if (nextSquare >= 0 && Board[nextSquare] != null &&
                     Board[nextSquare].Player == Game.CurrentSide &&
                     Board[nextSquare].PieceType != pawnType)
                 {
                     //	The king can swap with this piece.  We won't bother
                     //	to see if the target square is attacked because the
                     //	CheckmateRule is going to verify that anyway and we
                     //	don't want to perform that operation twice.
                     list.BeginMoveAdd(MoveType.Swap, king, nextSquare);
                     Piece kingpiece  = list.AddPickup(king);
                     Piece otherpiece = list.AddPickup(nextSquare);
                     list.AddDrop(kingpiece, nextSquare);
                     list.AddDrop(otherpiece, king);
                     list.EndMoveAdd(0);
                 }
             }
         }
     }
 }
示例#3
0
        // *** OVERRIDES *** //

        public override void GenerateSpecialMoves(MoveList list, bool capturesOnly, int ply)
        {
            if (!capturesOnly)
            {
                BitBoard pawns = Board.GetPieceTypeBitboard(Game.CurrentSide, PawnType.TypeNumber);
                while (pawns)
                {
                    int pawnSquare = pawns.ExtractLSB();
                    int nextSquare = Board.NextSquare(PredefinedDirections.N + Game.CurrentSide, pawnSquare);
                    if (nextSquare >= 0 && Board[nextSquare] != null &&
                        Board[nextSquare].TypeNumber == PawnType.TypeNumber &&
                        Board[nextSquare].Player != Game.CurrentSide)
                    {
                        Piece enemyPawn = Board[nextSquare];
                        //	we can only perform the swap if the enemyPawn is not
                        //	currently attacking any piece of the current side
                        int attackSquare1 = Board.NextSquare(PredefinedDirections.E, pawnSquare);
                        int attackSquare2 = Board.NextSquare(PredefinedDirections.W, pawnSquare);
                        if ((attackSquare1 < 0 || Board[attackSquare1] == null || Board[attackSquare1].Player != Game.CurrentSide) &&
                            (attackSquare2 < 0 || Board[attackSquare2] == null || Board[attackSquare2].Player != Game.CurrentSide))
                        {
                            //	swap move is legal - add it now
                            list.BeginMoveAdd(MoveType.Swap, pawnSquare, nextSquare);
                            Piece myPawn = list.AddPickup(pawnSquare);
                            enemyPawn = list.AddPickup(nextSquare);
                            list.AddDrop(myPawn, nextSquare);
                            list.AddDrop(enemyPawn, pawnSquare);
                            list.EndMoveAdd(25);
                        }
                    }
                }
            }
        }
        public override void GenerateSpecialMoves(MoveList list, bool capturesOnly, int ply)
        {
            int epCaptureSquare = ply == 1
                                ? (Game.GameMoveNumber == 0 ? epCaptureSquares[0] : gameHistoryCaptureSquares[Game.GameMoveNumber - 1])
                                : epCaptureSquares[ply - 1];

            if (epCaptureSquare > 0)
            {
                int targetSquare = ply == 1
                                        ? (Game.GameMoveNumber == 0 ? epMoverSquares[0] : gameHistoryMoverSquares[Game.GameMoveNumber - 1])
                                        : epMoverSquares[ply - 1];
                int   victimPawnMoveDirection = Board.DirectionLookup(epCaptureSquare, targetSquare);
                Piece targetPawn = Board[targetSquare];

                while (epCaptureSquare != targetSquare)
                {
                    int   s        = Board.NextSquare(captureDirections[targetPawn.Player], epCaptureSquare);
                    Piece attacker = Board[Board.NextSquare(captureDirections[targetPawn.Player], epCaptureSquare)];
                    if (attacker.PieceType == PawnType)
                    {
                        //	this is a valid en passant attack
                        list.BeginMoveAdd(MoveType.EnPassant, attacker.Square, epCaptureSquare);
                        list.AddPickup(attacker.Square);
                        list.AddPickup(targetPawn.Square);
                        list.AddDrop(attacker, epCaptureSquare, null);
                        list.EndMoveAdd(3000);
                    }
                    epCaptureSquare = Board.NextSquare(victimPawnMoveDirection, epCaptureSquare);
                }
            }
        }
示例#5
0
        // *** EVENT HANDLERS *** //

        public override MoveEventResponse MoveBeingGenerated(MoveList moves, int from, int to, MoveType type)
        {
            if (Board[from].PieceType == PieceType)
            {
                int direction = Board.DirectionLookup(from, to);
                if (direction >= 0)
                {
                    int nextStep = Board.NextSquare(direction, to);
                    if (nextStep >= 0 && nextStep < Board.NumSquares)
                    {
                        Piece pieceOnNextSquare    = Board[nextStep];
                        Piece pieceOnLandingSquare = Board[to];
                        if (pieceOnNextSquare != null && pieceOnNextSquare.Player != Board[from].Player)
                        {
                            //	we can capture by advance
                            moves.BeginMoveAdd(pieceOnLandingSquare == null ? MoveType.BaroqueCapture : MoveType.ExtraCapture, from, to, nextStep);
                            Piece pieceBeingMoved    = moves.AddPickup(from);
                            Piece pieceBeingCaptured = moves.AddPickup(nextStep);
                            if (pieceOnLandingSquare != null)
                            {
                                moves.AddPickup(to);
                            }
                            moves.AddDrop(pieceBeingMoved, to);
                            moves.EndMoveAdd(pieceOnLandingSquare == null
                                                                ? (3000 + pieceBeingCaptured.PieceType.MidgameValue - (pieceBeingMoved.PieceType.MidgameValue / 16))
                                                                : (4000 + pieceBeingCaptured.PieceType.MidgameValue + pieceOnLandingSquare.PieceType.MidgameValue - (pieceBeingMoved.PieceType.MidgameValue / 16)));
                            return(MoveEventResponse.Handled);
                        }
                    }
                }
            }
            return(base.MoveBeingGenerated(moves, from, to, type));
        }
示例#6
0
        public override MoveEventResponse MoveBeingGenerated(MoveList moves, int from, int to, MoveType type)
        {
            Piece movingPiece = Board[from];

            if (movingPiece.TypeNumber == promotingTypeNumber)
            {
                Location        loc    = Board.SquareToLocation(Board.PlayerSquare(movingPiece.Player, to));
                PromotionOption option = condition(loc);
                if (option != PromotionOption.CannotPromote)
                {
                    //	enemy piece being captured (if any)
                    Piece capturedEnemyPiece = Board[to];

                    //	if promotion is optional, add move without promotion
                    if (option == PromotionOption.CanPromote)
                    {
                        if (capturedEnemyPiece == null)
                        {
                            moves.AddMove(from, to, true);
                        }
                        else
                        {
                            moves.AddCapture(from, to, true);
                        }
                    }

                    List <int>   pieceTypesFound = new List <int>();
                    List <Piece> capturedPieces  = Game.GetCapturedPieceList(movingPiece.Player);
                    foreach (Piece capturedFriendlyPiece in capturedPieces)
                    {
                        if (capturedFriendlyPiece.TypeNumber != movingPiece.TypeNumber &&
                            !pieceTypesFound.Contains(capturedFriendlyPiece.TypeNumber))
                        {
                            if (capturedEnemyPiece == null)
                            {
                                moves.BeginMoveAdd(MoveType.MoveReplace, from, to, capturedFriendlyPiece.TypeNumber);
                                moves.AddPickup(from);
                                moves.AddDrop(capturedFriendlyPiece, to);
                                moves.EndMoveAdd(5000 + capturedFriendlyPiece.PieceType.MidgameValue);
                            }
                            else
                            {
                                moves.BeginMoveAdd(MoveType.CaptureReplace, from, to, capturedFriendlyPiece.TypeNumber);
                                moves.AddPickup(from);
                                moves.AddPickup(to);
                                moves.AddDrop(capturedFriendlyPiece, to);
                                moves.EndMoveAdd(5000 + capturedFriendlyPiece.PieceType.MidgameValue + capturedEnemyPiece.PieceType.MidgameValue);
                            }
                            pieceTypesFound.Add(capturedFriendlyPiece.TypeNumber);
                        }
                    }
                    return(MoveEventResponse.Handled);
                }
            }
            return(MoveEventResponse.NotHandled);
        }
        public override MoveEventResponse MoveBeingGenerated(MoveList moves, int from, int to, MoveType type)
        {
            Piece movingPiece = Board[from];

            if (movingPiece == null)
            {
                throw new System.Exception("ex");
            }
            if (movingPiece.TypeNumber == promotingTypeNumber)
            {
                //	check the from-square condition (if any, usually there isn't)
                if (origLocationCondition != null)
                {
                    Location fromLocation = Board.SquareToLocation(Board.PlayerSquare(movingPiece.Player, from));
                    if (!origLocationCondition(fromLocation))
                    {
                        return(MoveEventResponse.NotHandled);
                    }
                }

                //	check the to-square condition
                Location toLocation = Board.SquareToLocation(Board.PlayerSquare(movingPiece.Player, to));
                if (destLocationCondition(toLocation))
                {
                    //	this is a promotion; add one move for each promotion type
                    Piece capturedPiece = Board[to];
                    if (capturedPiece == null)
                    {
                        foreach (PieceType promoteTo in promotionTypes)
                        {
                            moves.BeginMoveAdd(MoveType.MoveWithPromotion, from, to);
                            moves.AddPickup(from);
                            moves.AddDrop(movingPiece, to, promoteTo);
                            moves.EndMoveAdd(5000 + promoteTo.MidgameValue);
                        }
                    }
                    else
                    {
                        foreach (PieceType promoteTo in promotionTypes)
                        {
                            moves.BeginMoveAdd(MoveType.CaptureWithPromotion, from, to);
                            moves.AddPickup(from);
                            moves.AddPickup(to);
                            moves.AddDrop(movingPiece, to, promoteTo);
                            moves.EndMoveAdd(5000 + promoteTo.MidgameValue + capturedPiece.PieceType.MidgameValue);
                        }
                    }
                    return(MoveEventResponse.Handled);
                }
            }
            return(MoveEventResponse.NotHandled);
        }
示例#8
0
        public static bool CustomMoveGenerationHandler(PieceType pieceType, Piece piece, MoveList moveList, bool capturesOnly)
        {
            MoveCapability[] moves;
            int nMoves = pieceType.GetMoveCapabilities(out moves);

            for (int nMove = 0; nMove < nMoves; nMove++)
            {
                MoveCapability move       = moves[nMove];
                int            step       = 1;
                int            nextSquare = piece.Board.NextSquare(piece.Player, move.NDirection, piece.Square);
                while (nextSquare >= 0 && step <= move.MaxSteps)
                {
                    Piece pieceOnSquare = piece.Board[nextSquare];
                    if (pieceOnSquare != null)
                    {
                        if (step >= move.MinSteps && move.CanCapture && pieceOnSquare.Player != piece.Player)
                        {
                            moveList.AddCapture(piece.Square, nextSquare);
                        }
                        else if (step >= move.MinSteps && pieceOnSquare.Player == piece.Player && piece.PieceType != pieceOnSquare.PieceType)
                        {
                            //	self-capture move allowing relocation of friendly piece
                            int currentSquare = piece.Square;
                            while (currentSquare != nextSquare)
                            {
                                moveList.BeginMoveAdd(MoveType.MoveRelay, piece.Square, nextSquare, currentSquare);
                                moveList.AddPickup(piece.Square);
                                moveList.AddPickup(nextSquare);
                                moveList.AddDrop(piece, nextSquare);
                                moveList.AddDrop(pieceOnSquare, currentSquare);
                                moveList.EndMoveAdd(piece.PieceType.GetMidgamePST(nextSquare) - piece.PieceType.GetMidgamePST(piece.Square) +
                                                    pieceOnSquare.PieceType.GetMidgamePST(currentSquare) - pieceOnSquare.PieceType.GetMidgamePST(nextSquare));
                                currentSquare = piece.Board.NextSquare(piece.Player, move.NDirection, currentSquare);
                            }
                        }
                        nextSquare = -1;
                    }
                    else
                    {
                        if (step >= move.MinSteps && !move.MustCapture && !capturesOnly)
                        {
                            moveList.AddMove(piece.Square, nextSquare);
                        }
                        nextSquare = piece.Board.NextSquare(piece.Player, move.NDirection, nextSquare);
                        step++;
                    }
                }
            }
            return(false);
        }
示例#9
0
        public override void GenerateSpecialMoves(MoveList list, bool capturesOnly, int ply)
        {
            int epSquare = ply == 1 ? gameHistory[Game.GameMoveNumber] : epSquares[ply - 1];

            if (epSquare > 0)
            {
                int   nd   = Game.PlayerDirection(Game.CurrentSide ^ 1, NDirection);
                int   sq   = Board.NextSquare(nd, epSquare);
                Piece pawn = Board[sq];
                for (int ndir = 0; ndir < nAttackDirections; ndir++)
                {
                    int nextSquare = Board.NextSquare(attackDirections[Game.CurrentSide ^ 1, ndir], epSquare);
                    if (nextSquare >= 0)
                    {
                        Piece piece = Board[nextSquare];
                        if (piece != null && piece.PieceType == PawnType && piece.Player == Game.CurrentSide)
                        {
                            //	find square of pawn being captured.  we may have to make several
                            //	steps for large-board games where pawns make more than two steps
                            //	and can still be captured e.p.
                            int captureSquare = Board.NextSquare(nd, epSquare);
                            while (Board[captureSquare] == null)
                            {
                                captureSquare = Board.NextSquare(nd, captureSquare);
                            }

                            //	this piece can capture en passant
                            int nSquaresFirstBoard = Board.NumSquares / 2;
                            if (epSquare > nSquaresFirstBoard)
                            {
                                list.BeginMoveAdd(MoveType.EnPassant, nextSquare, epSquare - nSquaresFirstBoard);
                                list.AddPickup(nextSquare);
                                list.AddPickup(captureSquare);
                                list.AddDrop(piece, epSquare - nSquaresFirstBoard, null);
                                list.EndMoveAdd(120);
                            }
                            else
                            {
                                list.BeginMoveAdd(MoveType.EnPassant, nextSquare, epSquare + nSquaresFirstBoard);
                                list.AddPickup(nextSquare);
                                list.AddPickup(captureSquare);
                                list.AddDrop(piece, epSquare + nSquaresFirstBoard, null);
                                list.EndMoveAdd(120);
                            }
                        }
                    }
                }
            }
        }
示例#10
0
        public override MoveEventResponse MoveBeingGenerated(MoveList moves, int from, int to, MoveType type)
        {
            int nSquaresOnFirstBoard = Board.NumSquares / 2;

            if (type == MoveType.StandardMove)
            {
                if (to >= nSquaresOnFirstBoard)
                {
                    if (Board[to - nSquaresOnFirstBoard] == null)
                    {
                        moves.AddMove(from, to - nSquaresOnFirstBoard, true);
                    }
                }
                else
                {
                    if (Board[to + nSquaresOnFirstBoard] == null)
                    {
                        moves.AddMove(from, to + nSquaresOnFirstBoard, true);
                    }
                }
                return(MoveEventResponse.Handled);
            }
            else if (type == MoveType.StandardCapture)
            {
                if (to >= nSquaresOnFirstBoard)
                {
                    moves.BeginMoveAdd(MoveType.StandardCapture, from, to - nSquaresOnFirstBoard);
                    Piece pieceBeingMoved    = moves.AddPickup(from);
                    Piece pieceBeingCaptured = moves.AddPickup(to);
                    moves.AddDrop(pieceBeingMoved, to - nSquaresOnFirstBoard);
                    moves.EndMoveAdd(3000 +
                                     pieceBeingCaptured.PieceType.MidgameValue -
                                     (pieceBeingMoved.PieceType.MidgameValue / 16));
                }
                else
                {
                    moves.BeginMoveAdd(MoveType.StandardCapture, from, to + nSquaresOnFirstBoard);
                    Piece pieceBeingMoved    = moves.AddPickup(from);
                    Piece pieceBeingCaptured = moves.AddPickup(to);
                    moves.AddDrop(pieceBeingMoved, to + nSquaresOnFirstBoard);
                    moves.EndMoveAdd(3000 +
                                     pieceBeingCaptured.PieceType.MidgameValue -
                                     (pieceBeingMoved.PieceType.MidgameValue / 16));
                }
                return(MoveEventResponse.Handled);
            }
            return(MoveEventResponse.NotHandled);
        }
 public override MoveEventResponse MoveBeingGenerated(MoveList moves, int from, int to, MoveType type)
 {
     if (currentState >= 4)
     {
         //	Handle the automatic drops of the silver and gold generals at the beginning of the game
         if (Board[from].PieceType != pawnType || Game.StartingPieceSquares[Board[from].Player, from] == 0)
         {
             return(MoveEventResponse.IllegalMove);
         }
         //PieceType dropType = currentState < 6 ? silverGeneralType : goldGeneralType;
         moves.BeginMoveAdd(MoveType.StandardMove, from, to);
         Piece pawn = moves.AddPickup(from);
         moves.AddDrop(pawn, to);
         moves.AddDrop(generals[currentState - 4], from);
         moves.EndMoveAdd(pawnType.GetMidgamePST(Board.PlayerSquare(Board[from].Player, to)));
         return(MoveEventResponse.Handled);
     }
     else
     {
         //	Don't allow to move the same piece twice in a row unless it is a king
         if (Board[from] == pieceLastMoved[searchStateHistoryIndex - 1] && Board[from].PieceType != kingType)
         {
             return(MoveEventResponse.IllegalMove);
         }
     }
     return(MoveEventResponse.NotHandled);
 }
示例#12
0
        public override MoveEventResponse MoveBeingGenerated(MoveList moves, int from, int to, MoveType type)
        {
            Piece movingPiece = Board[from];

            foreach (var change in changes)
            {
                if (change.PieceType == movingPiece.PieceType)
                {
                    bool capturing = (type & MoveType.CaptureProperty) != 0;
                    if ((capturing && change.ChangeOnCapture) || (!capturing && change.ChangeOnMove))
                    {
                        Piece capturedPiece = Board[to];
                        if (capturedPiece != null)
                        {
                            //	does capture have to be of a specific type?
                            if (change.RequiredCaptureType != null &&
                                //	and is this the wrong type?
                                capturedPiece.PieceType != change.RequiredCaptureType)
                            {
                                //	this change rule is not applicable
                                continue;
                            }
                            moves.BeginMoveAdd(type, from, to);
                            moves.AddPickup(from);
                            moves.AddPickup(to);
                            moves.AddDrop(movingPiece, to, change.NewType);
                            moves.EndMoveAdd(change.NewType.MidgameValue - change.PieceType.MidgameValue
                                             + change.NewType.GetMidgamePST(from) - change.PieceType.GetMidgamePST(to)
                                             + capturedPiece.PieceType.MidgameValue + 1000);
                        }
                        else
                        {
                            moves.BeginMoveAdd(type, from, to);
                            moves.AddPickup(from);
                            moves.AddDrop(movingPiece, to, change.NewType);
                            moves.EndMoveAdd(change.NewType.MidgameValue - change.PieceType.MidgameValue
                                             + change.NewType.GetMidgamePST(from) - change.PieceType.GetMidgamePST(to));
                        }
                        return(MoveEventResponse.Handled);
                    }
                    continue;
                }
            }
            return(MoveEventResponse.NotHandled);
        }
示例#13
0
        public override void GenerateSpecialMoves(MoveList list, bool capturesOnly, int ply)
        {
            int      kingSquare         = Board.GetPieceTypeBitboard(Game.CurrentSide, kingType.TypeNumber).LSB;
            BitBoard potentialAttackers = Board.GetPieceTypeBitboard(Game.CurrentSide ^ 1, chasingType.TypeNumber);

            while (potentialAttackers)
            {
                int sq        = potentialAttackers.ExtractLSB();
                int direction = Board.DirectionLookup(sq, kingSquare);
                if (direction >= 0 && chasingType.AttackRangePerDirection[direction] >= Board.GetDistance(sq, kingSquare))
                {
                    //	King is attacked by appropriate chasing type.
                    //	Allow him to flee two squares in any direction.
                    for (int nDir = 0; nDir < 8; nDir++)
                    {
                        int nextSquare = Board.NextSquare(nDir, kingSquare);
                        if (nextSquare >= 0 && Board[nextSquare] == null)
                        {
                            nextSquare = Board.NextSquare(nDir, nextSquare);
                            if (nextSquare >= 0)
                            {
                                Piece pieceOnSquare = Board[nextSquare];
                                if (pieceOnSquare == null)
                                {
                                    list.BeginMoveAdd(MoveType.StandardMove, kingSquare, nextSquare);
                                    Piece king = list.AddPickup(kingSquare);
                                    list.AddDrop(king, nextSquare);
                                    list.EndMoveAdd(150);
                                }
                                else if (pieceOnSquare.Player != Game.CurrentSide)
                                {
                                    list.BeginMoveAdd(MoveType.StandardCapture, kingSquare, nextSquare);
                                    Piece king = list.AddPickup(kingSquare);
                                    list.AddPickup(nextSquare);
                                    list.AddDrop(king, nextSquare);
                                    list.EndMoveAdd(3000 + pieceOnSquare.PieceType.MidgameValue);
                                }
                            }
                        }
                    }
                }
            }
        }
示例#14
0
 public override void GenerateSpecialMoves(MoveList list, bool capturesOnly, int ply)
 {
     if (!capturesOnly)
     {
         int   pocketSquare  = pocketSquares[Game.CurrentSide];
         Piece pieceInPocket = Board[pocketSquare];
         if (pieceInPocket != null)
         {
             for (int square = 0; square < Board.NumSquares; square++)
             {
                 if (Board[square] == null)
                 {
                     list.BeginMoveAdd(MoveType.Drop, pocketSquare, square);
                     Piece piece = list.AddPickup(pocketSquare);
                     list.AddDrop(piece, square, pieceInPocket.PieceType);
                     list.EndMoveAdd(piece.PieceType.GetMidgamePST(square) - 10);
                 }
             }
         }
     }
 }
示例#15
0
        // *** OVERRIDES *** //

        public override void GenerateSpecialMoves(MoveList list, bool capturesOnly, int ply)
        {
            if (!capturesOnly)
            {
                int nSquaresFirstBoard = Board.NumSquares / 2;
                int castlingPriv       = ply == 1 ? gameHistoryPrivs[Game.GameMoveNumber] : searchStackPrivs[ply - 1];
                for (int x = 0; x < nCastlingMoves[Game.CurrentSide]; x++)
                {
                    if ((castlingMoves[Game.CurrentSide, x].RequiredPriv & castlingPriv) != 0)
                    {
                        //	make sure final landing squares on the other board are free
                        if (castlingMoves[Game.CurrentSide, x].KingFromSquare < nSquaresFirstBoard)
                        {
                            //	going from first board to second
                            if (Board[castlingMoves[Game.CurrentSide, x].KingToSquare + nSquaresFirstBoard] != null ||
                                Board[castlingMoves[Game.CurrentSide, x].OtherToSquare + nSquaresFirstBoard] != null)
                            {
                                //	occupied - castling not possible
                                continue;
                            }
                        }
                        else
                        {
                            //	going from second board to first
                            if (Board[castlingMoves[Game.CurrentSide, x].KingToSquare - nSquaresFirstBoard] != null ||
                                Board[castlingMoves[Game.CurrentSide, x].OtherToSquare - nSquaresFirstBoard] != null)
                            {
                                //	occupied - castling not possible
                                continue;
                            }
                        }
                        //	find the left-most square that needs to be free on the board castling FROM
                        int minSquare = castlingMoves[Game.CurrentSide, x].KingFromSquare;
                        minSquare = castlingMoves[Game.CurrentSide, x].KingToSquare < minSquare ? castlingMoves[Game.CurrentSide, x].KingToSquare : minSquare;
                        minSquare = castlingMoves[Game.CurrentSide, x].OtherFromSquare < minSquare ? castlingMoves[Game.CurrentSide, x].OtherFromSquare : minSquare;
                        minSquare = castlingMoves[Game.CurrentSide, x].OtherToSquare < minSquare ? castlingMoves[Game.CurrentSide, x].OtherToSquare : minSquare;
                        //	find the right-most square that needs to be free on the board castling FROM
                        int maxSquare = castlingMoves[Game.CurrentSide, x].KingFromSquare;
                        maxSquare = castlingMoves[Game.CurrentSide, x].KingToSquare > maxSquare ? castlingMoves[Game.CurrentSide, x].KingToSquare : maxSquare;
                        maxSquare = castlingMoves[Game.CurrentSide, x].OtherFromSquare > maxSquare ? castlingMoves[Game.CurrentSide, x].OtherFromSquare : maxSquare;
                        maxSquare = castlingMoves[Game.CurrentSide, x].OtherToSquare > maxSquare ? castlingMoves[Game.CurrentSide, x].OtherToSquare : maxSquare;
                        //	make sure the squares are empty
                        bool squaresEmpty = true;
                        for (int file = Board.GetFile(minSquare); squaresEmpty && file <= Board.GetFile(maxSquare); file++)
                        {
                            int sq = file * Board.NumRanks + Board.GetRank(minSquare);
                            if (sq != castlingMoves[Game.CurrentSide, x].KingFromSquare &&
                                sq != castlingMoves[Game.CurrentSide, x].OtherFromSquare &&
                                Board[sq] != null)
                            {
                                //	the path is blocked by a piece other than those involved in castling
                                squaresEmpty = false;
                            }
                        }
                        if (squaresEmpty)
                        {
                            //	make sure squares the King is passes through are not attacked
                            bool squaresAttacked = false;
                            if (castlingMoves[Game.CurrentSide, x].KingFromSquare < castlingMoves[Game.CurrentSide, x].KingToSquare)
                            {
                                for (int file = Board.GetFile(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                     !squaresAttacked && file <= Board.GetFile(castlingMoves[Game.CurrentSide, x].KingToSquare); file++)
                                {
                                    int sq = file * Board.NumRanks + Board.GetRank(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                    if (Game.IsSquareAttacked(sq, Game.CurrentSide ^ 1))
                                    {
                                        squaresAttacked = true;
                                    }
                                }
                            }
                            else
                            {
                                for (int file = Board.GetFile(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                     !squaresAttacked && file >= Board.GetFile(castlingMoves[Game.CurrentSide, x].KingToSquare); file--)
                                {
                                    int sq = file * Board.NumRanks + Board.GetRank(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                    if (Game.IsSquareAttacked(sq, Game.CurrentSide ^ 1))
                                    {
                                        squaresAttacked = true;
                                    }
                                }
                            }

                            if (!squaresAttacked)
                            {
                                //	required squares are empty and not attacked so the move is legal - add it
                                if (castlingMoves[Game.CurrentSide, x].KingFromSquare < nSquaresFirstBoard)
                                {
                                    //	going from first board to second
                                    list.BeginMoveAdd(MoveType.Castling, castlingMoves[Game.CurrentSide, x].KingFromSquare,
                                                      castlingMoves[Game.CurrentSide, x].KingToSquare + nSquaresFirstBoard);
                                    Piece king  = list.AddPickup(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                    Piece other = list.AddPickup(castlingMoves[Game.CurrentSide, x].OtherFromSquare);
                                    list.AddDrop(king, castlingMoves[Game.CurrentSide, x].KingToSquare + nSquaresFirstBoard, null);
                                    list.AddDrop(other, castlingMoves[Game.CurrentSide, x].OtherToSquare + nSquaresFirstBoard, null);
                                    list.EndMoveAdd(1000);
                                }
                                else
                                {
                                    //	going from second board to first
                                    list.BeginMoveAdd(MoveType.Castling, castlingMoves[Game.CurrentSide, x].KingFromSquare,
                                                      castlingMoves[Game.CurrentSide, x].KingToSquare - nSquaresFirstBoard);
                                    Piece king  = list.AddPickup(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                    Piece other = list.AddPickup(castlingMoves[Game.CurrentSide, x].OtherFromSquare);
                                    list.AddDrop(king, castlingMoves[Game.CurrentSide, x].KingToSquare - nSquaresFirstBoard, null);
                                    list.AddDrop(other, castlingMoves[Game.CurrentSide, x].OtherToSquare - nSquaresFirstBoard, null);
                                    list.EndMoveAdd(1000);
                                }
                            }
                        }
                    }
                }
            }
        }
示例#16
0
        public override MoveEventResponse MoveBeingGenerated(MoveList moves, int from, int to, MoveType type)
        {
            Piece movingPiece = Board[from];

            foreach (PromotionCapability promotion in promotionCapabilities)
            {
                if (movingPiece.TypeNumber == promotion.PromotingTypeNumber)
                {
                    Location        toLocation = Board.SquareToLocation(Board.PlayerSquare(movingPiece.Player, to));
                    PromotionOption option     = promotion.FromAndToConditionDelegate != null
                                                ? promotion.FromAndToConditionDelegate(Board.SquareToLocation(Board.PlayerSquare(movingPiece.Player, from)), toLocation)
                                                : promotion.ConditionDelegate(toLocation);

                    if (option != PromotionOption.CannotPromote)
                    {
                        for (int x = 0; x < Game.MAX_PIECE_TYPES; x++)
                        {
                            typesUsed[x] = false;
                        }

                        //	enemy piece being captured (if any)
                        Piece capturedPiece = Board[to];

                        //	if promotion is optional, add move without promotion
                        if (option == PromotionOption.CanPromote)
                        {
                            if (capturedPiece == null)
                            {
                                moves.AddMove(from, to, true);
                            }
                            else
                            {
                                moves.AddCapture(from, to, true);
                            }
                        }

                        //	handle traditional promotion
                        if (promotion.PromotionTypes != null)
                        {
                            if (capturedPiece == null)
                            {
                                foreach (PieceType promoteTo in promotion.PromotionTypes)
                                {
                                    moves.BeginMoveAdd(MoveType.MoveWithPromotion, from, to);
                                    moves.AddPickup(from);
                                    moves.AddDrop(movingPiece, to, promoteTo);
                                    moves.EndMoveAdd(5000 + promoteTo.MidgameValue);
                                    typesUsed[promoteTo.TypeNumber] = true;
                                }
                            }
                            else
                            {
                                foreach (PieceType promoteTo in promotion.PromotionTypes)
                                {
                                    moves.BeginMoveAdd(MoveType.CaptureWithPromotion, from, to);
                                    moves.AddPickup(from);
                                    moves.AddPickup(to);
                                    moves.AddDrop(movingPiece, to, promoteTo);
                                    moves.EndMoveAdd(5000 + promoteTo.MidgameValue + capturedPiece.PieceType.MidgameValue);
                                    typesUsed[promoteTo.TypeNumber] = true;
                                }
                            }
                        }

                        //	handle promotion by replacement
                        if (promotion.ReplacementPromotionTypes != null)
                        {
                            List <Piece> capturedPieces = Game.GetCapturedPieceList(movingPiece.Player);
                            foreach (Piece capturedFriendlyPiece in capturedPieces)
                            {
                                if (capturedFriendlyPiece.TypeNumber != movingPiece.TypeNumber &&
                                    !typesUsed[capturedFriendlyPiece.TypeNumber] &&
                                    promotion.ReplacementPromotionTypes.Contains(capturedFriendlyPiece.PieceType))
                                {
                                    if (capturedPiece == null)
                                    {
                                        moves.BeginMoveAdd(MoveType.MoveReplace, from, to, capturedFriendlyPiece.TypeNumber);
                                        moves.AddPickup(from);
                                        moves.AddDrop(capturedFriendlyPiece, to);
                                        moves.EndMoveAdd(5000 + capturedFriendlyPiece.PieceType.MidgameValue);
                                    }
                                    else
                                    {
                                        moves.BeginMoveAdd(MoveType.CaptureReplace, from, to, capturedFriendlyPiece.TypeNumber);
                                        moves.AddPickup(from);
                                        moves.AddPickup(to);
                                        moves.AddDrop(capturedFriendlyPiece, to);
                                        moves.EndMoveAdd(5000 + capturedFriendlyPiece.PieceType.MidgameValue + capturedPiece.PieceType.MidgameValue);
                                    }
                                    typesUsed[capturedFriendlyPiece.TypeNumber] = true;
                                }
                            }
                        }
                        return(MoveEventResponse.Handled);
                    }
                }
            }
            return(MoveEventResponse.NotHandled);
        }
        public override void GenerateSpecialMoves(MoveList list, bool capturesOnly, int ply)
        {
            if (!capturesOnly)
            {
                int nSquaresFirstBoard = Board.NumSquares / 2;
                int castlingPriv       = ply == 1 ? gameHistoryPrivs[Game.GameMoveNumber] : searchStackPrivs[ply - 1];
                for (int x = 0; x < nCastlingMoves[Game.CurrentSide]; x++)
                {
                    if ((castlingMoves[Game.CurrentSide, x].RequiredPriv & castlingPriv) != 0)
                    {
                        if (castlingMoves[Game.CurrentSide, x].KingFromSquare < castlingMoves[Game.CurrentSide, x].KingToSquare)
                        {
                            bool squaresEmpty = true;
                            for (int file = Board.GetFile(castlingMoves[Game.CurrentSide, x].KingFromSquare) + 1;
                                 squaresEmpty && (file <= Board.GetFile(castlingMoves[Game.CurrentSide, x].KingToSquare) ||
                                                  file <= Board.GetFile(castlingMoves[Game.CurrentSide, x].OtherFromSquare)); file++)
                            {
                                int sq = file * Board.NumRanks + Board.GetRank(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                if (sq != castlingMoves[Game.CurrentSide, x].OtherFromSquare && Board[sq] != null)
                                {
                                    squaresEmpty = false;
                                }
                            }
                            if (squaresEmpty)
                            {
                                bool squaresAttacked = false;
                                for (int file = Board.GetFile(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                     !squaresAttacked && file <= Board.GetFile(castlingMoves[Game.CurrentSide, x].KingToSquare); file++)
                                {
                                    int sq = file * Board.NumRanks + Board.GetRank(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                    if (Game.IsSquareAttacked(sq, Game.CurrentSide ^ 1))
                                    {
                                        squaresAttacked = true;
                                    }
                                }
                                if (!squaresAttacked)
                                {
                                    if (castlingMoves[Game.CurrentSide, x].KingToSquare < nSquaresFirstBoard)
                                    {
                                        //	moving from first board to second board
                                        if (Board[castlingMoves[Game.CurrentSide, x].KingToSquare + nSquaresFirstBoard] == null &&
                                            Board[castlingMoves[Game.CurrentSide, x].KingToSquare - Board.NumRanks + nSquaresFirstBoard] == null)
                                        {
                                            list.BeginMoveAdd(MoveType.Castling, castlingMoves[Game.CurrentSide, x].KingFromSquare,
                                                              castlingMoves[Game.CurrentSide, x].KingToSquare + nSquaresFirstBoard);
                                            Piece king  = list.AddPickup(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                            Piece other = list.AddPickup(castlingMoves[Game.CurrentSide, x].OtherFromSquare);
                                            list.AddDrop(king, castlingMoves[Game.CurrentSide, x].KingToSquare + nSquaresFirstBoard, null);
                                            list.AddDrop(other, castlingMoves[Game.CurrentSide, x].KingToSquare - Board.NumRanks + nSquaresFirstBoard, null);
                                            list.EndMoveAdd(1000);
                                        }
                                    }
                                    else
                                    {
                                        //	moving from second board to first board
                                        if (Board[castlingMoves[Game.CurrentSide, x].KingToSquare - nSquaresFirstBoard] == null &&
                                            Board[castlingMoves[Game.CurrentSide, x].OtherToSquare - nSquaresFirstBoard] == null)
                                        {
                                            list.BeginMoveAdd(MoveType.Castling, castlingMoves[Game.CurrentSide, x].KingFromSquare,
                                                              castlingMoves[Game.CurrentSide, x].KingToSquare - nSquaresFirstBoard);
                                            Piece king  = list.AddPickup(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                            Piece other = list.AddPickup(castlingMoves[Game.CurrentSide, x].OtherFromSquare);
                                            list.AddDrop(king, castlingMoves[Game.CurrentSide, x].KingToSquare - nSquaresFirstBoard, null);
                                            list.AddDrop(other, castlingMoves[Game.CurrentSide, x].KingToSquare - Board.NumRanks - nSquaresFirstBoard, null);
                                            list.EndMoveAdd(1000);
                                        }
                                    }

                                    for (int file = Board.GetFile(castlingMoves[Game.CurrentSide, x].KingToSquare) + 1;
                                         !squaresAttacked && file < Board.GetFile(castlingMoves[Game.CurrentSide, x].OtherFromSquare); file++)
                                    {
                                        int sq = file * Board.NumRanks + Board.GetRank(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                        squaresAttacked = Game.IsSquareAttacked(sq, Game.CurrentSide ^ 1);
                                        if (!squaresAttacked)
                                        {
                                            if (castlingMoves[Game.CurrentSide, x].KingToSquare < nSquaresFirstBoard)
                                            {
                                                //	moving from first board to second board
                                                if (Board[sq + nSquaresFirstBoard] == null &&
                                                    Board[sq - Board.NumRanks + nSquaresFirstBoard] == null)
                                                {
                                                    list.BeginMoveAdd(MoveType.Castling, castlingMoves[Game.CurrentSide, x].KingFromSquare, sq + nSquaresFirstBoard);
                                                    Piece king  = list.AddPickup(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                                    Piece other = list.AddPickup(castlingMoves[Game.CurrentSide, x].OtherFromSquare);
                                                    list.AddDrop(king, sq + nSquaresFirstBoard, null);
                                                    list.AddDrop(other, sq - Board.NumRanks + nSquaresFirstBoard, null);
                                                    list.EndMoveAdd(1000);
                                                }
                                            }
                                            else
                                            {
                                                //	moving from second board to first board
                                                if (Board[sq - nSquaresFirstBoard] == null &&
                                                    Board[sq - Board.NumRanks - nSquaresFirstBoard] == null)
                                                {
                                                    list.BeginMoveAdd(MoveType.Castling, castlingMoves[Game.CurrentSide, x].KingFromSquare, sq - nSquaresFirstBoard);
                                                    Piece king  = list.AddPickup(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                                    Piece other = list.AddPickup(castlingMoves[Game.CurrentSide, x].OtherFromSquare);
                                                    list.AddDrop(king, sq - nSquaresFirstBoard, null);
                                                    list.AddDrop(other, sq - Board.NumRanks - nSquaresFirstBoard, null);
                                                    list.EndMoveAdd(1000);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            bool squaresEmpty = true;
                            for (int file = Board.GetFile(castlingMoves[Game.CurrentSide, x].KingFromSquare) - 1;
                                 squaresEmpty && (file >= Board.GetFile(castlingMoves[Game.CurrentSide, x].KingToSquare) ||
                                                  file >= Board.GetFile(castlingMoves[Game.CurrentSide, x].OtherFromSquare)); file--)
                            {
                                int sq = file * Board.NumRanks + Board.GetRank(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                if (sq != castlingMoves[Game.CurrentSide, x].OtherFromSquare && Board[sq] != null)
                                {
                                    squaresEmpty = false;
                                }
                            }
                            if (squaresEmpty)
                            {
                                bool squaresAttacked = false;
                                for (int file = Board.GetFile(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                     !squaresAttacked && file >= Board.GetFile(castlingMoves[Game.CurrentSide, x].KingToSquare); file--)
                                {
                                    int sq = file * Board.NumRanks + Board.GetRank(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                    if (Game.IsSquareAttacked(sq, Game.CurrentSide ^ 1))
                                    {
                                        squaresAttacked = true;
                                    }
                                }
                                if (!squaresAttacked)
                                {
                                    if (castlingMoves[Game.CurrentSide, x].KingToSquare < nSquaresFirstBoard)
                                    {
                                        //	moving from first board to second board
                                        if (Board[castlingMoves[Game.CurrentSide, x].KingToSquare + nSquaresFirstBoard] == null &&
                                            Board[castlingMoves[Game.CurrentSide, x].KingToSquare + Board.NumRanks + nSquaresFirstBoard] == null)
                                        {
                                            list.BeginMoveAdd(MoveType.Castling, castlingMoves[Game.CurrentSide, x].KingFromSquare,
                                                              castlingMoves[Game.CurrentSide, x].KingToSquare + nSquaresFirstBoard);
                                            Piece king  = list.AddPickup(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                            Piece other = list.AddPickup(castlingMoves[Game.CurrentSide, x].OtherFromSquare);
                                            list.AddDrop(king, castlingMoves[Game.CurrentSide, x].KingToSquare + nSquaresFirstBoard, null);
                                            list.AddDrop(other, castlingMoves[Game.CurrentSide, x].KingToSquare + Board.NumRanks + nSquaresFirstBoard, null);
                                            list.EndMoveAdd(1000);
                                        }
                                    }
                                    else
                                    {
                                        //	moving from second board to first board
                                        if (Board[castlingMoves[Game.CurrentSide, x].KingToSquare - nSquaresFirstBoard] == null &&
                                            Board[castlingMoves[Game.CurrentSide, x].KingToSquare + Board.NumRanks - nSquaresFirstBoard] == null)
                                        {
                                            list.BeginMoveAdd(MoveType.Castling, castlingMoves[Game.CurrentSide, x].KingFromSquare,
                                                              castlingMoves[Game.CurrentSide, x].KingToSquare + nSquaresFirstBoard);
                                            Piece king  = list.AddPickup(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                            Piece other = list.AddPickup(castlingMoves[Game.CurrentSide, x].OtherFromSquare);
                                            list.AddDrop(king, castlingMoves[Game.CurrentSide, x].KingToSquare - nSquaresFirstBoard, null);
                                            list.AddDrop(other, castlingMoves[Game.CurrentSide, x].KingToSquare + Board.NumRanks - nSquaresFirstBoard, null);
                                            list.EndMoveAdd(1000);
                                        }
                                    }

                                    for (int file = Board.GetFile(castlingMoves[Game.CurrentSide, x].KingFromSquare) - 1;
                                         !squaresAttacked && file > Board.GetFile(castlingMoves[Game.CurrentSide, x].OtherFromSquare); file--)
                                    {
                                        int sq = file * Board.NumRanks + Board.GetRank(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                        squaresAttacked = Game.IsSquareAttacked(sq, Game.CurrentSide ^ 1);
                                        if (!squaresAttacked)
                                        {
                                            if (castlingMoves[Game.CurrentSide, x].KingToSquare < nSquaresFirstBoard)
                                            {
                                                //	moving from first board to second board
                                                if (Board[sq + nSquaresFirstBoard] == null &&
                                                    Board[sq + Board.NumRanks + nSquaresFirstBoard] == null)
                                                {
                                                    list.BeginMoveAdd(MoveType.Castling, castlingMoves[Game.CurrentSide, x].KingFromSquare, sq + nSquaresFirstBoard);
                                                    Piece king  = list.AddPickup(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                                    Piece other = list.AddPickup(castlingMoves[Game.CurrentSide, x].OtherFromSquare);
                                                    list.AddDrop(king, sq + nSquaresFirstBoard, null);
                                                    list.AddDrop(other, sq + Board.NumRanks + nSquaresFirstBoard, null);
                                                    list.EndMoveAdd(1000);
                                                }
                                            }
                                            else
                                            {
                                                //	moving from second board to first board
                                                if (Board[sq - nSquaresFirstBoard] == null &&
                                                    Board[sq + Board.NumRanks - nSquaresFirstBoard] == null)
                                                {
                                                    list.BeginMoveAdd(MoveType.Castling, castlingMoves[Game.CurrentSide, x].KingFromSquare, sq - nSquaresFirstBoard);
                                                    Piece king  = list.AddPickup(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                                    Piece other = list.AddPickup(castlingMoves[Game.CurrentSide, x].OtherFromSquare);
                                                    list.AddDrop(king, sq - nSquaresFirstBoard, null);
                                                    list.AddDrop(other, sq + Board.NumRanks - nSquaresFirstBoard, null);
                                                    list.EndMoveAdd(1000);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
示例#18
0
        public static bool CustomMoveGenerationHandler(PieceType pieceType, Piece piece, MoveList moveList, bool capturesOnly)
        {
            MoveCapability[] moves;
            int nMoves = pieceType.GetMoveCapabilities(out moves);

            for (int nMove = 0; nMove < nMoves; nMove++)
            {
                MoveCapability move       = moves[nMove];
                int            step       = 1;
                int            nextSquare = piece.Board.NextSquare(piece.Player, move.NDirection, piece.Square);
                while (nextSquare >= 0 && step <= move.MaxSteps)
                {
                    Piece pieceOnSquare = piece.Board[nextSquare];
                    if (pieceOnSquare != null)
                    {
                        if (step >= move.MinSteps && move.CanCapture && pieceOnSquare.Player != piece.Player)
                        {
                            moveList.AddCapture(piece.Square, nextSquare);
                            for (int x = 0; x < 8; x++)
                            {
                                int targetSquare = piece.Board.NextSquare(x, nextSquare);
                                if (targetSquare >= 0 && piece.Board[targetSquare] != null && piece.Board[targetSquare].Player != piece.Player)
                                {
                                    moveList.BeginMoveAdd(MoveType.ExtraCapture, piece.Square, nextSquare, targetSquare);
                                    moveList.AddPickup(piece.Square);
                                    moveList.AddPickup(nextSquare);
                                    moveList.AddPickup(targetSquare);
                                    moveList.AddDrop(piece, nextSquare);
                                    moveList.EndMoveAdd(4000 + piece.Board[nextSquare].PieceType.MidgameValue + piece.Board[targetSquare].PieceType.MidgameValue);
                                }
                            }
                        }
                        nextSquare = -1;
                    }
                    else
                    {
                        if (step >= move.MinSteps && !move.MustCapture)
                        {
                            if (!capturesOnly)
                            {
                                moveList.AddMove(piece.Square, nextSquare);
                            }
                            for (int x = 0; x < 8; x++)
                            {
                                int targetSquare = piece.Board.NextSquare(x, nextSquare);
                                if (targetSquare >= 0 && piece.Board[targetSquare] != null && piece.Board[targetSquare].Player != piece.Player)
                                {
                                    moveList.BeginMoveAdd(MoveType.ExtraCapture, piece.Square, nextSquare, targetSquare);
                                    moveList.AddPickup(piece.Square);
                                    moveList.AddPickup(targetSquare);
                                    moveList.AddDrop(piece, nextSquare);
                                    moveList.EndMoveAdd(3000 + piece.Board[targetSquare].PieceType.MidgameValue);
                                }
                            }
                        }
                        nextSquare = piece.Board.NextSquare(piece.Player, move.NDirection, nextSquare);
                        step++;
                    }
                }
            }

            return(false);
        }
 protected void generatePermutations(MoveList moves, int from, int to, int pendingBits, int activeBits)
 {
     if (pendingBits == 0)
     {
         //	here is where we generate a move, capturing whichever pieces
         //	are indicated by activeBits
         if (activeBits != 0)
         {
             //	Determine whether activeBits has only one bit set.
             //	If it has only one, the type of generated move will
             //	be MoveType.ExtraCapture (a move type inherrently
             //	understood by the framework.)  If more than one
             //	bit is set, we have multiple indirect captures and
             //	we will need to use a custom MoveType
             MoveType moveType = (activeBits & (activeBits - 1)) == 0
                                         ? MoveType.ExtraCapture
                                         : MoveType.CustomMove;
             //	Calculate the evaluation for the move (we will add to
             //	it as we pick up other pieces
             int eval = 2000 + (Board[to] != null ? Board[to].MidgameValue : 0);
             //	Add the move
             moves.BeginMoveAdd(moveType, from, to, activeBits);
             Piece movingPiece = moves.AddPickup(from);
             if (Board[to] != null)
             {
                 moves.AddPickup(to);
             }
             //	Step through the intervening squares picking up
             //	the appropriate pieces
             int direction  = Board.DirectionLookup(from, to);
             int nSteps     = 1;
             int nextSquare = Board.NextSquare(direction, from);
             while (nextSquare != to && activeBits != 0)
             {
                 if ((activeBits & (1 << (nSteps - 1))) != 0)
                 {
                     moves.AddPickup(nextSquare);
                     if (moveType == MoveType.ExtraCapture)
                     {
                         moves.SetMoveTag(nextSquare);
                     }
                     eval       += Board[nextSquare].MidgameValue;
                     activeBits ^= 1 << (nSteps - 1);
                 }
                 nextSquare = Board.NextSquare(direction, nextSquare);
                 nSteps++;
             }
             moves.AddDrop(movingPiece, to);
             moves.EndMoveAdd(eval);
         }
     }
     else
     {
         //	get the next bit from pendingBits and recursively call this
         //	function both with and without that bit in activeBits
         int newPendingBits = pendingBits ^ (pendingBits & -pendingBits);
         int currentBit     = pendingBits ^ newPendingBits;
         generatePermutations(moves, from, to, newPendingBits, activeBits);
         generatePermutations(moves, from, to, newPendingBits, activeBits | currentBit);
     }
 }
示例#20
0
        public override void GenerateSpecialMoves(MoveList list, bool capturesOnly, int ply)
        {
            if (!capturesOnly)
            {
                int castlingPriv = ply == 1 ? gameHistoryPrivs[Game.GameMoveNumber] : searchStackPrivs[ply - 1];
                for (int x = 0; x < nCastlingMoves[Game.CurrentSide]; x++)
                {
                    if ((castlingMoves[Game.CurrentSide, x].RequiredPriv & castlingPriv) != 0)
                    {
                        //	find the left-most square that needs to be free
                        int minSquare = castlingMoves[Game.CurrentSide, x].KingFromSquare;
                        minSquare = castlingMoves[Game.CurrentSide, x].KingToSquare < minSquare ? castlingMoves[Game.CurrentSide, x].KingToSquare : minSquare;
                        minSquare = castlingMoves[Game.CurrentSide, x].OtherFromSquare < minSquare ? castlingMoves[Game.CurrentSide, x].OtherFromSquare : minSquare;
                        minSquare = castlingMoves[Game.CurrentSide, x].OtherToSquare < minSquare ? castlingMoves[Game.CurrentSide, x].OtherToSquare : minSquare;
                        //	find the right-most square that needs to be free
                        int maxSquare = castlingMoves[Game.CurrentSide, x].KingFromSquare;
                        maxSquare = castlingMoves[Game.CurrentSide, x].KingToSquare > maxSquare ? castlingMoves[Game.CurrentSide, x].KingToSquare : maxSquare;
                        maxSquare = castlingMoves[Game.CurrentSide, x].OtherFromSquare > maxSquare ? castlingMoves[Game.CurrentSide, x].OtherFromSquare : maxSquare;
                        maxSquare = castlingMoves[Game.CurrentSide, x].OtherToSquare > maxSquare ? castlingMoves[Game.CurrentSide, x].OtherToSquare : maxSquare;
                        //	make sure the squares are empty
                        bool squaresEmpty = true;
                        for (int file = Board.GetFile(minSquare); squaresEmpty && file <= Board.GetFile(maxSquare); file++)
                        {
                            int sq = file * Board.NumRanks + Board.GetRank(minSquare);
                            if (sq != castlingMoves[Game.CurrentSide, x].KingFromSquare &&
                                sq != castlingMoves[Game.CurrentSide, x].OtherFromSquare &&
                                Board[sq] != null)
                            {
                                //	the path is blocked by a piece other than those involved in castling
                                squaresEmpty = false;
                            }
                        }
                        if (squaresEmpty)
                        {
                            //	make sure squares the King is passes through are not attacked
                            bool squaresAttacked = false;
                            //	if this game doesn't have check/checkmate, we don't care if the squares are attacked
                            if (hasCheckmateRule)
                            {
                                if (castlingMoves[Game.CurrentSide, x].KingFromSquare < castlingMoves[Game.CurrentSide, x].KingToSquare)
                                {
                                    for (int file = Board.GetFile(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                         !squaresAttacked && file <= Board.GetFile(castlingMoves[Game.CurrentSide, x].KingToSquare); file++)
                                    {
                                        int sq = file * Board.NumRanks + Board.GetRank(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                        if (Game.IsSquareAttacked(sq, Game.CurrentSide ^ 1))
                                        {
                                            squaresAttacked = true;
                                        }
                                    }
                                }
                                else
                                {
                                    for (int file = Board.GetFile(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                         !squaresAttacked && file >= Board.GetFile(castlingMoves[Game.CurrentSide, x].KingToSquare); file--)
                                    {
                                        int sq = file * Board.NumRanks + Board.GetRank(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                        if (Game.IsSquareAttacked(sq, Game.CurrentSide ^ 1))
                                        {
                                            squaresAttacked = true;
                                        }
                                    }
                                }
                            }

                            if (!squaresAttacked)
                            {
                                //	required squares are empty and not attacked so the move is legal - add it
                                if (Board[castlingMoves[Game.CurrentSide, x].KingFromSquare] == null)
                                {
                                    throw new Exception("!");
                                }
                                list.BeginMoveAdd(MoveType.Castling, castlingMoves[Game.CurrentSide, x].KingFromSquare,
                                                  castlingMoves[Game.CurrentSide, x].KingToSquare);
                                Piece king  = list.AddPickup(castlingMoves[Game.CurrentSide, x].KingFromSquare);
                                Piece other = list.AddPickup(castlingMoves[Game.CurrentSide, x].OtherFromSquare);
                                list.AddDrop(king, castlingMoves[Game.CurrentSide, x].KingToSquare, null);
                                list.AddDrop(other, castlingMoves[Game.CurrentSide, x].OtherToSquare, null);
                                list.EndMoveAdd(100);
                            }
                        }
                    }
                }
            }
        }