示例#1
0
        private static string GetCastlingAvailabilityFenString(Castling castlingInfo)
        {
            var castlingAvailability = string.Empty;

            if (!castlingInfo.HasFlag(Castling.WhiteKingMoved))
            {
                if (!castlingInfo.HasFlag(Castling.WhiteKingsideRookMoved))
                {
                    castlingAvailability += "K";
                }
                if (!castlingInfo.HasFlag(Castling.WhiteQueensideRookMoved))
                {
                    castlingAvailability += "Q";
                }
            }

            if (!castlingInfo.HasFlag(Castling.BlackKingMoved))
            {
                if (!castlingInfo.HasFlag(Castling.BlackKingsideRookMoved))
                {
                    castlingAvailability += "k";
                }
                if (!castlingInfo.HasFlag(Castling.BlackQueensideRookMoved))
                {
                    castlingAvailability += "q";
                }
            }

            return(string.IsNullOrEmpty(castlingAvailability) ? "-" : castlingAvailability);
        }
示例#2
0
文件: King.cs 项目: ikcilrep/Hunter
        public override HashSet <IMove> PossibleMoves(Board board)
        {
            var position = board.FindPiece(this);

            var topRightCorner = new Position((byte)Math.Min(Position.MaxRow, position.Row + 1),
                                              (byte)Math.Min(Position.MaxColumn, position.Column + 1));

            var bottomLeftCorner = new Position((byte)Math.Max(Position.MinRow, position.Row - 1),
                                                (byte)Math.Max(Position.MinColumn, position.Column - 1));


            var range = Positions.Range(topRightCorner, bottomLeftCorner);

            range.ExceptWith(board.PiecesInRange(range, Color));

            var result = new HashSet <IMove>(range.Select(p => new Move(this, p, board)));

            void AddCastling(bool isLong)
            {
                if (Castling.IsCastling(this, isLong, board))
                {
                    result.Add(new Castling(this, isLong, board));
                }
            }

            AddCastling(false);
            AddCastling(true);

            return(result);
        }
        protected void HandleCastling(Player player, bool longCastling)
        {
            Castling castling = new Castling(player, longCastling);

            this.game.AddMove(castling);
            this.board.PerformMove(castling);
        }
示例#4
0
        public void Process(char c, ref IProcess step)
        {
            switch (c)
            {
            case 'w':
            case 'b':
                this.found = true;
                this.result.ActiveColor = c;
                break;

            case ' ':
                if (!this.found)
                {
                    this.result.Error = true;
                    step = null;
                }
                else
                {
                    step = new Castling(this.result);
                }
                break;

            default:
                // Unexpected char.
                this.result.Error = true;
                step = null;
                break;
            }
        }
示例#5
0
        public void PerformMove(Castling move)
        {
            int y = move.Player == Player.White ? 0 : 7;

            BoardPosition kingPosition = new BoardPosition(4, y);
            Man           king         = GetManOnPosition(kingPosition);

            int           rookX        = move.LongCastling ? 0 : 7;
            BoardPosition rookPosition = new BoardPosition(rookX, y);
            Man           rook         = GetManOnPosition(rookPosition);

            if (king == null || rook == null)
            {
                throw new ConverterException("Man to perform castling is not on position: move = " + move);
            }

            SetManOnPosition(kingPosition, null);
            SetManOnPosition(rookPosition, null);

            if (move.LongCastling)
            {
                SetManOnPosition(new BoardPosition(2, y), king);
                SetManOnPosition(new BoardPosition(3, y), rook);
            }
            else
            {
                SetManOnPosition(new BoardPosition(6, y), king);
                SetManOnPosition(new BoardPosition(5, y), rook);
            }
        }
