public static bool CanNotReach(this Figure figure, Pos cell, IList <Figure> board)
 {
     return(!CanReach(figure, cell, board));
 }
 public static bool IsOnBoard(this Pos cell)
 {
     return(0 <= cell.X && cell.X <= 7 && 0 <= cell.Y && cell.Y <= 7);
 }
        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);
        }