Пример #1
0
        private IEnumerable <ChessDraw> getForewardDraws(IChessBoard board, ChessPosition drawingPiecePosition)
        {
            var draws = new List <ChessDraw>();
            var piece = board.GetPieceAt(drawingPiecePosition);

            var coordsPosOneForeward = new Tuple <int, int>(drawingPiecePosition.Row + (piece.Color == ChessColor.White ? 1 : -1), drawingPiecePosition.Column);
            var coordsPosTwoForeward = new Tuple <int, int>(drawingPiecePosition.Row + (piece.Color == ChessColor.White ? 2 : -2), drawingPiecePosition.Column);

            if (ChessPosition.AreCoordsValid(coordsPosOneForeward))
            {
                var  posOneForeward = new ChessPosition(coordsPosOneForeward);
                bool oneForeward    = !board.IsCapturedAt(posOneForeward);

                if (oneForeward)
                {
                    draws.Add(new ChessDraw(board, drawingPiecePosition, posOneForeward));

                    if (!piece.WasMoved && ChessPosition.AreCoordsValid(coordsPosTwoForeward))
                    {
                        var posTwoForeward = new ChessPosition(coordsPosTwoForeward);

                        if (!board.IsCapturedAt(posTwoForeward))
                        {
                            draws.Add(new ChessDraw(board, drawingPiecePosition, posTwoForeward));
                        }
                    }
                }
            }

            return(draws);
        }
Пример #2
0
        private IEnumerable <ChessPosition> getStandardDrawPositions(ChessPosition position)
        {
            // get positions next to the current position of the king (all permutations of { -1, 0, +1 }^2 except (0, 0))
            var coords = new Tuple <int, int>[]
            {
                new Tuple <int, int>(position.Row - 1, position.Column - 1),
                new Tuple <int, int>(position.Row - 1, position.Column),
                new Tuple <int, int>(position.Row - 1, position.Column + 1),
                new Tuple <int, int>(position.Row, position.Column - 1),
                new Tuple <int, int>(position.Row, position.Column + 1),
                new Tuple <int, int>(position.Row + 1, position.Column - 1),
                new Tuple <int, int>(position.Row + 1, position.Column),
                new Tuple <int, int>(position.Row + 1, position.Column + 1),
            };

            // only retrieve positions that are actually onto the chess board (and not off scale)
            var positions = coords.Where(x => ChessPosition.AreCoordsValid(x)).Select(x => new ChessPosition(x.Item1, x.Item2));

            return(positions);
        }
Пример #3
0
        /// <summary>
        /// Compute the field positions that can be captured by the given chess piece.
        /// </summary>
        /// <param name="board">The chess board representing the game situation</param>
        /// <param name="drawingPiecePosition">The chess position of the chess piece to be drawn</param>
        /// <param name="precedingEnemyDraw">The last draw made by the opponent</param>
        /// <param name="analyzeDrawIntoCheck">Indicates whether drawing into a check situation should be analyzed</param>
        /// <returns>a list of all possible chess draws</returns>
        public IEnumerable <ChessDraw> GetDraws(IChessBoard board, ChessPosition drawingPiecePosition, ChessDraw?precedingEnemyDraw = null, bool analyzeDrawIntoCheck = false)
        {
            var piece = board.GetPieceAt(drawingPiecePosition);

            // make sure the chess piece is a knight
            if (piece.Type != ChessPieceType.Knight)
            {
                throw new InvalidOperationException("The chess piece is not a knight.");
            }

            // get positions next to the current position of the king (all permutations of { -1, 0, +1 }^2 except (0, 0))
            var coords = new Tuple <int, int>[]
            {
                new Tuple <int, int>(drawingPiecePosition.Row - 2, drawingPiecePosition.Column - 1),
                new Tuple <int, int>(drawingPiecePosition.Row - 2, drawingPiecePosition.Column + 1),
                new Tuple <int, int>(drawingPiecePosition.Row - 1, drawingPiecePosition.Column - 2),
                new Tuple <int, int>(drawingPiecePosition.Row - 1, drawingPiecePosition.Column + 2),
                new Tuple <int, int>(drawingPiecePosition.Row + 1, drawingPiecePosition.Column - 2),
                new Tuple <int, int>(drawingPiecePosition.Row + 1, drawingPiecePosition.Column + 2),
                new Tuple <int, int>(drawingPiecePosition.Row + 2, drawingPiecePosition.Column - 1),
                new Tuple <int, int>(drawingPiecePosition.Row + 2, drawingPiecePosition.Column + 1),
            };

            // only retrieve positions that are actually onto the chess board (and not off scale)
            var positions = coords.Where(x => ChessPosition.AreCoordsValid(x)).Select(x => new ChessPosition(x));

            // do not draw into positions captured by allied chess pieces
            positions = positions.Where(x => !board.IsCapturedAt(x) || board.GetPieceAt(x).Color != piece.Color);

            // transform positions to chess draws
            var draws = positions.Select(newPos => new ChessDraw(board, drawingPiecePosition, newPos));

            if (analyzeDrawIntoCheck && draws?.Count() > 0)
            {
                // remove draws that would draw into a check situation
                draws = draws.Where(x => !ChessDrawSimulator.Instance.IsDrawIntoCheck(board, x));
            }

            return(draws);
        }
