예제 #1
0
        static IEnumerable <Move> GetCastlingMoves(Checkerboard checkerboard, Pawn king)
        {
            if (checkerboard.AllMoves.Any(move => move.Pawn == king) || checkerboard.CheckIfCheck(checkerboard.CurrentColorToMove))
            {
                yield break;
            }

            var rookH = checkerboard.GetPawns(king.PawnColor).FirstOrDefault(p => p.PawnType == PawnType.Rook && p.Position.Letter == 7);

            if (rookH != null &&
                !checkerboard.AllMoves.Any(m => m.Pawn == rookH) &&
                GetPositionsInBetween(king.PawnColor, false).Any(pos => checkerboard.GetPawn(pos.Letter, pos.Digit) == null) &&
                !checkerboard.GetPawns(king.PawnColor.Opposite())
                .Any(p => p.GetAvailableMoves(checkerboard)
                     .Any(m => (m.NewPawnPos.Digit == rookH.Position.Digit - 1 && m.NewPawnPos.Letter == rookH.Position.Letter) ||
                          (m.NewPawnPos.Digit == rookH.Position.Digit - 2 && m.NewPawnPos.Letter == rookH.Position.Letter))))
            {
                yield return(checkerboard.GetCastlingMove(king, new Position(6, king.PawnColor == PawnColor.White ? 1 : 8), rookH, new Position(5, king.PawnColor == PawnColor.White ? 1 : 8)));
            }

            var rookA = checkerboard.GetPawns(king.PawnColor).FirstOrDefault(p => p.PawnType == PawnType.Rook && p.Position.Letter == 0);

            if (rookA != null &&
                !checkerboard.AllMoves.Any(m => m.Pawn == rookA) &&
                GetPositionsInBetween(king.PawnColor, true).Any(pos => checkerboard.GetPawn(pos.Letter, pos.Digit) == null) &&
                !checkerboard.GetPawns(king.PawnColor.Opposite())
                .Any(p => p.GetAvailableMoves(checkerboard)
                     .Any(m => m.NewPawnPos.Digit == rookH.Position.Digit + 1 && m.NewPawnPos.Letter == rookH.Position.Letter ||
                          (m.NewPawnPos.Digit == rookH.Position.Digit + 2 && m.NewPawnPos.Letter == rookH.Position.Letter) ||
                          (m.NewPawnPos.Digit == rookH.Position.Digit + 3 && m.NewPawnPos.Letter == rookH.Position.Letter))))
            {
                yield return(checkerboard.GetCastlingMove(king, new Position(2, king.PawnColor == PawnColor.White ? 1 : 8), rookH, new Position(4, king.PawnColor == PawnColor.White ? 1 : 8)));
            }

            IEnumerable <Position> GetPositionsInBetween(PawnColor pawnColor, bool smallCastle)
            {
                if (pawnColor == PawnColor.White && smallCastle)
                {
                    yield return(new Position(5, 1));

                    yield return(new Position(6, 1));
                }
                else if (pawnColor == PawnColor.White)
                {
                    yield return(new Position(1, 1));

                    yield return(new Position(2, 1));

                    yield return(new Position(3, 1));
                }
                else if (smallCastle)
                {
                    yield return(new Position(5, 8));

                    yield return(new Position(6, 8));
                }
                else
                {
                    yield return(new Position(1, 8));

                    yield return(new Position(2, 8));

                    yield return(new Position(3, 8));
                }
            }
        }