------------------------------------------------------------------------------
-- | knight, bishop, rook, queen simple checks - not discovered check
simpleChecks :: Board -> [ Move ]
simpleChecks b = do
  pt <- [ Queen, Rook, Bishop, Knight ]

  let kingMoves  = moveFun b pt (eKingPos b) .&. complement (myPieces b)
  f <- toList $ piecesOf b (b^.next) pt
  let pieceMoves = moveFun b pt f
      common = kingMoves .&. pieceMoves

  -- common should be mempty most of the time, so we should
  -- short circuit the calcualtion from this point
  t <- toList common
  guard $ moveValid pt f t
  return
    $ (capturedPiece .~ pieceAt b t)
    $ defaultMove f t pt (b^.next)

  where
    moveValid Knight f t = let hd = hDist f t
                               vd = vDist f t
                           in (hd == 1 && vd == 2) || (hd == 2 && vd == 1)
    moveValid Bishop f t = hDist f t == vDist f t
    moveValid Rook   f t = hDist f t == 0 || vDist f t == 0
    moveValid Queen  f t = moveValid Rook f t || moveValid Bishop f t
    moveValid _      _ _ = error "unexpected piece type"


------------------------------------------------------------------------------
-- | discovered checks (with any piece type except pawns)
simpleChecks :: Board -> [ Move ]
simpleChecks b = do
  pt <- [ Queen, Rook, Bishop, Knight ]

  let kingMoves  = moveFun b pt (eKingPos b) .&. complement (myPieces b)
  f <- toList $ piecesOf b (b^.next) pt
  let pieceMoves = moveFun b pt f
      common = kingMoves .&. pieceMoves

  -- common should be mempty most of the time, so we should
  -- short circuit the calcualtion from this point
  t <- toList common
  guard $ moveValid pt f t
  return
    $ (capturedPiece .~ pieceAt b t)
    $ defaultMove f t pt (b^.next)

  where
    moveValid Knight f t = let hd = hDist f t
                               vd = vDist f t
                           in (hd == 1 && vd == 2) || (hd == 2 && vd == 1)
    moveValid Bishop f t = hDist f t == vDist f t
    moveValid Rook   f t = hDist f t == 0 || vDist f t == 0
    moveValid Queen  f t = moveValid Rook f t || moveValid Bishop f t
    moveValid _      _ _ = error "unexpected piece type"


------------------------------------------------------------------------------
-- | discovered checks (with any piece type except pawns)
simpleChecks b = do
  pt <- [ Queen, Rook, Bishop, Knight ]

  let kingMoves  = moveFun b pt (eKingPos b) .&. complement (myPieces b)
  f <- toList $ piecesOf b (b^.next) pt
  let pieceMoves = moveFun b pt f
      common = kingMoves .&. pieceMoves

  -- common should be mempty most of the time, so we should
  -- short circuit the calcualtion from this point
  t <- toList common
  guard $ moveValid pt f t
  return
    $ (capturedPiece .~ pieceAt b t)
    $ defaultMove f t pt (b^.next)

  where
    moveValid Knight f t = let hd = hDist f t
                               vd = vDist f t
                           in (hd == 1 && vd == 2) || (hd == 2 && vd == 1)
    moveValid Bishop f t = hDist f t == vDist f t
    moveValid Rook   f t = hDist f t == 0 || vDist f t == 0
    moveValid Queen  f t = moveValid Rook f t || moveValid Bishop f t
    moveValid _      _ _ = error "unexpected piece type"


------------------------------------------------------------------------------
-- | discovered checks (with any piece type except pawns)