Esempio n. 1
0
        public void GivenExistingMatch_WhenPreviousGameWonAndNoDynamitesAvailableInTheGame_ThenBotsMoveShouldBeOfOneThatBeatsItsPreviousHandWithNoDynamitAndNoWaterbomb()
        {
            // Assemble
            var           botStrategy = new BotStrategy();
            IMatchService service     = new MatchService(botStrategy);

            service.NewMatch(3, 0);

            //Act

            //first game
            service.AddGame();
            var botsFirstMove = service.BotsMove();

            service.GameResult(Outcome.Win, Move.Paper);

            //second game
            service.AddGame();
            var         botsSecondMove = service.BotsMove();
            MoveHelpers mh             = new MoveHelpers();
            var         beaters        = mh.GetBeaters(botsFirstMove).ToList();

            //Assert
            Assert.AreNotEqual(Move.Dynamite, botsSecondMove);
            Assert.AreNotEqual(Move.Waterbomb, botsSecondMove);
            Assert.Contains(botsSecondMove, beaters);
        }
Esempio n. 2
0
        public void GivenExistingMatch_WhenDynamiteAvailableInTheGameAndAlreadyUsedByBot_ThenBotsMoveShouldBeOfOneThatBeatsPlayersPreviousHand()
        {
            // Assemble
            var botStrategy = new BotStrategy();

            var strategyMock = new Mock <IBotStrategy>();

            var sequence = strategyMock.SetupSequence(m => m.GetBotsNextMove(It.IsAny <Game>(), It.IsAny <bool>(), It.IsAny <bool>()));


            IMatchService service = new MatchService(strategyMock.Object);


            service.NewMatch(3, 1);

            Move playersMove = Move.Waterbomb;

            //Act

            //first game
            sequence.Returns(Move.Dynamite);
            service.AddGame();
            var botsFirstMove = service.BotsMove();
            var gameResult    = service.GameResult(Outcome.Lose, playersMove);

            //second game
            sequence.Returns(botStrategy.GetBotsNextMove(gameResult, false, true));
            service.AddGame();
            var         botsSecondMove = service.BotsMove();
            MoveHelpers mh             = new MoveHelpers();
            var         beaters        = mh.GetBeaters(playersMove).ToList();

            //Assert
            Assert.Contains(botsSecondMove, beaters);
        }
        public static IEnumerable <TestCaseData> GetEPDestinationValidatorTestCases()
        {
            var e2 = "e2".ToBoardIndex();
            var whiteAttacksEPSquare      = "d6";
            var blackAttacksEPSquare      = "d3";
            var badEpWhite                = "e6";
            var badEpBlack                = "e3";
            var whiteEnPassantAttackBoard =
                fenTextToBoard.Translate($"rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq {whiteAttacksEPSquare} 0 2");
            var blackEnPassantAttackBoard =
                fenTextToBoard.Translate($"rnbqkbnr/ppp1pppp/8/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq {blackAttacksEPSquare} 0 2");

            yield return(new TestCaseData(whiteEnPassantAttackBoard, MoveHelpers.GenerateMove(e2, whiteAttacksEPSquare.ToBoardIndex()))
                         .SetName($"{name} - EP Index ({whiteAttacksEPSquare}) is set")
                         .Returns(MoveError.NoneSet));

            yield return(new TestCaseData(whiteEnPassantAttackBoard, MoveHelpers.GenerateMove(e2, badEpWhite.ToBoardIndex()))
                         .SetName($"{name} - EP Index ({badEpWhite}) is not set")
                         .Returns(MoveError.EpNotAvailable));

            yield return(new TestCaseData(blackEnPassantAttackBoard, MoveHelpers.GenerateMove(e2, blackAttacksEPSquare.ToBoardIndex()))
                         .SetName($"{name} - EP Index ({blackAttacksEPSquare}) is set")
                         .Returns(MoveError.NoneSet));

            yield return(new TestCaseData(blackEnPassantAttackBoard, MoveHelpers.GenerateMove(e2, badEpBlack.ToBoardIndex()))
                         .SetName($"{name} - EP Index ({badEpBlack}) is not set")
                         .Returns(MoveError.EpNotAvailable));
        }
        public static IEnumerable <TestCaseData> GetTestCases()
        {
            const string name = "Pieces blocking castling";
            const string emptyFenWhiteToMove = "4k3/8/8/8/8/8/8/4K3 w - - 0 1";

            foreach (var castlingMove in MoveHelpers.BlackCastlingMoves)
            {
                var san = castlingMove.GetCastlingSan();
                foreach (var testCaseData in GetCastlingMoves(Color.Black, castlingMove))
                {
                    yield return(testCaseData.SetName($"{name} - Black {san}: {testCaseData.TestName}"));
                }
            }

            foreach (var castlingMove in MoveHelpers.WhiteCastlingMoves)
            {
                var san = castlingMove.GetCastlingSan();
                foreach (var testCaseData in GetCastlingMoves(Color.White, castlingMove))
                {
                    yield return(testCaseData.SetName($"{name} - White {san}: {testCaseData.TestName}"));
                }
            }

            yield return(new TestCaseData(fenTextToBoard.Translate(emptyFenWhiteToMove),
                                          MoveHelpers.GenerateMove("e2".ToBoardIndex(), "e4".ToBoardIndex()))
                         .SetName($"{name} - Non-castling move should return no error")
                         .Returns(MoveError.NoneSet));

            yield return(new TestCaseData(fenTextToBoard.Translate(emptyFenWhiteToMove),
                                          MoveHelpers.GenerateMove("e2".ToBoardIndex(), "e4".ToBoardIndex(), MoveType.Castle))
                         .SetName($"{name} - Bad castling move should return no error")
                         .Returns(MoveError.BadDestination));
        }
        internal static IEnumerable <TestCaseData> GetActiveColorValidatorTestCases()
        {
            var initialBoard = new Board();
            var e2           = "e2".ToBoardIndex();
            var e3           = "e3".ToBoardIndex();
            var e4           = "e4".ToBoardIndex();
            var e6           = "e6".ToBoardIndex();
            var e7           = "e7".ToBoardIndex();

            var sourceEmptyMove = MoveHelpers.GenerateMove(e3, e4);
            var sourceOccupiedWithActiveColorMove   = MoveHelpers.GenerateMove(e2, e4);
            var sourceOccupiedWithOpponentColorMove = MoveHelpers.GenerateMove(e7, e6);

            yield return(new TestCaseData(initialBoard, sourceEmptyMove)
                         .SetName($"{name} - should return error condition if source square is empty")
                         .SetDescription("Test validator -  if source square is occupied by Active Color")
                         .Returns(MoveError.ActivePlayerHasNoPieceOnSourceSquare));

            yield return(new TestCaseData(initialBoard, sourceOccupiedWithActiveColorMove)
                         .SetName($"{name} - should return no error when source occupied by Active Color")
                         .SetDescription("Test validator -  if source square is occupied by Active Color")
                         .Returns(MoveError.NoneSet));

            yield return(new TestCaseData(initialBoard, sourceOccupiedWithOpponentColorMove)
                         .SetName($"{name} - should return error condition if source square is occupied by Opponent Color")
                         .SetDescription("Test validator -  if source square is occupied by Active Color")
                         .Returns(MoveError.ActivePlayerHasNoPieceOnSourceSquare));
        }
        public static IEnumerable <TestCaseData> GetCastlingMoves(Color color, Move move)
        {
            const string emptyFenWhiteToMove    = "4k3/8/8/8/8/8/8/4K3 w - - 0 1";
            const string emptyFenBlackToMove    = "4k3/8/8/8/8/8/8/4K3 b - - 0 1";
            var          rookInitialSquareIndex = MoveHelpers.GetRookMoveForCastleMove(move).SourceIndex;
            var          between             = BoardHelpers.InBetween(rookInitialSquareIndex, move.SourceIndex);
            var          blockerPermutations = MovingPieceService.GetAllPermutationsOfSetBits(between.GetSetBits(), 0, 0)
                                               .Where(x => x != 0);
            var fen   = color == Color.Black ? emptyFenBlackToMove : emptyFenWhiteToMove;
            var board = fenTextToBoard.Translate(fen);

            foreach (var permutation in blockerPermutations)
            {
                var editedBoard = (Board)board.Clone();
                editedBoard.Occupancy[(int)color][(int)Piece.King] = permutation;
                var strBlockers = string.Join(", ", permutation.GetSetBits());
                yield return(new TestCaseData(editedBoard, move)
                             .SetName($"Blockers on indices {strBlockers}")
                             .Returns(MoveError.CastleOccupancyBetween));
            }

            yield return(new TestCaseData(board, move)
                         .SetName("No Blockers")
                         .Returns(MoveError.NoneSet));
        }