Пример #4
0
        private IEnumerable <ChessDraw> getCatchDraws(IChessBoard board, ChessPosition drawingPiecePosition, ChessDraw?precedingEnemyDraw = null)
        {
            var draws = new List <ChessDraw>();
            var piece = board.GetPieceAt(drawingPiecePosition);

            // get the possible chess field positions (info: right / left from the point of view of the white side player)
            var coordsPosCatchLeft  = new Tuple <int, int>(drawingPiecePosition.Row + (piece.Color == ChessColor.White ? 1 : -1), drawingPiecePosition.Column + 1);
            var coordsPosCatchRight = new Tuple <int, int>(drawingPiecePosition.Row + (piece.Color == ChessColor.White ? 1 : -1), drawingPiecePosition.Column - 1);

            // check for en-passant precondition
            bool wasLastDrawPeasantDoubleForeward =
                precedingEnemyDraw != null && precedingEnemyDraw.Value.DrawingPieceType == ChessPieceType.Peasant &&
                Math.Abs(precedingEnemyDraw.Value.OldPosition.Row - precedingEnemyDraw.Value.NewPosition.Row) == 2;

            // check if left catch / en-passant is possible
            if (ChessPosition.AreCoordsValid(coordsPosCatchLeft))
            {
                var posCatchLeft = new ChessPosition(coordsPosCatchLeft);

                bool catchLeft = board.IsCapturedAt(posCatchLeft) && board.GetPieceAt(posCatchLeft).Color != piece.Color;
                if (catchLeft)
                {
                    draws.Add(new ChessDraw(board, drawingPiecePosition, posCatchLeft));
                }

                if (wasLastDrawPeasantDoubleForeward)
                {
                    // get the positions of an enemy chess piece taken by a possible en-passant
                    var posEnPassantEnemyLeft = new ChessPosition(drawingPiecePosition.Row, drawingPiecePosition.Column + 1);

                    bool isLeftFieldCapturedByEnemy =
                        precedingEnemyDraw.Value.NewPosition == posEnPassantEnemyLeft && board.IsCapturedAt(posEnPassantEnemyLeft) &&
                        board.GetPieceAt(posEnPassantEnemyLeft).Color != piece.Color;

                    bool enPassantLeft = isLeftFieldCapturedByEnemy && Math.Abs(posEnPassantEnemyLeft.Column - drawingPiecePosition.Column) == 1;
                    if (enPassantLeft)
                    {
                        draws.Add(new ChessDraw(board, drawingPiecePosition, posCatchLeft));
                    }
                }
            }

            // check if right catch / en-passant is possible
            if (ChessPosition.AreCoordsValid(coordsPosCatchRight))
            {
                var posCatchRight = new ChessPosition(coordsPosCatchRight);

                bool catchRight = board.IsCapturedAt(posCatchRight) && board.GetPieceAt(posCatchRight).Color != piece.Color;
                if (catchRight)
                {
                    draws.Add(new ChessDraw(board, drawingPiecePosition, posCatchRight));
                }

                if (wasLastDrawPeasantDoubleForeward)
                {
                    // get the positions of an enemy chess piece taken by a possible en-passant
                    var posEnPassantEnemyRight = new ChessPosition(drawingPiecePosition.Row, drawingPiecePosition.Column - 1);

                    bool isRightFieldCapturedByEnemy =
                        precedingEnemyDraw.Value.NewPosition == posEnPassantEnemyRight &&
                        board.IsCapturedAt(posEnPassantEnemyRight) && board.GetPieceAt(posEnPassantEnemyRight).Color != piece.Color;

                    bool enPassantRight = isRightFieldCapturedByEnemy && Math.Abs(posEnPassantEnemyRight.Column - drawingPiecePosition.Column) == 1;
                    if (enPassantRight)
                    {
                        draws.Add(new ChessDraw(board, drawingPiecePosition, posCatchRight));
                    }
                }
            }

            return(draws);
        }
