public IChessGame Create()
        {
            var piecesFactory   = new PiecesFactory();
            var movementHistory = new MovementHistory();
            var piecePromoter   = new PiecePromoter(movementHistory);
            var castlingMover   = new CastlingMover(movementHistory);
            var enPassantMover  = new EnPassantMover(movementHistory);
            var pieceMover      = new PieceMover(movementHistory, piecePromoter,
                                                 castlingMover, enPassantMover);
            var chessBoard = new ChessBoard(piecesFactory, pieceMover);

            List <IMovement> movements = new();
            var pawnMovement           = new PawnMovement(chessBoard);
            var enPassantMovement      = new EnPassantMovement(chessBoard);
            var kingMovement           = new KingMovement(chessBoard);
            var horizontalMovement     = new HorizontalMovement(chessBoard);
            var verticalMovement       = new VerticalMovement(chessBoard);
            var pdiagonalMovement      = new PositiveDiagonalMovement(chessBoard);
            var ndiagonalMovement      = new NegativeDiagonalMovement(chessBoard);
            var knightMovement         = new KnightMovement(chessBoard);

            movements.Add(pawnMovement);
            movements.Add(enPassantMovement);
            movements.Add(kingMovement);
            movements.Add(horizontalMovement);
            movements.Add(verticalMovement);
            movements.Add(pdiagonalMovement);
            movements.Add(ndiagonalMovement);
            movements.Add(knightMovement);
            var movementComposite = new MovementComposite(movements);

            List <IMovement> movementsWithCastling = new();
            var queensideCastlingMovement          =
                new QueensideCastlingMovement(chessBoard, movementComposite);
            var kingsideCastlingMovement =
                new KingsideCastlingMovement(chessBoard, movementComposite);

            movementsWithCastling.Add(movementComposite);
            movementsWithCastling.Add(queensideCastlingMovement);
            movementsWithCastling.Add(kingsideCastlingMovement);
            var movementCompositeWithCastling = new MovementComposite(movementsWithCastling);

            var promotionDetector = new PromotionDetector(chessBoard);

            var checkDetector = new CheckDetector(chessBoard, movementCompositeWithCastling);

            var legalMovement = new LegalMovement(chessBoard,
                                                  movementCompositeWithCastling, checkDetector);

            var moveValidator = new MoveValidator(chessBoard,
                                                  legalMovement, promotionDetector);

            var gameFinishedDetector = new GameFinishedDetector(checkDetector,
                                                                legalMovement);

            return(new ChessGame(chessBoard, moveValidator,
                                 promotionDetector, gameFinishedDetector, legalMovement));
        }
        public void BlackEnPassantTest()
        {
            //WP - white pawn
            //BP - black pawn
            //PM - possible move
            //7
            //6
            //5
            //4
            //3                   WP BP
            //2                   PM
            //1
            //0
            //  0  1  2  3  4  5  6  7
            var boardMock     = new Mock <IChessBoard>(MockBehavior.Strict);
            var historyMock   = new Mock <IReadOnlyMovementHistory>(MockBehavior.Strict);
            var whitePawnMock = new Mock <IReadOnlyChessPiece>(MockBehavior.Strict);
            var blackPawnMock = new Mock <IReadOnlyChessPiece>(MockBehavior.Strict);

            var whitePawnPosition         = new Position(6, 3);
            var blackPawnPositon          = new Position(7, 3);
            var whitePawnPreviousPosition = new Position(6, 1);
            var possibleCapturePosition   = new Position(6, 2);

            whitePawnMock
            .SetupGet(p => p.Color)
            .Returns(ChessColor.White);
            whitePawnMock
            .SetupGet(p => p.PieceType)
            .Returns(ChessPieceType.Pawn);
            whitePawnMock
            .SetupGet(p => p.Position)
            .Returns(whitePawnPosition);
            whitePawnMock
            .SetupGet(p => p.HasMoved)
            .Returns(true);

            blackPawnMock
            .SetupGet(p => p.Color)
            .Returns(ChessColor.Black);
            blackPawnMock
            .SetupGet(p => p.PieceType)
            .Returns(ChessPieceType.Pawn);
            blackPawnMock
            .SetupGet(p => p.Position)
            .Returns(blackPawnPositon);
            blackPawnMock
            .SetupGet(p => p.HasMoved)
            .Returns(true);

            var pieces = new List <IReadOnlyChessPiece>()
            {
                whitePawnMock.Object, blackPawnMock.Object
            };

            var moves = new List <ChessMove>()
            {
                new ChessMove(whitePawnPreviousPosition, whitePawnPosition)
            };

            historyMock
            .SetupGet(h => h.ChessMoves)
            .Returns(moves);

            boardMock
            .SetupGet(b => b.Pieces)
            .Returns(pieces);
            boardMock
            .SetupGet(b => b.History)
            .Returns(historyMock.Object);

            var movement       = new EnPassantMovement(boardMock.Object);
            var availableMoves = movement.GetAvailableMoves(blackPawnMock.Object);

            Assert.AreEqual(1, availableMoves.Count());
            var move = availableMoves.First();

            Assert.AreEqual(new ChessMove(blackPawnPositon, possibleCapturePosition), move);
        }
        public void WhenLastMoveWasNotDoublePawnMove_EnPassantIsNotPossible()
        {
            //WP - white pawn
            //WR - white rook
            //BP - black pawn
            //7
            //6
            //5    WR
            //4
            //3          WP BP
            //2
            //1
            //0
            //  0  1  2  3  4  5  6  7
            var boardMock     = new Mock <IChessBoard>(MockBehavior.Strict);
            var historyMock   = new Mock <IReadOnlyMovementHistory>(MockBehavior.Strict);
            var whitePawnMock = new Mock <IReadOnlyChessPiece>(MockBehavior.Strict);
            var blackPawnMock = new Mock <IReadOnlyChessPiece>(MockBehavior.Strict);
            var whiteRookMock = new Mock <IReadOnlyChessPiece>(MockBehavior.Strict);

            var whitePawnPosition = new Position(3, 3);
            var blackPawnPositon  = new Position(4, 3);
            var whiteRookPosition = new Position(1, 5);

            whitePawnMock
            .SetupGet(p => p.Color)
            .Returns(ChessColor.White);
            whitePawnMock
            .SetupGet(p => p.PieceType)
            .Returns(ChessPieceType.Pawn);
            whitePawnMock
            .SetupGet(p => p.Position)
            .Returns(whitePawnPosition);
            whitePawnMock
            .SetupGet(p => p.HasMoved)
            .Returns(true);

            blackPawnMock
            .SetupGet(p => p.Color)
            .Returns(ChessColor.Black);
            blackPawnMock
            .SetupGet(p => p.PieceType)
            .Returns(ChessPieceType.Pawn);
            blackPawnMock
            .SetupGet(p => p.Position)
            .Returns(blackPawnPositon);
            blackPawnMock
            .SetupGet(p => p.HasMoved)
            .Returns(true);

            whiteRookMock
            .SetupGet(p => p.Position)
            .Returns(whiteRookPosition);
            whiteRookMock
            .SetupGet(p => p.PieceType)
            .Returns(ChessPieceType.Rook);

            var pieces = new List <IReadOnlyChessPiece>()
            {
                whitePawnMock.Object, blackPawnMock.Object,
                whiteRookMock.Object
            };

            var moves = new List <ChessMove>()
            {
                new ChessMove(new Position(1, 1), whiteRookPosition)
            };

            historyMock
            .SetupGet(h => h.ChessMoves)
            .Returns(moves);

            boardMock
            .SetupGet(b => b.Pieces)
            .Returns(pieces);
            boardMock
            .SetupGet(b => b.History)
            .Returns(historyMock.Object);

            var movement       = new EnPassantMovement(boardMock.Object);
            var availableMoves = movement.GetAvailableMoves(whitePawnMock.Object);

            Assert.AreEqual(0, availableMoves.Count());
        }