Esempio n. 7
0
        public void GetLosingMoves()
        {
            MoveHelpers mh      = new MoveHelpers();
            var         beaters = mh.GetBeaters(Move.Rock);

            CollectionAssert.AreEquivalent(new[] { Move.Paper, Move.Dynamite }, beaters);
        }
Esempio n. 8
0
        public static IEnumerable <TestCaseData> GetTestCases()
        {
            var whitePromotionOfPawn  = "4k3/P7/8/8/8/8/8/4K3 w - - 0 1";
            var whitePromotionOfRook  = "4k3/R7/8/8/8/8/8/4K3 w - - 0 1";
            var blackPromotionOfPawn  = "4k3/8/8/8/8/8/p7/4K3 b - - 0 1";
            var blackPromotionOfQueen = "4k3/8/8/8/8/8/q7/4K3 b - - 0 1";
            var whitePromotion        = MoveHelpers.GenerateMove("a7".ToBoardIndex(), "a8".ToBoardIndex(), MoveType.Promotion);
            var blackPromotion        = MoveHelpers.GenerateMove("a2".ToBoardIndex(), "a1".ToBoardIndex(), MoveType.Promotion);

            yield return(new TestCaseData(fenTranslator.Translate(whitePromotionOfPawn), whitePromotion)
                         .SetName($"{name} - White Promoting Pawn (Valid)")
                         .Returns(MoveError.NoneSet));

            yield return(new TestCaseData(fenTranslator.Translate(whitePromotionOfRook), whitePromotion)
                         .SetName($"{name} - White Promoting Rook (Invalid)")
                         .Returns(MoveError.SourceIsNotPawn));

            yield return(new TestCaseData(fenTranslator.Translate(blackPromotionOfPawn), blackPromotion)
                         .SetName($"{name} - Black Promoting Pawn (Valid)")
                         .Returns(MoveError.NoneSet));

            yield return(new TestCaseData(fenTranslator.Translate(blackPromotionOfQueen), blackPromotion)
                         .SetName($"{name} - Black Promoting Queen (Invalid)")
                         .Returns(MoveError.SourceIsNotPawn));
        }
Esempio n. 9
0
 public static void ShouldGetPromotionPieceFromMove()
 {
     foreach (PromotionPiece pp in Enum.GetValues(typeof(PromotionPiece)))
     {
         var move = MoveHelpers.GenerateMove(45, 53, MoveType.Promotion, pp);
         Assert.AreEqual(pp, move.PromotionPiece);
     }
 }
Esempio n. 10
0
 public static void ShouldGetMoveTypeFromMove()
 {
     foreach (MoveType mt in Enum.GetValues(typeof(MoveType)))
     {
         var move = MoveHelpers.GenerateMove(45, 53, mt);
         Assert.AreEqual(mt, move.MoveType);
     }
 }
