示例#1
0
文件: Piece.cs 项目: vgichar/shah
        /// <summary>
        /// Generates the move.
        /// In this class, the move is not verified if it puts its own king in check. 
        /// This is implemented in the BlackPiece and WhitePiece subclasses.
        /// </summary>
        /// <param name="board">The board</param>
        /// <param name="from">The starting square</param>
        /// <param name="to">The ending square</param>
        /// <returns></returns>
        internal virtual Move GenerateMove(Board board, int from, int to)
        {
            if (!MightMove(board, from, to)) { return null; }

            Move move = new Move(board.Status, from, to);


            move.ChangeSideToMove();// change side to move
            move.SetEnPassantTarget(null);// reset the en passant target

            if (board[to] == null)// if there is no capture
            {
                move.IncrementPly();// increment the ply 
            }
            else// if there is a capture
            {
                move.ResetPly();// reset the ply 

                // if there this moves captures a rook
                // and the ending squares is one of the board corners
                // reset castling availability
                if (board[to] is WhiteRook)
                {
                    if (to == Board.A1)
                    {
                        move.MakeWhiteLongCastlingUnavail();
                    }
                    else if (to == Board.H1)
                    {
                        move.MakeWhiteShortCastlingUnavail();
                    }
                }
                else if (board[to] is BlackRook)
                {
                    if (to == Board.A8)
                    {
                        move.MakeBlackLongCastlingUnavail();
                    }
                    else if (to == Board.H8)
                    {
                        move.MakeBlackShortCastlingUnavail();
                    }
                }
            }

            return move;
        }
示例#2
0
        /// <summary>
        /// Gets the end of the SAN (standard algebraic notation) for a move - promotion and check/checkmate representation - after the move is made
        /// without checking the status of the game or if it's a valid move.
        /// </summary>
        /// <param name="game">The game</param>
        /// <param name="move">The move</param>
        /// <returns></returns>
        public static string GetSANEnd(Game game, Move move)
        {
            // the game must not be null
            if (game == null) { throw new ArgumentNullException("game", "Resources.NullGameMsg"); }

            // the move must not be null
            if (move == null) { throw new ArgumentNullException("move", "Resources.NullMoveMsg"); }

            StringBuilder sb = new StringBuilder(3);

            if (move is PromotionMove)
            {
                // add promotion notation
                sb.Append('=').Append(pieceTypeToUpperCharConversion[(move as PromotionMove).PromotionType]);
            }

            if (game.Status == GameStatus.Check)
            {
                // add check representation
                sb.Append('+');
            }
            else if (game.Status == GameStatus.Checkmate)
            {
                // add checkmate representation
                sb.Append('#');
            }

            return sb.ToString();
        }
示例#3
0
文件: Game.cs 项目: vgichar/shah
        /// <summary>
        /// Makes a move.
        /// If the move is illegal or it's null, throws an Argument(Null)Exception.
        /// </summary>
        /// <param name="move">The move</param>
        public void Make(Move move)
        {
            // check to see if the move it's not null and it's valid
            if (move == null) { throw new ArgumentNullException("move", Resources.NullMoveMsg); }
            bool findMove = false;
            foreach (Move m in PossibleMoves)
            {
                if (move.From == m.From && move.To == m.To)
                {
                    findMove = true;
                    break;
                }
            }
            if (!findMove) { throw new ArgumentException(Resources.IllegalMoveMsg, "move"); }

            // build the event args
            CancelMoveEventArgs moveEventArgs = new CancelMoveEventArgs(move, currentBoardIndex - 1);

            // raise the Moving event
            OnMoving(moveEventArgs);

            // if the move was cancelled
            if (moveEventArgs.Cancel) { return; }

            // remove the moves after current board index (if any)
            if (!IsLast)
            {
                moveHistory.RemoveRange(currentBoardIndex, moveHistory.Count - currentBoardIndex);
            }

            // if this is a promotion, the promotion is not set and the promotion delegate is not null, call the promotion delegate
            if (move is PromotionMove && (move as PromotionMove).PromotionType == null && Promote != null)
            {
                (move as PromotionMove).PromotionType = Promote();
            }

            // make the move
            move.Make(currentBoard);

            // add the current hash to the history
            AddHistoryHash();

            // generate the possible moves
            GenerateMoves();

            // set the status of the game
            SetStatus();

            // increment the current board index
            currentBoardIndex++;

            // add move to history
            moveHistory.Add(move);

            // raise the Moved event
            OnMoved(new MoveEventArgs(move, currentBoardIndex - 1));
        }
