public static bool CanBeBlocked(this Figure enemy, Figure theKing, IList <Figure> figures)
        {
            var directHitters = new[] { FigureType.Knight, FigureType.Pawn };

            if (directHitters.Contains(enemy.Type))
            {
                return(false);
            }

            var moveX = Math.Sign(theKing.Cell.X - enemy.Cell.X);
            var moveY = Math.Sign(theKing.Cell.Y - enemy.Cell.Y);

            var nextPos    = new Pos(enemy.Cell.Y + moveY, enemy.Cell.X + moveX);
            var kingAllies = figures.Where(f => f.IsAllyOf(theKing)).ToArray();

            while (!nextPos.Equals(theKing.Cell))
            {
                if (kingAllies.Any(a => a.CanReach(nextPos, figures)))
                {
                    return(true);
                }

                nextPos = new Pos(nextPos.Y + moveY, nextPos.X + moveX);
            }

            return(false);
        }
        public static bool CanHit(this Figure figure, Pos cell, IList <Figure> board)
        {
            if (figure.Type == FigureType.Pawn)
            {
                var enemyInCell = board.SingleOrDefault(f => f.Cell.Equals(cell));
                if (enemyInCell != null &&
                    enemyInCell.Type == FigureType.Pawn &&
                    enemyInCell.PrevCell != null &&
                    enemyInCell.PrevCell.Value.Y - cell.Y == 2 &&
                    Math.Abs(cell.X - figure.Cell.X) == 1)
                {
                    return(true);
                }

                if (figure.Owner == 1) // if the figure is black
                {
                    return(figure.Cell.Equals(new Pos(cell.Y - 1, cell.X - 1)) ||
                           figure.Cell.Equals(new Pos(cell.Y - 1, cell.X + 1)));
                }
                else // if the figure is white
                {
                    return(figure.Cell.Equals(new Pos(cell.Y + 1, cell.X - 1)) ||
                           figure.Cell.Equals(new Pos(cell.Y + 1, cell.X + 1)));
                }
            }

            if (figure.Type == FigureType.King)
            {
                var hitPositions = new[]
                {
                    new Pos(cell.Y + 1, cell.X + 1),
                    new Pos(cell.Y + 1, cell.X),
                    new Pos(cell.Y + 1, cell.X - 1),
                    new Pos(cell.Y - 1, cell.X + 1),
                    new Pos(cell.Y - 1, cell.X),
                    new Pos(cell.Y - 1, cell.X - 1),
                    new Pos(cell.Y, cell.X + 1),
                    new Pos(cell.Y, cell.X - 1)
                };

                return(hitPositions.Any(x => figure.Cell.Equals(x)));
            }

            if (figure.Type == FigureType.Knight)
            {
                var hitPositions = new[]
                {
                    new Pos(cell.Y - 2, cell.X + 1),
                    new Pos(cell.Y - 2, cell.X - 1),
                    new Pos(cell.Y + 2, cell.X + 1),
                    new Pos(cell.Y + 2, cell.X - 1),
                    new Pos(cell.Y + 1, cell.X - 2),
                    new Pos(cell.Y - 1, cell.X - 2),
                    new Pos(cell.Y + 1, cell.X + 2),
                    new Pos(cell.Y - 1, cell.X + 2),
                };

                return(hitPositions.Any(x => figure.Cell.Equals(x)));
            }

            var occupied = board.Select(x => x.Cell).ToArray();

            if (figure.Type == FigureType.Bishop)
            {
                if (figure.Cell.Y == figure.Cell.X - (cell.X - cell.Y) ||
                    figure.Cell.Y + figure.Cell.X == cell.X + cell.Y)
                {
                    var moveX = Math.Sign(cell.X - figure.Cell.X);
                    var moveY = Math.Sign(cell.Y - figure.Cell.Y);

                    var nextPos = new Pos(figure.Cell.Y + moveY, figure.Cell.X + moveX);
                    while (!nextPos.Equals(cell))
                    {
                        if (occupied.Contains(nextPos))
                        {
                            return(false);
                        }
                        nextPos = new Pos(nextPos.Y + moveY, nextPos.X + moveX);
                    }

                    return(true);
                }

                return(false);
            }

            if (figure.Type == FigureType.Rook)
            {
                if (figure.Cell.X == cell.X || figure.Cell.Y == cell.Y)
                {
                    var moveX = Math.Sign(cell.X - figure.Cell.X);
                    var moveY = Math.Sign(cell.Y - figure.Cell.Y);

                    var nextPos = new Pos(figure.Cell.Y + moveY, figure.Cell.X + moveX);
                    while (!nextPos.Equals(cell))
                    {
                        if (occupied.Contains(nextPos))
                        {
                            return(false);
                        }
                        nextPos = new Pos(nextPos.Y + moveY, nextPos.X + moveX);
                    }

                    return(true);
                }

                return(false);
            }

            if (figure.Type == FigureType.Queen)
            {
                if (figure.Cell.X == cell.X ||
                    figure.Cell.Y == cell.Y ||
                    figure.Cell.Y == figure.Cell.X - (cell.X - cell.Y) ||
                    figure.Cell.Y + figure.Cell.X == cell.X + cell.Y)
                {
                    var moveX = Math.Sign(cell.X - figure.Cell.X);
                    var moveY = Math.Sign(cell.Y - figure.Cell.Y);

                    var nextPos = new Pos(figure.Cell.Y + moveY, figure.Cell.X + moveX);
                    while (!nextPos.Equals(cell))
                    {
                        if (occupied.Contains(nextPos))
                        {
                            return(false);
                        }
                        nextPos = new Pos(nextPos.Y + moveY, nextPos.X + moveX);
                    }

                    return(true);
                }

                return(false);
            }

            return(true);
        }