Esempio n. 11
0
 public void EndTurn()
 {
     foreach (Unit unit in Units)
     {
         if (UseAi)
         {
             unit.MoveTo(MoveHelpers.GetAiMove(unit));
             unit.Attack(MoveHelpers.GetAiAttckNode(unit.CurrNode, unit.Faction, unit));
         }
         unit.Refresh();
     }
 }
Esempio n. 12
0
        public void ApplyMove_EnPassantCaptures(string fen, int src, int dst, ulong oppPawn, ulong actPawn)
        {
            var move        = MoveHelpers.GenerateMove((ushort)src, (ushort)dst, MoveType.EnPassant);
            var board       = new FenTextToBoard().Translate(fen);
            var activeColor = board.ActivePlayer;
            var oppColor    = board.ActivePlayer.Toggle();
            var actual      = board.ApplyMoveToBoard(move);

            Assert.AreEqual(actual.Occupancy.Occupancy(activeColor, Piece.Pawn), actPawn,
                            $"{board.ActivePlayer}'s pawn structure incorrect after En Passant capture");
            Assert.AreEqual(actual.Occupancy.Occupancy(oppColor, Piece.Pawn), oppPawn,
                            $"{board.ActivePlayer.Toggle()}'s pawn structure incorrect after En Passant capture");
        }
Esempio n. 13
0
        public IEnumerable <IMove> GetLegalMoves(ushort squareIndex, ulong[][] occupancy, ushort?enPassantIdx,
                                                 CastlingAvailability castlingAvailability)
        {
            var pieceOfColor = occupancy.GetPieceOfColorAtIndex(squareIndex);

            if (pieceOfColor == null)
            {
                yield break;
            }

            var piece = pieceOfColor.Value.Piece;
            var color = pieceOfColor.Value.Color;

            var relevantOccupancy = occupancy.Occupancy();

            if (piece == Piece.Pawn && enPassantIdx.HasValue)
            {
                var epValue = enPassantIdx.Value.GetBoardValueOfIndex();
                relevantOccupancy |= epValue;
            }

            var pseudoLegalMoves = GetPseudoLegalMoves(squareIndex, piece, color, relevantOccupancy);
            var moves            = new List <IMove>();

            foreach (var destinationIndex in pseudoLegalMoves.GetSetBits())
            {
                var moveType = BoardHelpers.GetMoveType(occupancy, squareIndex, destinationIndex, enPassantIdx);
                var move     = MoveHelpers.GenerateMove(squareIndex, destinationIndex, moveType);
                moves.Add(move);
            }

            if (piece == Piece.King && IsKingSquare(squareIndex, color))
            {
                moves.AddRange(GetPseudoLegalCastlingMoves(color, castlingAvailability));
            }

            foreach (var move in moves)
            {
                var moveValidator =
                    new MoveValidator(
                        new Board(occupancy, 0, enPassantIdx, null, castlingAvailability, color, 0, true),
                        move);
                var validationResult = moveValidator.Validate();
                if (validationResult == MoveError.NoneSet)
                {
                    yield return(move);
                }
            }
        }
Esempio n. 14
0
        public static IEnumerable <TestCaseData> GetNotInCheckBeforeMoveTestCases()
        {
            var e2    = "e2".ToBoardIndex();
            var e4    = "e4".ToBoardIndex();
            var board = new Board();
            var move  = MoveHelpers.GenerateMove(e2, e4);

            yield return(new TestCaseData(board, move, true)
                         .SetName("NotInCheckBeforeMoveValidator - Castling side is in check")
                         .Returns(MoveError.CastleKingInCheck));

            yield return(new TestCaseData(board, move, false)
                         .SetName("NotInCheckBeforeMoveValidator - Castling side is not in check")
                         .Returns(MoveError.NoneSet));
        }
Esempio n. 15
0
    public static Node GetAiAttckNode(Node startingNode, Faction faction, Unit unit)
    {
        Node  desiredAttackNode  = null;
        float desireToAttackNode = 0;

        foreach (Node possibleAttackNode in MoveHelpers.GetPossibleAttackNodes(startingNode, faction))
        {
            var desire = unit.AiCalcDesireToAttackNode(possibleAttackNode);
            if (desire > desireToAttackNode)
            {
                desiredAttackNode  = possibleAttackNode;
                desireToAttackNode = desire;
            }
        }
        return(desiredAttackNode);
    }