示例#4
0
        /// <summary>
        /// Gets the begin of the SAN (standard algebraic notation) for a move - without promotion or check/checkmate representation -  before the move is made
        /// without checking the status of the game or if it's a valid move.
        /// </summary>
        /// <param name="game">The game</param>
        /// <param name="move">The move</param>
        /// <returns></returns>
        public static string GetSANBegin(Game game, Move move)
        {
            // the game must not be null
            if (game == null) { throw new ArgumentNullException("game", "Resources.NullGameMsg"); }

            // the move must not be null
            if (move == null) { throw new ArgumentNullException("move", "Resources.NullMoveMsg"); }

            StringBuilder sb = new StringBuilder(6);

            //if it's a castling move
            if (move is CastlingMove)
            {
                if (move.To == Board.G1 || move.To == Board.G8)
                {
                    // short castling
                    sb.Append("O-O");
                }
                else if (move.To == Board.C1 || move.To == Board.C8)
                {
                    // long castling
                    sb.Append("O-O-O");
                }
            }
            else
            {
                // add piece type and disambiguation
                char p = pieceTypeToUpperCharConversion[game.CurrentBoard[move.From].GetType()];
                if (p == 'P')
                {
                    // if the pawn captures, add the starting square file
                    if (move.HasCapture)
                    {
                        sb.Append(GetFileNotation(move.From));
                    }
                }
                else
                {
                    // add piece char
                    sb.Append(p);

                    // add disambiguation

                    // disambigutationList will contain starting squares that contain the same
                    // type of piece and that can move to the same ending square as "move"
                    List<int> disambiguationList = new List<int>(5);
                    foreach (Move m in game.PossibleMoves)
                    {
                        if (m.To == move.To && m.From != move.From && game.CurrentBoard[m.From].ToString() == game.CurrentBoard[move.From].ToString())
                        {
                            disambiguationList.Add(m.From);
                        }
                    }

                    if (disambiguationList.Count > 0)
                    {
                        // see if the file is unique
                        bool isFileUnique = true;
                        foreach (int from in disambiguationList)
                        {
                            if (Board.File(move.From) == Board.File(from))
                            {
                                isFileUnique = false;
                                break;
                            }
                        }

                        if (isFileUnique)
                        {
                            // insert file
                            sb.Append(Utils.GetFileNotation(move.From));
                        }
                        else
                        {
                            // see if the rank is unique
                            bool isRankUnique = true;
                            foreach (int from in disambiguationList)
                            {
                                if (Board.Rank(move.From) == Board.Rank(from))
                                {
                                    isRankUnique = false;
                                    break;
                                }
                            }

                            if (isRankUnique)
                            {
                                // insert rank
                                sb.Append(Utils.GetRankNotation(move.From));
                            }
                            else
                            {
                                // both file and rank are not unique, insert both of them
                                sb.Append(Utils.GetNotation(move.From));
                            }
                        }
                    }
                }

                // if there is a capture, add capture notation
                if (move.HasCapture)
                {
                    sb.Append('x');
                }

                // add destination square
                sb.Append(GetNotation(move.To));
            }

            return sb.ToString();
        }
示例#5
0
        /// <summary>
        /// Gets the move CAN (coordinate algebraic notation) without checking the status of the game or if it's a valid move.
        /// </summary>
        /// <param name="move">The move</param>
        /// <returns></returns>
        public static string GetCAN(Move move)
        {
            // the move must not be null
            if (move == null) { throw new ArgumentNullException("move", "Resources.NullMoveMsg"); }

            StringBuilder sb = new StringBuilder(5);

            // add starting square notation
            sb.Append(GetNotation(move.From));

            // add ending square notation
            sb.Append(GetNotation(move.To));

            // add promotion notation (if any)
            if (move is PromotionMove)
            {
                sb.Append(pieceTypeToLowerCharConversion[(move as PromotionMove).PromotionType]);
            }

            return sb.ToString();
        }
示例#6
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="move"></param>
 /// <param name="index"></param>
 public CancelMoveEventArgs(Move move, int index)
     : base(move, index)
 {
 }
示例#7
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="move"></param>
 /// <param name="index"></param>
 public MoveEventArgs(Move move, int index)
 {
     this.move = move;
     this.index = index;
 }
示例#8
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="before">The before status</param>
 /// <param name="from">The starting square</param>
 /// <param name="to">The ending square</param>
 /// <param name="rookMove">The rook move</param>
 internal CastlingMove(BoardStatus before, int from, int to, Move rookMove)
     : base(before, from, to)
 {
     this.rookMove = rookMove;
 }