コード例 #1
0
ファイル: Board.cs プロジェクト: maxledlie/ChessSharp
        public List <Move> PawnMoves(ISquare pawn)
        {
            AssertType(pawn, PieceType.Pawn);

            byte yCoord = pawn.Location.YCoord;
            byte xCoord = pawn.Location.XCoord;

            List <Move> moves = new List <Move>();

            if (LastRow(pawn))
            {
                return(moves);
            }

            sbyte minusIfWhite = (sbyte)((pawn.Colour == PieceColour.White) ? -1 : 1);

            // Advance one square if not blocked by a piece of either colour
            if (this[xCoord, yCoord + minusIfWhite].Type == PieceType.None)
            {
                moves.Add(new Move(pawn.Location, new GridLocation(xCoord, (yCoord + minusIfWhite))));

                // Advance two squares if not blocked and haven't moved yet, and take note of the enPassant square.
                if (pawn.HasMoved == false && this[xCoord, yCoord + 2 * minusIfWhite].Type == PieceType.None)
                {
                    moves.Add(new Move(pawn.Location, new GridLocation(xCoord, (yCoord + 2 * minusIfWhite)),
                                       enPassantSquare: this[xCoord, yCoord + minusIfWhite]));
                }
            }

            // If not on the far left, can take the piece to its diagonal left
            if (xCoord != 0)
            {
                ISquare leftTarget = this[xCoord - 1, yCoord + minusIfWhite];
                if (leftTarget.Type != PieceType.None && leftTarget.Colour != pawn.Colour)
                {
                    moves.Add((new Move(pawn.Location, leftTarget.Location)));
                }
                else if (leftTarget == EnPassantSquare)
                {
                    moves.Add(new Move(pawn, EnPassantSquare, sideEffect: new Move(EnPassantSquare.RelativeLocation(0, (sbyte)-minusIfWhite), null)));
                }
            }

            // If not on the far right, can take the piece to its diagonal right
            if (xCoord != 7)
            {
                ISquare rightTarget = this[xCoord + 1, yCoord + minusIfWhite];
                if (rightTarget.Type != PieceType.None && rightTarget.Colour != pawn.Colour)
                {
                    moves.Add(new Move(pawn, rightTarget));
                }
                else if (rightTarget == EnPassantSquare)
                {
                    moves.Add(new Move(pawn, EnPassantSquare, sideEffect: new Move(EnPassantSquare.RelativeLocation(0, (sbyte)-minusIfWhite), null)));
                }
            }
            return(moves);
        }
コード例 #2
0
ファイル: State.cs プロジェクト: tuxmania87/ChessLib
 public bool Equals(State other)
 {
     if (ReferenceEquals(null, other))
     {
         return(false);
     }
     // if (ReferenceEquals(this, other)) return true;
     return(LastMove.Equals(other.LastMove) &&
            Key.Equals(other.Key) &&
            PawnStructureKey.Equals(other.PawnStructureKey) &&
            EnPassantSquare.Equals(other.EnPassantSquare) &&
            CastlelingRights == other.CastlelingRights &&
            NonPawnMaterial.First() == other.NonPawnMaterial.First() &&
            NonPawnMaterial.Last() == other.NonPawnMaterial.Last() &&
            PliesFromNull == other.PliesFromNull &&
            Rule50 == other.Rule50 &&
            Pinners.Equals(other.Pinners) &&
            Checkers.Equals(other.Checkers) &&
            CapturedPiece == other.CapturedPiece &&
            Equals(Previous, other.Previous));
 }
コード例 #3
0
        /// <summary>
        /// <para>"Validates" a move using simple logic. For example that the piece actually being moved exists etc.</para>
        /// <para>This is basically only useful while developing and/or debugging</para>
        /// </summary>
        /// <param name="move">The move to check for logical errors</param>
        /// <returns>True if move "appears" to be legal, otherwise false</returns>
        public bool IsPseudoLegal(Move move)
        {
            // Verify that the piece actually exists on the board at the location defined by the move struct
            if ((_bitboardPieces[move.GetMovingPiece().ToInt()] & move.GetFromSquare()).Empty())
            {
                return(false);
            }

            var to = move.GetToSquare();

            if (move.IsCastlelingMove())
            {
                // TODO : Basic castleling verification
                if (CanCastle(move.GetFromSquare() < to ? ECastleling.Short : ECastleling.Long))
                {
                    return(true);
                }

                var mg = new MoveGenerator(Position);
                mg.GenerateMoves();
                return(mg.Moves.Contains(move));
            }
            else if (move.IsEnPassantMove())
            {
                // TODO : En-passant here

                // TODO : Test with unit test
                var opponent = ~move.GetMovingSide();
                if (EnPassantSquare.PawnAttack(opponent) & Position.Pieces(EPieceType.Pawn, opponent))
                {
                    return(true);
                }
            }
            else if (move.IsCaptureMove())
            {
                var opponent = ~move.GetMovingSide();
                if ((_occupiedBySide[opponent.Side] & to).Empty())
                {
                    return(false);
                }

                if ((_bitboardPieces[move.GetCapturedPiece().ToInt()] & to).Empty())
                {
                    return(false);
                }
            }
            else if ((_occupied & to) != 0)
            {
                return(false);
            }

            // ReSharper disable once SwitchStatementMissingSomeCases
            switch (move.GetMovingPiece().Type())
            {
            case EPieceType.Bishop:
            case EPieceType.Rook:
            case EPieceType.Queen:
                if (move.GetFromSquare().BitboardBetween(to) & _occupied)
                {
                    return(false);
                }

                break;
            }

            return(true);
        }