Esempio n. 16
0
        protected static IEnumerable <TestCase <Board, Board> > GetApplyMoveToBoardTestCases()
        {
            var boardTransitions = new[]
            {
                new Board(),
                FenReader.Translate("rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1"),
                FenReader.Translate("rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 2"),
                FenReader.Translate("rnbqkbnr/ppp1pppp/8/3P4/8/8/PPPP1PPP/RNBQKBNR b KQkq - 0 2"),
                FenReader.Translate("rnb1kbnr/ppp1pppp/8/3q4/8/8/PPPP1PPP/RNBQKBNR w KQkq - 0 3"),
                FenReader.Translate("rnb1kbnr/ppp1pppp/8/3q4/8/2N5/PPPP1PPP/R1BQKBNR b KQkq - 1 3"),
                FenReader.Translate("rnbqkbnr/ppp1pppp/8/8/8/2N5/PPPP1PPP/R1BQKBNR w KQkq - 2 4"),
                FenReader.Translate("rnbqkbnr/ppp1pppp/8/8/2B5/2N5/PPPP1PPP/R1BQK1NR b KQkq - 3 4"),
                FenReader.Translate("rnbqkbnr/ppp2ppp/4p3/8/2B5/2N5/PPPP1PPP/R1BQK1NR w KQkq - 0 5"),
                FenReader.Translate("rnbqkbnr/ppp2ppp/4p3/8/2B5/2N2N2/PPPP1PPP/R1BQK2R b KQkq - 1 5"),
                FenReader.Translate("rnbqkb1r/ppp2ppp/4pn2/8/2B5/2N2N2/PPPP1PPP/R1BQK2R w KQkq - 2 6"),
                FenReader.Translate("rnbqkb1r/ppp2ppp/4pn2/8/2B5/2N2N2/PPPP1PPP/R1BQ1RK1 b kq - 3 6"),
                FenReader.Translate("rnbqk2r/ppp1bppp/4pn2/8/2B5/2N2N2/PPPP1PPP/R1BQ1RK1 w kq - 4 7"),
                FenReader.Translate("rnbqk2r/ppp1bppp/4pn2/8/2BP4/2N2N2/PPP2PPP/R1BQ1RK1 b kq d3 0 7"),
                FenReader.Translate("rnbq1rk1/ppp1bppp/4pn2/8/2BP4/2N2N2/PPP2PPP/R1BQ1RK1 w - - 1 8")
            };
            var movesToApply = new[]
            {
                MoveHelpers.GenerateMove(12, 28),
                MoveHelpers.GenerateMove(51, 35),
                MoveHelpers.GenerateMove(28, 35),
                MoveHelpers.GenerateMove(59, 35),
                MoveHelpers.GenerateMove(1, 18),
                MoveHelpers.GenerateMove(35, 59),
                MoveHelpers.GenerateMove(5, 26),
                MoveHelpers.GenerateMove(52, 44),
                MoveHelpers.GenerateMove(6, 21),
                MoveHelpers.GenerateMove(62, 45),
                MoveHelpers.WhiteCastleKingSide,
                MoveHelpers.GenerateMove(61, 52),
                MoveHelpers.GenerateMove(11, 27),
                MoveHelpers.BlackCastleKingSide
            };

            for (var boardIndex = 0; boardIndex < movesToApply.Length; boardIndex++)
            {
                var startingBoard = boardTransitions[boardIndex];
                var endingBoard   = boardTransitions[boardIndex + 1];
                var move          = movesToApply[boardIndex];
                yield return(new TestCase <Board, Board>(endingBoard, startingBoard,
                                                         $"{boardIndex:D2} {move}", move));
            }
        }
        public static IEnumerable <TestCaseData> GetNoPieceAtSourceTestCases()
        {
            const string name        = "Source Square";
            var          source      = "h3".ToBoardIndex();
            var          destination = "h4".ToBoardIndex();
            var          board       = new Board();

            // Double-check that test case is valid
            Assert.AreEqual(0, board.Occupancy.Occupancy(board.ActivePlayer) & source.GetBoardValueOfIndex(), 0,
                            "Test is not arranged properly. Piece found at source square.");

            yield return(new TestCaseData(board, MoveHelpers.GenerateMove(source, destination),
                                          PseudoLegalMovesIncludingDestinationSquare)
                         .SetName($"{name} - should return error when no piece is at source.")
                         .SetDescription("Validates an error is returned when nothing is on source")
                         .Returns(MoveError.ActivePlayerHasNoPieceOnSourceSquare));
        }
Esempio n. 18
0
        /// <summary>
        ///     Get the test cases for testing <see cref="NotInCheckAfterMoveValidator" />
        /// </summary>
        /// <returns></returns>
        public static IEnumerable <TestCaseData> GetKingNotInCheckAfterMoveValidatorTests()
        {
            const string pseudoTestCaseName = "Validator.Move.KingNotInCheckAfterMoveValidator";
            var          board         = fenTextToBoard.Translate("4k3/8/8/8/8/8/8/4K3 w - - 0 1");
            var          postMoveBoard = fenTextToBoard.Translate("3k4/8/8/8/8/8/8/3K4 w - - 0 1");
            var          move          = MoveHelpers.GenerateMove("e2".ToBoardIndex(), "e4".ToBoardIndex());

            yield return
                (new TestCaseData(board, postMoveBoard, move, true)
                 .SetName(pseudoTestCaseName + " - In Check")
                 .SetDescription("Proposed move leaves King in check.")
                 .Returns(MoveError.MoveLeavesKingInCheck));

            yield return
                (new TestCaseData(board, postMoveBoard, move, false)
                 .SetName(pseudoTestCaseName + " - Not In Check")
                 .SetDescription("Proposed move does not leave King in check.")
                 .Returns(MoveError.NoneSet));
        }
        public static IEnumerable <TestCaseData> GetValidDestinationTestCases(Color activeColor)
        {
            var board         = (Board)(activeColor == Color.Black ? BlackCastlingBoard.Clone() : WhiteCastlingBoard.Clone());
            var castlingMoves = activeColor == Color.Black
                ? MoveHelpers.BlackCastlingMoves
                : MoveHelpers.WhiteCastlingMoves;
            var opponentCastlingMoves = activeColor == Color.Black
                ? MoveHelpers.WhiteCastlingMoves
                : MoveHelpers.BlackCastlingMoves;

            foreach (var castlingMove in castlingMoves)
            {
                var castlingSan = castlingMove.GetCastlingSan();
                var testName    =
                    $"{name} - {activeColor} {castlingSan} destination {castlingMove.DestinationIndex.ToSquareString()} (Valid)";
                yield return(new TestCaseData(board, castlingMove)
                             .SetName(testName)
                             .Returns(MoveError.NoneSet));
            }

            foreach (var castlingMove in opponentCastlingMoves)
            {
                var castlingSan = castlingMove.GetCastlingSan();
                var testName    =
                    $"{name} - {activeColor} {castlingSan} destination {castlingMove.DestinationIndex.ToSquareString()} (Invalid)";
                yield return(new TestCaseData(board, castlingMove)
                             .SetName(testName)
                             .Returns(MoveError.CastleBadDestinationSquare));
            }

            var nonCastlingMoveWhiteSide = MoveHelpers.GenerateMove("e2".ToBoardIndex(), "e4".ToBoardIndex(), MoveType.Castle);
            var nonCastlingMoveBlackSide = MoveHelpers.GenerateMove("e7".ToBoardIndex(), "e5".ToBoardIndex(), MoveType.Castle);
            var nonCastlingMoves         = new[] { nonCastlingMoveBlackSide, nonCastlingMoveWhiteSide };

            foreach (var nonCastlingMove in nonCastlingMoves)
            {
                yield return(new TestCaseData(board, nonCastlingMove)
                             .SetName(
                                 $"{name} - {activeColor} [non-castling move] destination {nonCastlingMove.DestinationIndex.ToSquareString()} (Invalid)")
                             .Returns(MoveError.CastleBadDestinationSquare));
            }
        }