Пример #5
0
        /// <summary>
        /// Compute the field positions that can be captured by the given chess piece.
        /// </summary>
        /// <param name="board">The chess board representing the game situation</param>
        /// <param name="drawingPiecePosition">The chess position of the chess piece to be drawn</param>
        /// <param name="precedingEnemyDraw">The last draw made by the opponent</param>
        /// <param name="analyzeDrawIntoCheck">Indicates whether drawing into a check situation should be analyzed</param>
        /// <returns>a list of all possible chess draws</returns>
        public IEnumerable <ChessDraw> GetDraws(IChessBoard board, ChessPosition drawingPiecePosition, ChessDraw?precedingEnemyDraw = null, bool analyzeDrawIntoCheck = false)
        {
            var piece = board.GetPieceAt(drawingPiecePosition);

            // make sure the chess piece is bishop-like
            if (piece.Type != ChessPieceType.Bishop && piece.Type != ChessPieceType.Queen)
            {
                throw new InvalidOperationException("The chess piece is not a bishop.");
            }

            var draws = new List <ChessDraw>();

            // get upper left-side draws
            for (int i = 1; i < 8; i++)
            {
                // get position and make sure it is valid (otherwise exit loop)
                var coords = new Tuple <int, int>(drawingPiecePosition.Row + i, drawingPiecePosition.Column - i);
                if (!ChessPosition.AreCoordsValid(coords))
                {
                    break;
                }

                var newPos = new ChessPosition(coords);

                if (!board.IsCapturedAt(newPos) || board.GetPieceAt(newPos).Color != piece.Color)
                {
                    draws.Add(new ChessDraw(board, drawingPiecePosition, newPos));
                }
                if (board.IsCapturedAt(newPos))
                {
                    break;
                }
            }

            // get lower left-side draws
            for (int i = 1; i < 8; i++)
            {
                // get position and make sure it is valid (otherwise exit loop)
                var coords = new Tuple <int, int>(drawingPiecePosition.Row - i, drawingPiecePosition.Column - i);
                if (!ChessPosition.AreCoordsValid(coords))
                {
                    break;
                }

                var newPos = new ChessPosition(coords);

                if (!board.IsCapturedAt(newPos) || board.GetPieceAt(newPos).Color != piece.Color)
                {
                    draws.Add(new ChessDraw(board, drawingPiecePosition, newPos));
                }
                if (board.IsCapturedAt(newPos))
                {
                    break;
                }
            }

            // get upper right-side draws
            for (int i = 1; i < 8; i++)
            {
                // get position and make sure it is valid (otherwise exit loop)
                var coords = new Tuple <int, int>(drawingPiecePosition.Row + i, drawingPiecePosition.Column + i);
                if (!ChessPosition.AreCoordsValid(coords))
                {
                    break;
                }

                var newPos = new ChessPosition(coords);

                if (!board.IsCapturedAt(newPos) || board.GetPieceAt(newPos).Color != piece.Color)
                {
                    draws.Add(new ChessDraw(board, drawingPiecePosition, newPos));
                }
                if (board.IsCapturedAt(newPos))
                {
                    break;
                }
            }

            // get lower right-side draws
            for (int i = 1; i < 8; i++)
            {
                // get position and make sure it is valid (otherwise exit loop)
                var coords = new Tuple <int, int>(drawingPiecePosition.Row - i, drawingPiecePosition.Column + i);
                if (!ChessPosition.AreCoordsValid(coords))
                {
                    break;
                }

                var newPos = new ChessPosition(coords);

                if (!board.IsCapturedAt(newPos) || board.GetPieceAt(newPos).Color != piece.Color)
                {
                    draws.Add(new ChessDraw(board, drawingPiecePosition, newPos));
                }
                if (board.IsCapturedAt(newPos))
                {
                    break;
                }
            }

            // analyze draw into a check situation
            if (analyzeDrawIntoCheck && draws?.Count() > 0)
            {
                draws = draws.Where(draw => !ChessDrawSimulator.Instance.IsDrawIntoCheck(board, draw)).ToList();
            }

            return(draws);
        }