// Used more specifically to enforce board logic
        public bool DoesMoveLeaveUsInCheck(IBoardState <ChessPieceEntity> boardState, BoardMove move)
        {
            var attackingPlayer = boardState.GetItem(move.From).Item.Player;

            var clone = (IBoardState <ChessPieceEntity>)boardState.Clone();

            _moveService.Move(clone, move);

            var king = clone.GetItems((int)attackingPlayer, (int)ChessPieceName.King).Single();

            return(_playerStateService.IsLocationUnderCheck(clone, king.Location, king.Item.Player).result);
        }
Example #2
0
        private PlayerState CheckForCheckMate(IBoardState <ChessPieceEntity> boardState,
                                              LocatedItem <ChessPieceEntity> king, LocatedItem <ChessPieceEntity> attacker)
        {
            var state = PlayerState.Check;

            var clone = (IBoardState <ChessPieceEntity>)boardState.Clone();

            // Find the attacking piece
            // Not sure why we need to refresh its piece paths here but I get problems with out it
            RefreshPiecePaths(clone, attacker);

            // find the path it's attacking on
            var attackPath = attacker.Paths.FirstOrDefault(p => p.ContainsTo(king.Location));

            // Remove the king from the board so as to not have it's location block
            // attack paths from the new location
            clone.Remove(king.Location);
            var kingCannotMove = !king.Paths.Any() || king.Paths.FlattenMoves()
                                 .ToList()
                                 .All(m
                                      => IsLocationUnderCheck(clone, m.To, king.Item.Player).result);

            //
            // get all friendly pieces except king
            // refresh there paths
            var friendlyPieces = clone.GetItems(king.Item.Owner)
                                 .Where(p => p.Item.Piece != ChessPieceName.King)
                                 .OrderBy(p => p.Item.EntityType);

            // check if any friendly paths intersect the attackPath or attack the attacker
            var canBlock = friendlyPieces.Where(fp
                                                => fp.Paths.FlattenMoves()
                                                .Any(fm => attackPath
                                                     .Any(am => am.To.Equals(fm.To) || am.From.Equals(fm.To)
                                                          )
                                                     )
                                                );

            if (kingCannotMove && !canBlock.Any())
            {
                return(PlayerState.Checkmate);
            }

            return(PlayerState.Check);
        }
        // Typically only used to produce correct san notation on output
        public bool DoesMoveCauseCheck(IBoardState <ChessPieceEntity> boardState, BoardMove move)
        {
            // TODO: Would it be quicker to
            var attackingPlayer = boardState.GetItem(move.From).Item.Player;

            var defender = boardState.GetItem(move.To);

            if (defender != null && defender.Item.Is(attackingPlayer.Enemy(), ChessPieceName.King))
            {
                return(true);
            }

            var clone = (IBoardState <ChessPieceEntity>)boardState.Clone();

            _moveService.Move(clone, move);

            var king = clone.GetItems((int)attackingPlayer.Enemy(), (int)ChessPieceName.King).Single();

            return(_playerStateService.IsLocationUnderCheck(clone, king.Location, king.Item.Player).result);
        }