Esempio n. 20
0
        /// <summary>
        ///     Gets a basic move with no SAN and no en passant information
        /// </summary>
        /// <param name="lan"></param>
        /// <returns></returns>
        public static Move BasicMoveFromLAN(string lan)
        {
            var length = lan.Length;

            if (length < 4 || length > 5)
            {
                throw new MoveException($"LAN move {lan} has invalid length.");
            }

            var sourceString   = lan.Substring(0, 2);
            var destString     = lan.Substring(2, 2);
            var source         = sourceString.ToBoardIndex();
            var dest           = destString.ToBoardIndex();
            var promotionChar  = lan.Length == 5 ? lan[4] : (char?)null;
            var promotionPiece = PieceHelpers.GetPromotionPieceFromChar(promotionChar);
            var isPromotion    = length == 5;

            return(MoveHelpers.GenerateMove(source, dest,
                                            isPromotion ? MoveType.Promotion : MoveType.Normal, promotionPiece));
        }
        private static IEnumerable <TestCaseData> GetEnPassantTestCases(string name)
        {
            const string enPassantAvailableFen             = "rnbqkbnr/1p1ppppp/8/p1pP4/8/8/PPP1PPPP/RNBQKBNR w KQkq c6 0 3";
            var          pawnAttackingEnPassantSquareBoard = fenTextToBoard.Translate(enPassantAvailableFen);

            var enPassantCapture = MoveHelpers.GenerateMove(d5, c6, MoveType.EnPassant);

            var occupancy = PseudoLegalMovesIncludingDestinationSquare;

            yield return(new TestCaseData(pawnAttackingEnPassantSquareBoard, enPassantCapture,
                                          occupancy)
                         .SetName($"{name} - Pawn attacks en passant square")
                         .Returns(MoveError.NoneSet));


            yield return(new TestCaseData(pawnAttackingEnPassantSquareBoard, pseudoLegalMove,
                                          occupancy)
                         .SetName($"{name} - Pawn attacks en passant square but move isn't marked correctly")
                         .Returns(MoveError.EnPassantNotMarked));
        }
Esempio n. 22
0
        protected static IEnumerable <TestCase <ushort?, Board> > GetEnPassantIndexTestCases()
        {
            yield return(new TestCase <ushort?, Board>(20, new Board(), "After 1. e4", MoveHelpers.GenerateMove(12, 28)));

            yield return(new TestCase <ushort?, Board>(44,
                                                       FenReader.Translate("rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1"), "After 1. e4 e5",
                                                       MoveHelpers.GenerateMove(52, 36)));

            yield return(new TestCase <ushort?, Board>(null,
                                                       FenReader.Translate("rnbqkbnr/pppppppp/8/8/8/8/PPPPRPPP/RNBQKBNR b KQkq - 0 1"), "After 1. Re4 from e3",
                                                       MoveHelpers.GenerateMove(12, 28)));

            yield return(new TestCase <ushort?, Board>(null, new Board(), "No piece on square",
                                                       MoveHelpers.GenerateMove(28, 29)));

            yield return(new TestCase <ushort?, Board>(null, new Board(), "After 1. e3",
                                                       MoveHelpers.GenerateMove(12, 20)));

            yield return(new TestCase <ushort?, Board>(null,
                                                       FenReader.Translate("rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1"), "After 1.e4 e6",
                                                       MoveHelpers.GenerateMove(52, 44)));
        }
Esempio n. 23
0
        private List <Individual> EvolveOnce()
        {
            var newPopulation = new ConcurrentBag <Individual>();

            Parallel.For(0, population.Count / 2, _ =>
                         //for (var i = 0; i < population.Count / 2; i++)
            {
                var father = GetWeightedChoice();
                var mother = GetWeightedChoice();

                var split   = Rand.Next(Dna.Length);
                var brother = new Dna(father.Take(split).Concat(mother.Skip(split))
                                      .Select(x => Rand.NextDouble() < 0.001 ? MoveHelpers.GetRandomMove() : x)
                                      .ToArray());
                var sister = new Dna(mother.Take(split).Concat(father.Skip(split))
                                     .Select(x => Rand.NextDouble() < 0.001 ? MoveHelpers.GetRandomMove() : x)
                                     .ToArray());
                newPopulation.Add(new Individual(brother, fitnessFunc(brother)));
                newPopulation.Add(new Individual(sister, fitnessFunc(sister)));
            });
            return(newPopulation.ToList());
        }
        private static IEnumerable <TestCaseData> GetFriendlyPieceOccupyingDestinationTestCases()
        {
            const string name = "Destination Occupation";
            const string whiteOccupiesDestination = "rnbqkbnr/ppp2ppp/8/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq e6 0 3";
            const string blackOccupiesDestination = "r1bqk1nr/pppp1ppp/2n5/3Np3/1bP5/P7/1P1PPPPP/R1BQKBNR b KQkq - 0 4";
            var          boardWhite = fenTextToBoard.Translate(whiteOccupiesDestination);
            var          boardBlack = fenTextToBoard.Translate(blackOccupiesDestination);
            var          d4         = "d4".ToBoardIndex();
            var          b4         = "b4".ToBoardIndex();
            var          whiteMove  = MoveHelpers.GenerateMove("e3".ToBoardIndex(), d4);
            var          blackMove  = MoveHelpers.GenerateMove("c6".ToBoardIndex(), b4);

            yield return(new TestCaseData(boardWhite, whiteMove, d4.GetBoardValueOfIndex())
                         .SetName($"{name} - Active color occupies destination")
                         .SetDescription("Check that active color does not occupy destination(White, Pe3 x Pe4)")
                         .Returns(MoveError.ActiveColorPieceAtDestination));

            yield return(new TestCaseData(boardBlack, blackMove, b4.GetBoardValueOfIndex())
                         .SetName($"{name} - Active color occupies destination (Black, Nb6 x Bb4")
                         .SetDescription("Check that active color does not occupy destination")
                         .Returns(MoveError.ActiveColorPieceAtDestination));
        }