示例#6
0
 private static string GetRookFile(Castling side, int rook, int king)
 {
     return(side switch
     {
         Castling.KingSide => king <rook?GetFileChar(rook).ToString() : string.Empty,
                                        Castling.QueenSide => king> rook?GetFileChar(rook).ToString() : string.Empty,
             _ => string.Empty
     });
 private static bool CanCastle(Position position, Castling side)
 {
     return(side switch
     {
         Castling.KingSide => (position.PieceMap & position.KingSideCastlingMask[position.SideIndex]) == 0 && (attacksMap & position.KingSideCastlingAttackMask[position.SideIndex]) == 0,
         Castling.QueenSide => (position.PieceMap & position.QueenSideCastlingMask[position.SideIndex]) == 0 && (attacksMap & position.QueenSideCastlingAttackMask[position.SideIndex]) == 0,
         _ => false
     });
示例#8
0
        public bool MovePiece(Cell currentCell, Vector3 mousePosition)
        {
            var from = new Vector2Int
            {
                x = currentCell.position.x,
                y = currentCell.position.y
            };

            var availableCells = GameEngine.GetAvailableCells(from);

            foreach (var position in availableCells)
            {
                var targetCell = mBoard.mAllCells[position.x, position.y];
                if (RectTransformUtility.RectangleContainsScreenPoint(targetCell.mRectTransform, mousePosition))
                {
                    MovePiece(currentCell, targetCell);
                    return(true);
                }
            }

            var piece = GameEngine.GetBoard().mPieces[from.x, from.y];

            if (piece.GetType() == typeof(King))
            {
                var shortCastlingMoves = Castling.GetShortMoves(currentCell.position, GameEngine);
                foreach (var castlingMove in shortCastlingMoves)
                {
                    var targetCell = mBoard.mAllCells[castlingMove.x, castlingMove.y];
                    if (RectTransformUtility.RectangleContainsScreenPoint(targetCell.mRectTransform, mousePosition))
                    {
                        MovePiece(currentCell, targetCell);
                        var rookCell       = mBoard.mAllCells[7, currentCell.position.y];
                        var targetRookCell = mBoard.mAllCells[5, currentCell.position.y];
                        MovePiece(rookCell, targetRookCell);

                        return(true);
                    }
                }


                var longCastlingMoves = Castling.GetLongMoves(currentCell.position, GameEngine);
                foreach (var castlingMove in longCastlingMoves)
                {
                    var targetCell = mBoard.mAllCells[castlingMove.x, castlingMove.y];
                    if (RectTransformUtility.RectangleContainsScreenPoint(targetCell.mRectTransform, mousePosition))
                    {
                        MovePiece(currentCell, targetCell);
                        var rookCell       = mBoard.mAllCells[0, currentCell.position.y];
                        var targetRookCell = mBoard.mAllCells[3, currentCell.position.y];
                        MovePiece(rookCell, targetRookCell);

                        return(true);
                    }
                }
            }

            return(false);
        }
示例#9
0
        public static ulong RemoveCastlingFlag(ulong hash, Castling currentCastling, Castling castlingChange)
        {
            if ((currentCastling & castlingChange) != 0)
            {
                return(hash ^ _castlingHashes[BitOperations.BitScan((ulong)castlingChange)]);
            }

            return(hash);
        }
示例#10
0
 public UndoMove(Cell from, Cell to, Piece promotion, Piece capture, Castling castling, Cell enpassant, int drawClock)
 {
     From = from;
     To = to;
     Promotion = promotion;
     Capture = capture;
     Castling = castling;
     Enpassant = enpassant;
     DrawClock = drawClock;
 }
示例#11
0
        // *** INITIALIZATION *** //

        #region SetGameVariables
        public override void SetGameVariables()
        {
            base.SetGameVariables();
            Array                  = "r1nb2bn1r/1rnbqkbnr/pppppppppp/10/10/10/10/PPPPPPPPPP/1RNBQKBNR/R1NB2BN1R";
            PromotionTypes         = "QRBN";
            PawnMultipleMove.Value = "Fast Pawn";
            EnPassant              = true;
            Castling.AddChoice("Colossus", "King starting on the second rank slides 1-3 spaces short " +
                               "or 1-4 spaces long to castle with the piece on the b or i file");
            Castling.Value = "Colossus";
        }
示例#12
0
        // *** INITIALIZATION *** //

        #region SetGameVariables
        public override void SetGameVariables()
        {
            base.SetGameVariables();
            Array = "#{BlackArray}/8/8/8/8/#{WhiteArray}";
            Castling.RemoveChoice("Flexible");
            WhiteArmy      = new ChoiceVariable(new string[] { "Fabulous FIDEs", "Colorbound Clobberers", "Remarkable Rookies", "Nutty Knights" });
            BlackArmy      = new ChoiceVariable(new string[] { "Fabulous FIDEs", "Colorbound Clobberers", "Remarkable Rookies", "Nutty Knights" });
            PawnDoubleMove = true;
            EnPassant      = true;
            Castling.AddChoice("CwDA", "Standard castling with the extra exception to prevent color-bound pieces from changing square colors");
            Castling.Value = "CwDA";
        }
示例#13
0
 public override void SetGameVariables()
 {
     base.SetGameVariables();
     Array = "w10w/1crnbqkbnrc1/1pppppppppp1/12/12/12/12/12/12/1PPPPPPPPPP1/1CRNBQKBNRC1/W10W";
     PromotionRule.AddChoice("Omega", "Standard promotion except that pawns promote on the 11th rank");
     PromotionRule.Value = "Omega";
     PromotionTypes      = "QRBNCW";
     Castling.AddChoice("Omega", "Omega Chess requires custom castling handling because the notations of the board squares is non-standard");
     Castling.Value         = "Omega";
     PawnMultipleMove.Value = "@3(2,3)";
     EnPassant = true;
 }
示例#14
0
        // *** INITIALIZATION *** //

        #region SetGameVariables
        public override void SetGameVariables()
        {
            base.SetGameVariables();
            Array = "12/12/2rnbqkbnr2/2pppppppp2/12/12/12/12/2PPPPPPPP2/2RNBQKBNR2/12/12";
            Castling.AddChoice("ChessOnA12x12Board", "Kings on g3 and g10 slide two squares in either direction to castle with the pieces on the c and j files");
            Castling.Value = "ChessOnA12x12Board";
            PromotionRule.AddChoice("ChessOnA12x12Board", "Standard promotion except that promote on the 10th rank");
            PromotionRule.Value    = "Custom";
            PromotionTypes         = "QRBN";
            PawnMultipleMove.Value = "@4(2)";
            EnPassant = true;
        }
示例#15
0
    public void Activate(Vector2Int gridPoint)
    {
        if (getPieceTypeAtGrid(gridPoint) == PieceType.King && (gridPoint == new Vector2Int(4, 0) || gridPoint == new Vector2Int(4, 7)))
        {
            Castling goTo = GetComponent <Castling>();
            goTo.Activate();
        }

        ActiveSelection(gridPoint, false);

        Display.instance.selectSimplePieceAtGrid(startGridPoint);
    }
示例#16
0
    public void Disactivate()
    {
        if (!this.enabled)
        {
            return;
        }

        Castling goTo = GetComponent <Castling>();

        goTo.Disactivate();

        DisactiveSelection();
    }
示例#17
0
        public Move Parse(string str)
        {
            Move move;

            if (str[0] == '0')
            {
                move = Castling.Parse(str, turn);
            }
            else
            {
                move = new AtomicMove(str);
            }
            return(move);
        }
示例#18
0
 public          Castling this[int side]
 {
     get { return(side == 0 ? WhiteCastling : BlackCastling); }
     set
     {
         if (side == 0)
         {
             WhiteCastling = value;
         }
         else
         {
             BlackCastling = value;
         }
     }
 }
示例#19
0
        public static string GetCastlingOptionsString(Castling option, bool isChess960, List <int> rooks, int king)
        {
            string res = string.Empty;

            if ((option & Castling.KingSide) != 0)
            {
                res += isChess960 ? GetRookFile(Castling.KingSide, rooks.Max(), king) : "k";
            }

            if ((option & Castling.QueenSide) != 0)
            {
                res += isChess960 ? GetRookFile(Castling.QueenSide, rooks.Min(), king) : "q";
            }

            return(string.Concat(res.OrderBy(c => c)));
        }
示例#20
0
        public void HighLightCells(Cell currentCell)
        {
            foreach (var highlightedPosition in GameEngine.GetAvailableCells(currentCell.position))
            {
                HighLightCell(highlightedPosition);
            }

            if (currentCell.mCurrentPiece != null && typeof(View.Pieces.King) == currentCell.mCurrentPiece.GetType())
            {
                var moves = Castling.GetMoves(currentCell.position, GameEngine);
                foreach (var move in moves)
                {
                    HighLightCell(move);
                }
            }
        }
示例#21
0
        public void CheckMovies_Short_Castling_Occupied_Field()
        {
            //Arrange
            var chessboard   = new ChessboardModel(new ChessMovie());
            var pieceFactory = new ChessPieceFactory();

            chessboard["e1"].Piece = pieceFactory.Create(ColourOfPiece.White, KindOfPiece.King);
            chessboard["h1"].Piece = pieceFactory.Create(ColourOfPiece.White, KindOfPiece.Rook);
            chessboard["a6"].Piece = pieceFactory.Create(ColourOfPiece.Black, KindOfPiece.Bishop);
            var castling = new Castling();
            //Act

            var receivedMovies = castling.CheckMovies(new Position("e1"), chessboard);

            //Assert
            Assert.AreEqual(receivedMovies.Count(), 0);
        }
示例#22
0
        public void Move(Point start, Point finish)
        {
            if (CanMove(start, finish))
            {
                Piece mover = GameBoard.Board.FromPoint(start).Piece;

                MakeMovement(start, finish);

                if (mover != null)
                {
                    //Manages castling.
                    if (mover.ChessPiece == ChessPiece.Rook)
                    {
                        Castling longCastling  = mover.Player == Player.White ? Castling.LongWhite : Castling.LongBlack;
                        Castling shortCastling = mover.Player == Player.White ? Castling.ShortWhite : Castling.ShortBlack;

                        if (start.X == 0)
                        {
                            castling &= ~longCastling;
                        }
                        if (start.X == 7)
                        {
                            castling &= ~shortCastling;
                        }
                    }
                    else if (mover.ChessPiece == ChessPiece.King)
                    {
                        castling &= mover.Player == Player.Black ? Castling.LongWhite | Castling.ShortWhite : Castling.LongBlack | Castling.ShortBlack;
                    }

                    //Manages promotions.
                    if (mover.ChessPiece == ChessPiece.Pawn && finish.Y == 7 || finish.Y == 0)
                    {
                        Promotion(mover, finish);
                    }
                }
            }
            else if (!Castle(Turn, start, finish))
            {
                throw new InvalidChessMoveException();
            }

            ChangeTurn();
        }
示例#23
0
        public GameState(Piece[] board, Piece active, Castling castling, Cell enpassant, int draw, int move)
        {
            if (board.Length != 64)
            {
                throw new ArgumentException("Board must be 64 squares", nameof(board));
            }

            if (active != Piece.White && active != Piece.Black)
            {
                throw new ArgumentException("Must be White or Black", nameof(active));
            }

            Board = new Board((Piece[])board.Clone());
            Active = active;
            Castling = castling;
            Enpassant = enpassant;
            DrawClock = draw;
            Move = move;
        }
        private static List <Move> GetCastlingMoves(int startSquare, Position position, bool onlyCaptures = false, bool capturesAndChecks = false)
        {
            List <Move> moves = new List <Move>();
            // Castling can also deliver a check

            Castling castlingOptions = position.SideToMoveCastlingOptions;

            if (((castlingOptions & Castling.KingSide) != 0) && CanCastle(position, Castling.KingSide))
            {
                int  endSquare = position.WhiteToMove ? 62 : 6;
                int  rookSqare = (position.WhiteToMove ? 56 : 0) + position.KingSideRookFile;
                bool isCheck   = (enemyCheckMap[Piece.Rook] & (1ul << rookSqare)) != 0;

                if (!onlyCaptures || capturesAndChecks && isCheck)
                {
                    moves.Add(new Move(startSquare, position.IsChess960 ? rookSqare : endSquare)
                    {
                        IsCastling = true,
                        IsCheck    = isCheck
                    });
                }
            }

            if (((castlingOptions & Castling.QueenSide) != 0) && CanCastle(position, Castling.QueenSide))
            {
                int  endSquare = position.WhiteToMove ? 58 : 2;
                int  rookSqare = (position.WhiteToMove ? 56 : 0) + position.QueenSideRookFile;
                bool isCheck   = (enemyCheckMap[Piece.Rook] & (1ul << rookSqare)) != 0;

                if (!onlyCaptures || capturesAndChecks && isCheck)
                {
                    moves.Add(new Move(startSquare, position.IsChess960 ? rookSqare : endSquare)
                    {
                        IsCastling = true,
                        IsCheck    = isCheck
                    });
                }
            }

            return(moves);
        }
示例#25
0
        public void CheckMovies_Short_Castling_Movie_Possible()
        {
            //Arrange
            var chessboard   = new ChessboardModel(new ChessMovie());
            var pieceFactory = new ChessPieceFactory();

            chessboard["e1"].Piece = pieceFactory.Create(ColourOfPiece.White, KindOfPiece.King);
            chessboard["h1"].Piece = pieceFactory.Create(ColourOfPiece.White, KindOfPiece.Rook);
            chessboard["a6"].Piece = pieceFactory.Create(ColourOfPiece.White, KindOfPiece.Bishop);
            var castling = new Castling();
            //Act

            var receivedMovies = castling.CheckMovies(new Position("e1"), chessboard);
            var expectedMovies = new List <string>()
            {
                "g1"
            };
            var commonMovies = receivedMovies.Intersect(expectedMovies);

            //Assert
            Assert.AreEqual(expectedMovies.Count(), commonMovies.Count());
        }
示例#26
0
 /// <summary>
 /// 生成文字描述。
 /// </summary>
 public void GenerateFriendlyText()
 {
     var sb = new System.Text.StringBuilder();
     sb.Append(Piece.GetFriendlyName());
     sb.Append("从");
     sb.Append(OriginalPosition.ToString());
     sb.Append("到");
     sb.Append(NewPosition.ToString());
     if (IsCapture && CapturedPiece != null)
     {
         sb.Append(", 吃");
         sb.Append(CapturedPiece.GetFriendlyName());
     }
     if (Promotion.HasValue)
     {
         sb.Append(", 晋升为");
         sb.Append(ChessGame.OriginalMapPgnCharToPiece(Promotion.Value, Player).GetFriendlyName());
     }
     if (Castling.Equals(CastlingType.KingSide))
     {
         sb.Append(", 王翼易位");
     }
     if (Castling.Equals(CastlingType.QueenSide))
     {
         sb.Append(", 后翼易位");
     }
     if(IsEnpassant)
     {
         sb.Append(", 吃过路兵");
     }
     if (IsCheckmate.HasValue && IsCheckmate.Value)
     {
         sb.Append(", 将死");
     } else if (IsChecking.HasValue && IsChecking.Value)
     {
         sb.Append(", 将军");
     }
     this._storedFriendlyText = sb.ToString();
 }
示例#27
0
        // create a board with a FEN string
        public Board(string fen)
        {
            Match Match = FenParser.Match(fen);

            if (!Match.Success)
            {
                throw new ArgumentException(string.Format("invalid FEN string \"{0}\"", fen));
            }

            // piece placement
            string Field = Match.Groups[1].Value;

            string[]     RankPlacement = Field.Split('/');
            BoardAddress Location;
            int          File;

            Pieces = new PiecePositions();
            for (int rank = 0; rank < 8; rank++)
            {
                File = 0;
                foreach (char c in RankPlacement[7 - rank])
                {
                    Location = new BoardAddress((char)('a' + File), rank);

                    switch (c)
                    {
                    case 'p':
                        Pieces.Black.Pawns |= Location.Position;
                        break;

                    case 'P':
                        Pieces.White.Pawns |= Location.Position;
                        break;

                    case 'n':
                        Pieces.Black.Knights |= Location.Position;
                        break;

                    case 'N':
                        Pieces.White.Knights |= Location.Position;
                        break;

                    case 'b':
                        Pieces.Black.Bishops |= Location.Position;
                        break;

                    case 'B':
                        Pieces.White.Bishops |= Location.Position;
                        break;

                    case 'r':
                        Pieces.Black.Rooks |= Location.Position;
                        break;

                    case 'R':
                        Pieces.White.Rooks |= Location.Position;
                        break;

                    case 'q':
                        Pieces.Black.Queens |= Location.Position;
                        break;

                    case 'Q':
                        Pieces.White.Queens |= Location.Position;
                        break;

                    case 'k':
                        Pieces.Black.King |= Location.Position;
                        break;

                    case 'K':
                        Pieces.White.King |= Location.Position;
                        break;

                    default:     // num empty spaces
                        if (!char.IsDigit(c))
                        {
                            throw new ArgumentException(string.Format("invalid character \"{0}\" in piece placement field", c));
                        }
                        File += c - '1';     // convert char to int
                        break;
                    }

                    File++;
                }
            }

            // active color
            Field = Match.Groups[2].Value.ToLower();
            if (Field == "w")
            {
                ActiveColorWhite = true;
            }
            else
            {
                ActiveColorWhite = false;
            }

            // castling availablity
            CastlingAvailability = new Castling();
            Field = Match.Groups[3].Value;
            if (Field == "-")   // not available
            {
                CastlingAvailability.White = Castling.Move.Disallowed;
                CastlingAvailability.Black = Castling.Move.Disallowed;
            }
            else     // available to at least one player
            // check white
            {
                if (Field.Contains("K") && Field.Contains("Q"))
                {
                    CastlingAvailability.White = Castling.Move.BothSides;
                }
                else if (Field.Contains("K"))
                {
                    CastlingAvailability.White = Castling.Move.KingSide;
                }
                else if (Field.Contains("Q"))
                {
                    CastlingAvailability.White = Castling.Move.QueenSide;
                }
                else
                {
                    CastlingAvailability.White = Castling.Move.Disallowed;
                }

                // check black
                if (Field.Contains("k") && Field.Contains("q"))
                {
                    CastlingAvailability.Black = Castling.Move.BothSides;
                }
                else if (Field.Contains("k"))
                {
                    CastlingAvailability.Black = Castling.Move.KingSide;
                }
                else if (Field.Contains("q"))
                {
                    CastlingAvailability.Black = Castling.Move.QueenSide;
                }
                else
                {
                    CastlingAvailability.Black = Castling.Move.Disallowed;
                }
            }

            // enpassant location
            Field = Match.Groups[4].Value;
            if (Field == "-")
            {
                EnPassantTarget = 0;
            }
            else
            {
                EnPassantTarget = new BoardAddress(Field).Position;
            }

            // halfmove clock
            Field = Match.Groups[5].Value;
            if (!byte.TryParse(Field, out HalfMoveClock))
            {
                throw new ArgumentException(string.Format("could not parse halfmove clock \"{0}\"", Field));
            }

            // halfmove clock
            Field = Match.Groups[6].Value;
            if (!int.TryParse(Field, out FullMoveNumber))
            {
                throw new ArgumentException(string.Format("could not parse full move number \"{0}\"", Field));
            }
        }
示例#28
0
        /// <summary>
        /// 生成 SAN 字符串。
        /// </summary>
        /// <param name="gameBeforeTheMove"></param>
        /// <returns></returns>
        public string GenerateSANString(ChessGame gameBeforeTheMove)
        {
            string SANResult;
            if (Castling.Equals(CastlingType.KingSide))
            {
                SANResult = "O-O";
            }
            else if (Castling.Equals(CastlingType.QueenSide))
            {
                SANResult = "O-O-O";
            }
            else
            {
                var sb = new System.Text.StringBuilder();

                if (!(Piece is Pieces.Pawn))
                {
                    sb.Append(char.ToUpper(Piece.GetFenCharacter()));
                }

                Piece[][] board = gameBeforeTheMove.GetBoard();
                List<Move> validMoves = new List<Move>();
                for (int r = 0; r < 8; r++)
                {
                    for (int f = 0; f < 8; f++)
                    {
                        if (board[r][f] != Piece) continue;
                        Move m = new Move(new Position((File)f, 8 - r), this.NewPosition, this.Player, this.Promotion);
                        if (gameBeforeTheMove.IsValidMove(m))
                        {
                            validMoves.Add(m);
                        }
                    }
                }
                if (validMoves.Count == 0) throw new PgnException("This move " + this.ToString() + " is not valid for gameBeforeTheMove.");
                else if (validMoves.Count > 1)
                {
                    bool fileUnique = true;
                    bool rankUnique = true;
                    foreach (var move in validMoves)
                    {
                        if(!(move.OriginalPosition.Equals(this.OriginalPosition)))
                        {
                            if (move.OriginalPosition.File == this.OriginalPosition.File)
                            {
                                fileUnique = false;
                            }
                            if (move.OriginalPosition.Rank == this.OriginalPosition.Rank)
                            {
                                rankUnique = false;
                            }
                        }
                    }

                    if (fileUnique)
                        sb.Append((char)((int)'a' + (int)this.OriginalPosition.File));
                    else if (rankUnique)
                        sb.Append(this.OriginalPosition.Rank.ToString());
                    else
                    {
                        sb.Append((char)((int)'a' + (int)this.OriginalPosition.File));
                        sb.Append(this.OriginalPosition.Rank.ToString());
                    }
                }

                if (IsCapture)
                    sb.Append("x");

                sb.Append(this.NewPosition.ToString().ToLower());

                if (Promotion.HasValue)
                {
                    sb.Append("=");
                    sb.Append(Promotion.Value);
                }

                if (IsCheckmate.HasValue && IsCheckmate.Value)
                {
                    sb.Append("#");
                }
                else if (IsChecking.HasValue && IsChecking.Value)
                {
                    sb.Append("+");
                }

                SANResult = sb.ToString();
            }
            try
            {
                ChessDotNet.PgnMoveReader.ParseMove(SANResult, Player, gameBeforeTheMove);
            }
            catch (PgnException)
            {
                throw new System.ArgumentException("This move " + SANResult + " is not valid for gameBeforeTheMove.");
            }
            catch (System.ArgumentException)
            {
                throw new System.ArgumentException("This move " + SANResult + " is not valid for gameBeforeTheMove.");
            }
            this._storedSANString = SANResult;
            return SANResult;
        }
示例#29
0
        public static string ConvertToFEN(IChessItemModel[,] ch_on_b, ChessSide currentSide, Castling whitePossibleCastling, Castling blackPossibleCastling, string captureOnTheIsle, int numberOfReversibleSemiSteps, int moveCount)
        {
            StringBuilder sb = new StringBuilder();

            //Figure placement
            string figurePlacement = ConvertToShortFEN(ch_on_b);

            sb.Append(figurePlacement.Split(' ')[0]);

            //Current side (black/white)
            sb.Append(' ');
            sb.Append(currentSide == ChessSide.black ? "b" : "w");
            //Castling possibility
            sb.Append(' ');
            bool isWhiteCastlingDone = false;

            switch (whitePossibleCastling)
            {
            case Castling._none:
                isWhiteCastlingDone = true;
                break;

            case Castling._short:
                sb.Append('K');
                break;

            case Castling._long:
                sb.Append('Q');
                break;

            case Castling._short_and_long:
                sb.Append("KQ");
                break;

            case Castling._done:
                isWhiteCastlingDone = true;
                break;
            }

            switch (blackPossibleCastling)
            {
            case Castling._none:
                if (isWhiteCastlingDone)
                {
                    sb.Append('-');
                }
                break;

            case Castling._short:
                sb.Append('k');
                break;

            case Castling._long:
                sb.Append('q');
                break;

            case Castling._short_and_long:
                sb.Append("kq");
                break;

            case Castling._done:
                if (isWhiteCastlingDone)
                {
                    sb.Append('-');
                }
                break;
            }

            //Capture on the isle
            sb.Append(' ');
            sb.Append(captureOnTheIsle);
            sb.Append(' ');
            sb.Append(numberOfReversibleSemiSteps);
            sb.Append(' ');
            sb.Append(moveCount);

            return(sb.ToString());
        }
示例#30
0
        public Position MakeMove(Move move)
        {
#if DEBUG
            _moveHistory.Push(move);
#endif
#if MOVE_CONSISTENCY_CHECK
            _fenHistory.Push(_fenWriter.Write(this, true));
#endif
            // Get the curent state to apply changes on top of it
            var state = CurrentState;
            state.HalfMoveClock++;
            state.CapturedPiece = Piece.None;

            int newEnPassantSquare = -1;

            // Adjust castling flags before actually moving pieces
            Castling enemyCastlingOptions = state[1 - _colorToMove];
            Castling castlingOptions      = state[_colorToMove];
            if (enemyCastlingOptions != 0 && EnemyPieces[move.EndSquare] == Piece.Rook)
            {
                // One of the rooks was captured
                enemyCastlingOptions &= move.EndSquare % Constants.BoardFiles == QueenSideRookFile ? ~Castling.QueenSide : ~Castling.KingSide;
            }

            if (castlingOptions != 0)
            {
                if (PiecesToMove[move.StartSquare] == Piece.Rook)
                {
                    // One of the rooks was moved
                    castlingOptions &= move.StartSquare % Constants.BoardFiles == QueenSideRookFile ? ~Castling.QueenSide : ~Castling.KingSide;
                }
                else if (PiecesToMove[move.StartSquare] == Piece.King)
                {
                    // King was moved
                    castlingOptions = 0;
                }
            }

            if (EnemyPieces[move.EndSquare] != Piece.None)
            {
                // Capture, remove enemy piece from the board and reset the clock
                state.CapturedPiece = EnemyPieces[move.EndSquare];
                state.HalfMoveClock = 0;
                EnemyPieces.RemoveAt(move.EndSquare);
                PiecesToMove.Move(move.StartSquare, move.EndSquare, move.PromotionPiece);
            }
            else if (PiecesToMove[move.StartSquare] == Piece.Pawn)
            {
                // Reset the clock on pawn moves
                state.HalfMoveClock = 0;
                var enPassantOffset = WhiteToMove ? 8 : -8;
                if (move.EndSquare == state.EnPassantSquare)
                {
                    // EnPassant, remove enemy pawn from the board
                    state.CapturedPiece = Piece.Pawn;
                    EnemyPieces.RemoveAt(move.EndSquare + enPassantOffset);
                }
                else if (move.StartSquare - move.EndSquare == enPassantOffset * 2)
                {
                    // EnPassant is possible next move
                    newEnPassantSquare = move.EndSquare + enPassantOffset;
                }

                PiecesToMove.Move(move.StartSquare, move.EndSquare, move.PromotionPiece);
            }
            else if (PiecesToMove[move.StartSquare] == Piece.King &&
                     (Math.Abs(move.StartSquare - move.EndSquare) == 2 || PiecesToMove[move.EndSquare] == Piece.Rook))
            {
                // Castling
                // To support general chess 960 case remove king and rook from the board and put them to the final sqares
                (int rookStartSquare, int rookEndSquare) = GetCastlingRookMove(move);
                PiecesToMove.RemoveAt(rookStartSquare);
                PiecesToMove.RemoveAt(move.StartSquare);
                PiecesToMove.Add(Piece.King, GetCastlingKingSqare(move));
                PiecesToMove.Add(Piece.Rook, rookEndSquare);
            }
            else
            {
                // General piece move
                PiecesToMove.Move(move.StartSquare, move.EndSquare, move.PromotionPiece);
            }

            state[1 - _colorToMove] = enemyCastlingOptions;
            state[_colorToMove]     = castlingOptions;
            state.EnPassantSquare   = newEnPassantSquare;
            _gameStateHistory.Push(state);

            // Increment total moves after the black's move only
            TotalMoves  += _colorToMove;
            _colorToMove = 1 - _colorToMove;

            return(this);
        }