예제 #1
0
        /// <summary>
        /// Change position of figure
        /// </summary>
        /// <param name="figureNumber">Number of figure.</param>
        /// <param name="to">Destination of figure.</param>
        /// <param name="computerMove"> </param>
        /// <param name="figureForPawnPromotionForComputer"> </param>
        /// <returns>True, if move was performed.</returns>
        public bool PlayerMove(int figureNumber, FigurePosition to,
                               bool computerMove = false,
                               Type figureForPawnPromotionForComputer = null)
        {
            if (!to.IsValid())
            {
                return(false);
            }

            Figure movingFigure;

            if (!figures.TryGetValue(figureNumber, out movingFigure))
            {
                return(false);
            }

            var from = movingFigure.Position;

            if (to == from)
            {
                return(false);
            }

            Figure attackedFigure       = null;
            int?   attackedFigureNumber = FindFigureNumber(to, false);

            if (attackedFigureNumber.HasValue)
            {
                if (!figures.TryGetValue(attackedFigureNumber.Value, out attackedFigure))
                {
                    return(false);
                }
            }

            if (movingFigure.Color != CurrentMoveColor) // if you try to move enemy piece?
            {
                return(false);
            }

            // Do not move computer's figures
            if (movingFigure.Color == computerColor && !computerMove)
            {
                return(false);
            }

            if (attackedFigureNumber.HasValue)
            {
                if (movingFigure.Color == attackedFigure.Color)
                {
                    return(false);
                }
            }

            // Create copy of chessboard to test the future possible position
            figuresCopy.Clear();
            for (var i = 0; i < figures.Count; i++)
            {
                figuresCopy.Add(figures.Keys[i],
                                figures.Values[i]);
            }

            #region Figures rules

            if (!movingFigure.CanMove(to, this))
            {
                return(false);
            }
            if (movingFigure is Pawn)
            {
                var pawn = (Pawn)movingFigure;
                if (to.Y == 8 || to.Y == 1)
                {
                    pawnToPositionForTransformation = to;
                }
                if (EnPassant == to)
                {
                    figuresCopy.Remove(FindFigureNumber(EnPassant + new Vector(0, -pawn.MoveVector()), true).Value);
                }
            } // casleing?
            else if (movingFigure is King)
            {
                if (Math.Abs(to.X - from.X) == 2)
                {
                    var line = CurrentMoveColor == FigureColors.White ? 1 : 8;
                    if (to.X > from.X)
                    {
                        var rookNumber = FindFigureNumber(new FigurePosition('h', line), true).Value;
                        figuresCopy.Remove(rookNumber);
                        figuresCopy.Add(rookNumber, new Rook(new FigurePosition('f', line), CurrentMoveColor));
                    }
                    else
                    {
                        var rookNumber = FindFigureNumber(new FigurePosition('a', line), true).Value;
                        figuresCopy.Remove(rookNumber);
                        figuresCopy.Add(rookNumber, new Rook(new FigurePosition('d', line), CurrentMoveColor));
                    }
                }
            }

            #endregion

            #region Make move on copy boardState

            // Move figure on test copy of chessboard to check on attacks on King
            // Need to delete figure that positions on 'to' if it exists
            if (attackedFigureNumber.HasValue)
            {
                figuresCopy.Remove(attackedFigureNumber.Value); // got piece?
            }
            else
            {
                Console.WriteLine("attackedFigureNumber is FALSE");
            }


            // Move figure to new position
            var figureType = figuresCopy.
                             Values[figuresCopy.IndexOfKey(figureNumber)].GetType();
            figuresCopy.Remove(figureNumber);
            figuresCopy.Add(figureNumber, (Figure)Activator.CreateInstance(figureType, to, CurrentMoveColor));

            #endregion

            /* Check if king on attack cell on copy boardState <- still needed?*/
            if (CanAttackOnCopyBoard(GetKingPositionOnCopy(CurrentMoveColor))) // king can be attacked?
            {
                return(false);
            }
            else
            {
                Console.WriteLine("CanAttackOnCopyBoard is false");
            }

            #region Save copy boardState

            // Can make move on "real" chessboard
            figures.Clear();
            for (int i = 0; i < figuresCopy.Count; i++)
            {
                figures.Add(figuresCopy.Keys[i],
                            figuresCopy.Values[i]);
            }

            #endregion

            /* Move performed */

            /* Change 3D model of figure if pawn promotion occured */
            var movedFigure = figures[figureNumber];
            if (movedFigure is Pawn)
            {
                if (movedFigure.Position.Y == 1 || movedFigure.Position.Y == 8)
                {
                    if (computerMove)
                    {
                        ChangePawnOnBoard(figureForPawnPromotionForComputer ?? typeof(Queen));
                    }
                    else
                    {
                        gameplayScreen.ShowFiguresBox();
                    }
                }
            }

            var isAnyFigureCaptured = attackedFigureNumber.HasValue;
            var isPawnMoved         = movedFigure is Pawn;
            // En passant
            if (movedFigure is Pawn && Math.Abs(to.X - from.X) == 2 && to.Y == from.Y)
            {
                EnPassant = new FigurePosition(from.X, (from.Y + to.Y) / 2);
            }
            else
            {
                EnPassant = null;
            }

            // Castle
            if (movedFigure is King)
            {
                SetCastling(CurrentMoveColor, CastlingTypes.Queenside, false);
                SetCastling(CurrentMoveColor, CastlingTypes.Kingside, false);
            }
            if (movedFigure is Rook)
            {
                if (from.X == 'a')
                {
                    SetCastling(CurrentMoveColor, CastlingTypes.Queenside, false);
                }
                if (from.X == 'h')
                {
                    SetCastling(CurrentMoveColor, CastlingTypes.Kingside, false);
                }
            }

            // Alternate move. Fullmove number
            if (CurrentMoveColor == FigureColors.White)
            {
                CurrentMoveColor            = FigureColors.Black; //TODO need logic to set for MP/saving
                GameState.CurrentPlayerMove = FigureColors.Black;
            }
            else
            {
                fullmoveNumber++;
                CurrentMoveColor            = FigureColors.White;
                GameState.CurrentPlayerMove = FigureColors.White;
            }

            // Halmove clock
            if (isPawnMoved || isAnyFigureCaptured)
            {
                halfmoveClock = 0;
            }
            else if (halfmoveClock.HasValue)
            {
                halfmoveClock++;
            }

            return(true);
        }