Esempio n. 25
0
        private Move ReturnMoveBeater(Move moveToBeat, bool botHasDynamitesAvailable, bool playerHasDynamitesAvailable)
        {
            var moveHelpers = new MoveHelpers();
            //this selects all the moves that beat the hand
            var availableMoves = moveHelpers.GetBeaters(moveToBeat);

            //if bot knows that player run out of dynamites, no point playing waterbomb
            if (availableMoves.Contains(Move.Waterbomb) && playerHasDynamitesAvailable == false)
            {
                return(GetRandomMoveFromSet(botHasDynamitesAvailable, playerHasDynamitesAvailable));
            }
            //if bot does not have any dynamites left, cant play it
            else if (availableMoves.Contains(Move.Dynamite) && botHasDynamitesAvailable == false)
            {
                return(availableMoves.Where(x => x != Move.Dynamite).FirstOrDefault());
            }
            //if more than one moves available, select one at random
            else
            {
                int index = new Random().Next(availableMoves.Count());
                return(availableMoves.ElementAt(index));
            }
        }
Esempio n. 26
0
        public Move GetMoveFromSAN(Board board, string sanMove)
        {
            Move moveExt;
            var  strMove = StripNonMoveInfoFromMove(sanMove);

            if (strMove.Length < 2)
            {
                throw new MoveException("Invalid move. Must have at least 2 characters.");
            }

            var colorMoving = board.ActivePlayer;

            if (char.IsLower(strMove[0]))
            {
                moveExt = GetPawnMoveDetails(board, strMove);
            }
            else if (strMove == CastleKingSide || strMove == CastleQueenSide)
            {
                if (colorMoving == Color.White)
                {
                    return(strMove == CastleKingSide
                        ? MoveHelpers.WhiteCastleKingSide
                        : MoveHelpers.WhiteCastleQueenSide);
                }

                return(strMove == CastleKingSide ? MoveHelpers.BlackCastleKingSide : MoveHelpers.BlackCastleQueenSide);
            }
            else
            {
                var pieceMoving            = PieceHelpers.GetPiece(strMove[0]);
                var destinationSquare      = strMove.Substring(strMove.Length - 2, 2).ToBoardIndex();
                var applicableBlockerBoard = board.Occupancy.Occupancy(colorMoving, pieceMoving);
                var squaresAttackingTarget =
                    Bitboard.Instance.PiecesAttackingSquareByColor(board.Occupancy, destinationSquare, colorMoving);
                var activePieces = squaresAttackingTarget & applicableBlockerBoard;
                if (activePieces == 0)
                {
                    throw new MoveException(
                              $"No pieces on any squares are attacking the square {destinationSquare.ToSquareString()}",
                              board);
                }


                var attackerIndices = activePieces.GetSetBits();


                if (attackerIndices.Length == 0)
                {
                    throw new MoveException(
                              $"Error with move {sanMove}:No pieces of type {pieceMoving.ToString()} are attacking the square {destinationSquare.ToSquareString()}",
                              board);
                }

                if (attackerIndices.Length == 1)
                {
                    moveExt = MoveHelpers.GenerateMove(attackerIndices[0], destinationSquare);
                }
                else
                {
                    moveExt = DetermineWhichPieceMovesToSquare(board, strMove, attackerIndices,
                                                               applicableBlockerBoard,
                                                               destinationSquare);
                }
            }

            if (moveExt == null)
            {
                throw new NoNullAllowedException(
                          $"MoveTranslatorService: Move should not be null after translation. Error in PGN or application for move {sanMove}.");
            }

            return(moveExt);
        }
