Beispiel #1
0
        /// <summary>
        /// Check cell on attacking by another figur.
        /// </summary>
        /// <param name="to">Checking cell position.</param>
        /// <returns>True if attacked, false if not.</returns>
        public bool CanAttackOnCopyBoard(FigurePosition to)
        {
            if (!to.IsValid())
            {
                return(false);
            }

            foreach (var figure in figuresCopy.Values)
            {
                // check color
                if (figure.Color == CurrentMoveColor)
                {
                    continue;
                }
                var from = figure.Position;
                // Cell not at attack, it occupied by enemy
                if (from == to)
                {
                    return(false);
                }
                // check only-attack-rules
                if (figure.CanAttack(to, this))
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #2
0
        /// <summary>
        /// Find figure number on boardState
        /// </summary>
        /// <param name="position">Type position</param>
        /// <param name="findOnCopy">If true - search on boardState temporary copy</param>
        /// <returns>Type number or null</returns>
        public int?FindFigureNumber(FigurePosition position, bool findOnCopy)
        {
            Figure fpc;
            var    figuresOnBoard = findOnCopy ? figuresCopy : figures;

            for (int i = 0; i < FiguresNumber; i++)
            {
                if (figuresOnBoard.TryGetValue(i, out fpc))
                {
                    if (fpc.Position == position)
                    {
                        return(i);
                    }
                }
            }
            return(null);
        }
Beispiel #3
0
        public void ComputerMove(String notation)
        {
            Trace.WriteLine(notation);
            /* Null move? */
            if (notation == "0000")
            {
                /* End of the game for computer */
                return;
            }
            /* Convert notation to coordinates */
            var  from = new FigurePosition(notation[0], int.Parse(notation[1].ToString(CultureInfo.InvariantCulture)));
            var  to   = new FigurePosition(notation[2], int.Parse(notation[3].ToString(CultureInfo.InvariantCulture)));
            Type promotionFigureType = null;

            if (notation.Length > 4)
            {
                /* Pawn promotion */
                switch (notation[4])
                {
                case 'n':
                    promotionFigureType = typeof(Knight);
                    break;

                case 'b':
                    promotionFigureType = typeof(Bishop);
                    break;

                case 'r':
                    promotionFigureType = typeof(Rook);
                    break;

                case 'q':
                    promotionFigureType = typeof(Queen);
                    break;
                }
            }
            var figureNumber = FindFigureNumber(from, false).Value;
            var moved        = PlayerMove(figureNumber, to, true, promotionFigureType);

            Debug.Assert(moved);
        }
Beispiel #4
0
 public bool IsPositionOccupied(FigurePosition position, bool afterMove)
 {
     return(FindFigureNumber(position, afterMove).HasValue);
 }
Beispiel #5
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);
        }