Esempio n. 27
0
        public static IEnumerable GetPseudoLegalMoveTestCases()
        {
            ushort whiteKingIndex = 4;
            ushort blackKingIndex = 60;

            var board       = FenReader.Translate("r1bqk2r/ppp1bppp/2np1n2/4p3/2P5/2N2NP1/PP1PPPBP/R1BQK2R w KQkq - 2 6");
            var kf1         = MoveHelpers.GenerateMove("e1".ToBoardIndex(), "f1".ToBoardIndex());
            var castleShort = MoveHelpers.WhiteCastleKingSide;
            var desc        = "White should have Kf1 and O-O";
            var name        = "Legal Moves - White King (O-O)";

            yield return(new TestCaseData(board, new[] { kf1, castleShort }, whiteKingIndex)
                         .SetName(name)
                         .SetDescription(desc));

            board = FenReader.Translate("r1bqk2r/ppp1bppp/3p4/8/2Ppn3/2NP2P1/PPQBPP1P/R3KB1R w KQkq - 2 9");
            var kd1        = MoveHelpers.GenerateMove("e1".ToBoardIndex(), "d1".ToBoardIndex());
            var castleLong = MoveHelpers.WhiteCastleQueenSide;

            desc = "White should have Kd1 and O-O-O";
            name = "Legal Moves - White King (O-O-O)";
            yield return(new TestCaseData(board, new[] { kd1, castleLong }, whiteKingIndex).SetName(name)
                         .SetDescription(desc));


            board = FenReader.Translate("r1bqk2r/ppp1bppp/3p4/8/2Ppn3/2NP2P1/PPQBPP1P/R3KB1R b KQkq - 2 9");
            var kf8 = MoveHelpers.GenerateMove("e8".ToBoardIndex(), "f8".ToBoardIndex());

            castleShort = MoveHelpers.BlackCastleKingSide;
            desc        = "Black should have Kf8 and O-O";
            name        = "Legal Moves - Black King (O-O)";
            yield return(new TestCaseData(board, new[] { kf8, castleShort }, blackKingIndex)
                         .SetName(name)
                         .SetDescription(desc));

            board = FenReader.Translate("r3kb1r/pppqpppp/3pb3/3N4/2P1P3/6P1/PPQBPP1P/R3KB1R b KQkq - 0 11");
            var kd8 = MoveHelpers.GenerateMove("e8".ToBoardIndex(), "d8".ToBoardIndex());

            castleLong = MoveHelpers.BlackCastleQueenSide;
            desc       = "Black should have Kd8 and O-O-O";
            name       = "Legal Moves - Black King (O-O-O)";
            yield return(new TestCaseData(board, new[] { kd8, castleLong }, blackKingIndex).SetName(name)
                         .SetDescription(desc));

            board = FenReader.Translate("2kr1b1r/pppqpppp/3pb3/3N4/2P1P3/6P1/PPQBPP1P/R3KB1R w KQ - 1 12");
            desc  = "No moves should be returned if source square is unoccupied";
            name  = "Legal Moves - [null]";
            yield return(new TestCaseData(board, Array.Empty <Move>(), (ushort)34)
                         .SetDescription(desc)
                         .SetName(name));

            board = FenReader.Translate("rnbqkbnr/ppp2ppp/8/2Ppp3/8/8/PP1PPPPP/RNBQKBNR w KQkq d6 0 3");
            desc  = "En Passant available on d6";
            name  = "Legal Moves - White En Passant";
            var normalMove = MoveHelpers.GenerateMove("c5".ToBoardIndex(), "c6".ToBoardIndex());
            var epMove     =
                MoveHelpers.GenerateMove("c5".ToBoardIndex(), "d6".ToBoardIndex(), MoveType.EnPassant);

            yield return(new TestCaseData(board, new[] { epMove, normalMove }, "c5".ToBoardIndex())
                         .SetDescription(desc)
                         .SetName(name));
        }
Esempio n. 28
0
        private void MakeMove()
        {
            var neighourhood = new Neighbourhood(board[x, y + 1], board[x, y - 1], board[x + 1, y], board[x - 1, y], board[x, y]);

            void MakeMove(Move move)
            {
                switch (move)
                {
                case Move.North:
                    if (neighourhood.North == Cell.Wall)
                    {
                        score -= 5;
                    }
                    else
                    {
                        y += 1;
                    }
                    return;

                case Move.East:
                    if (neighourhood.East == Cell.Wall)
                    {
                        score -= 5;
                    }
                    else
                    {
                        x += 1;
                    }
                    return;

                case Move.South:
                    if (neighourhood.South == Cell.Wall)
                    {
                        score -= 5;
                    }
                    else
                    {
                        y -= 1;
                    }
                    return;

                case Move.West:
                    if (neighourhood.West == Cell.Wall)
                    {
                        score -= 5;
                    }
                    else
                    {
                        x -= 1;
                    }
                    return;

                case Move.Pickup:
                    if (neighourhood.Current == Cell.Can)
                    {
                        score += 10;
                    }
                    else
                    {
                        score -= 1;
                    }
                    board[x, y] = Cell.Empty;
                    return;

                case Move.Stay:
                    return;

                case Move.Random:
                    MakeMove(MoveHelpers.GetRandomDirection());
                    return;

                default:
                    throw new ArgumentOutOfRangeException(nameof(move), move, null);
                }
            }

            MakeMove(cleaner.Move(neighourhood));
        }
Esempio n. 29
0
        protected static IEnumerable <TestCase <CastlingAvailability, Board> > GetCastlingAvailabilityPostMoveTestCases()
        {
            var allCastlingAvailable = FenReader.Translate("r3k2r/ppp5/8/8/8/8/PPP5/R3K2R w KQkq - 0 1");
            var knightsOnAFile       = FenReader.Translate("n3k2r/8/8/8/8/8/PPP5/N3K2R w Kk - 0 1");
            var knightsOnHFile       = FenReader.Translate("r3k2n/8/8/8/8/8/PPP5/R3K2N w Qq - 0 1");
            var bishopsOnAFile       = FenReader.Translate("b3k2r/8/8/8/8/1P6/P1P5/B3K2R w Kk - 0 1");
            var bishopsOnHFile       = FenReader.Translate("r3k2b/8/8/8/8/1P6/P1P5/R3K2B w Qq - 0 1");
            var queensOnAFile        = FenReader.Translate("q3k2r/8/8/8/8/8/PPP5/Q3K2R w Kk - 0 1");
            var queensOnHFile        = FenReader.Translate("r3k2q/8/8/8/8/8/PPP5/R3K2Q w Qq - 0 1");

            //
            // No Change in Castling Availability
            //No Piece on Square
            yield return(new TestCase <CastlingAvailability, Board>(allCastlingAvailable.CastlingAvailability,
                                                                    allCastlingAvailable, "No Piece on Source- Castling not affected", MoveHelpers.GenerateMove(16, 24)));

            //White Pawn
            yield return(new TestCase <CastlingAvailability, Board>(allCastlingAvailable.CastlingAvailability,
                                                                    allCastlingAvailable, "White Pawn Move- Castling not affected", MoveHelpers.GenerateMove(8, 24)));

            //Black Pawn
            yield return(new TestCase <CastlingAvailability, Board>(allCastlingAvailable.CastlingAvailability,
                                                                    allCastlingAvailable, "White Pawn Move- Castling not affected", MoveHelpers.GenerateMove(48, 32)));

            //White Knight from a1 -> b3
            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.WhiteKingside | CastlingAvailability.BlackKingside,
                             knightsOnAFile,
                             "White Knight from a1 -> b3- Castling not affected", MoveHelpers.GenerateMove(0, 17)));

            //White Knight from h1 -> g3
            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.WhiteQueenside | CastlingAvailability.BlackQueenside,
                             knightsOnHFile,
                             "White Knight from h1 -> g3- Castling not affected", MoveHelpers.GenerateMove(7, 22)));

            //Black Knight from a8 -> b6
            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.WhiteKingside | CastlingAvailability.BlackKingside,
                             knightsOnAFile,
                             "Black Knight from a8 -> b6- Castling not affected", MoveHelpers.GenerateMove(56, 41)));

            //Black Knight from h8 ->g6
            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.WhiteQueenside | CastlingAvailability.BlackQueenside,
                             knightsOnHFile,
                             "Black Knight from h8 ->g6- Castling not affected", MoveHelpers.GenerateMove(63, 46)));

            //White Bishop from a1 -> c3
            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.WhiteKingside | CastlingAvailability.BlackKingside,
                             bishopsOnAFile,
                             "White Bishop from a1 -> c3- Castling not affected", MoveHelpers.GenerateMove(0, 18)));

            //White Bishop from h1 -> f3
            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.WhiteQueenside | CastlingAvailability.BlackQueenside,
                             bishopsOnHFile,
                             "White Bishop from h1 -> f3- Castling not affected", MoveHelpers.GenerateMove(7, 21)));

            //Black Bishop from a8 -> c6
            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.WhiteKingside | CastlingAvailability.BlackKingside,
                             bishopsOnAFile,
                             "Black Bishop from a8 -> b6- Castling not affected", MoveHelpers.GenerateMove(56, 42)));

            //Black Bishop from h8 ->f6
            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.WhiteQueenside | CastlingAvailability.BlackQueenside,
                             bishopsOnHFile,
                             "Black Bishop from h8 -> f6- Castling not affected", MoveHelpers.GenerateMove(63, 45)));


            //White Queen from a1 -> c3
            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.WhiteKingside | CastlingAvailability.BlackKingside,
                             queensOnAFile,
                             "White Queen from a1 -> c3- Castling not affected", MoveHelpers.GenerateMove(0, 18)));

            //White Queen from h1 -> f3
            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.WhiteQueenside | CastlingAvailability.BlackQueenside,
                             queensOnHFile,
                             "White Queen from h1 -> f3- Castling not affected", MoveHelpers.GenerateMove(7, 21)));

            //Black Queen from a8 -> c6
            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.WhiteKingside | CastlingAvailability.BlackKingside,
                             queensOnAFile,
                             "Black Queen from a8 -> b6- Castling not affected", MoveHelpers.GenerateMove(56, 42)));

            //Black Queen from h8 ->f6
            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.WhiteQueenside | CastlingAvailability.BlackQueenside,
                             queensOnHFile,
                             "Black Queen from h8 -> f6- Castling not affected", MoveHelpers.GenerateMove(63, 45)));

            //Rook Moves
            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.BlackKingside | CastlingAvailability.BlackQueenside |
                             CastlingAvailability.WhiteKingside,
                             allCastlingAvailable, "White Rook Move- Queenside eliminated", MoveHelpers.GenerateMove(0, 2)));

            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.BlackKingside | CastlingAvailability.BlackQueenside |
                             CastlingAvailability.WhiteQueenside,
                             allCastlingAvailable, "White Rook Move- Kingside eliminated", MoveHelpers.GenerateMove(7, 6)));

            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.BlackKingside | CastlingAvailability.WhiteKingside |
                             CastlingAvailability.WhiteQueenside,
                             allCastlingAvailable, "Black Rook Move- Queenside eliminated", MoveHelpers.GenerateMove(56, 57)));

            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.BlackQueenside | CastlingAvailability.WhiteKingside |
                             CastlingAvailability.WhiteQueenside,
                             allCastlingAvailable, "Black Rook Move- Kingside eliminated", MoveHelpers.GenerateMove(63, 62)));

            //Castling Moves
            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.BlackKingside | CastlingAvailability.BlackQueenside, allCastlingAvailable,
                             "White Castles Kingside - White Castling Eliminated",
                             MoveHelpers.WhiteCastleKingSide));

            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.BlackKingside | CastlingAvailability.BlackQueenside, allCastlingAvailable,
                             "White Castles Queenside - White Castling Eliminated",
                             MoveHelpers.WhiteCastleQueenSide));

            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.WhiteKingside | CastlingAvailability.WhiteQueenside, allCastlingAvailable,
                             "Black Castles Kingside - White Castling Eliminated",
                             MoveHelpers.BlackCastleKingSide));

            yield return(new TestCase <CastlingAvailability, Board>(
                             CastlingAvailability.WhiteKingside | CastlingAvailability.WhiteQueenside, allCastlingAvailable,
                             "Black Castles Queenside - White Castling Eliminated",
                             MoveHelpers.BlackCastleQueenSide));

            //Odd circumstances
            var blackRookOnA1 = FenReader.Translate("r3k2r/ppp5/8/8/8/8/PPP5/r1B1K2R w Kkq - 0 1");
            var whiteRookOnA8 = FenReader.Translate("R1b1k2r/ppp5/8/8/8/8/PPP5/RN2K2R w KQk - 0 1");

            yield return(new TestCase <CastlingAvailability, Board>(blackRookOnA1.CastlingAvailability, blackRookOnA1,
                                                                    "Black Rook on a1- No Change", MoveHelpers.GenerateMove(0, 1)));

            yield return(new TestCase <CastlingAvailability, Board>(whiteRookOnA8.CastlingAvailability, whiteRookOnA8,
                                                                    "White Rook on a8- No Change", MoveHelpers.GenerateMove(56, 57)));
        }