module MoveGen.MoveQueries (isQuietMove, isLegalQuietMove, isWinningCapture, isCheckMove, isPromotionPush, isCastlingMove, isCapture) where

import           AppPrelude

import           Evaluation.Evaluation
import           Models.Move
import           Models.Piece
import           Models.Position
import           MoveGen.MakeMove
import           MoveGen.PieceQuietMoves (allQuietMoves)
import           MoveGen.PositionQueries
import           Utils.Board


isCastlingMove :: Move -> Bool
isCastlingMove :: Move -> Bool
isCastlingMove Move {Rank
Promotion
Piece
piece :: Piece
promotion :: Promotion
start :: Rank
end :: Rank
$sel:piece:Move :: Move -> Piece
$sel:promotion:Move :: Move -> Promotion
$sel:start:Move :: Move -> Rank
$sel:end:Move :: Move -> Rank
..} =
  Piece
piece Piece -> Piece -> Bool
forall a. Eq a => a -> a -> Bool
== Piece
King Bool -> Bool -> Bool
&& Rank -> Rank
forall a. Num a => a -> a
abs (Rank
start Rank -> Rank -> Rank
forall a. Num a => a -> a -> a
- Rank
end) Rank -> Rank -> Bool
forall a. Eq a => a -> a -> Bool
== Rank
2


isCheckMove :: Move -> Position -> Bool
isCheckMove :: Move -> Position -> Bool
isCheckMove Move
mv Position
pos =
  Position -> Bool
isKingInCheck (Position -> Bool) -> Position -> Bool
forall a b. (a -> b) -> a -> b
$ Move -> Position -> Position
makeMove Move
mv Position
pos


isCapture :: Move -> Position -> Bool
isCapture :: Move -> Position -> Bool
isCapture Move {Rank
Promotion
Piece
$sel:piece:Move :: Move -> Piece
$sel:promotion:Move :: Move -> Promotion
$sel:start:Move :: Move -> Rank
$sel:end:Move :: Move -> Rank
piece :: Piece
promotion :: Promotion
start :: Rank
end :: Rank
..} Position {Score
[ZKey]
Ply
Board
Color
previousPositions :: [ZKey]
halfMoveClock :: Ply
phase :: Score
color :: Color
player :: Board
enemy :: Board
pawns :: Board
knights :: Board
bishops :: Board
rooks :: Board
queens :: Board
kings :: Board
enPassant :: Board
castling :: Board
attacked :: Board
leapingCheckers :: Board
sliderCheckers :: Board
pinnedPieces :: Board
$sel:previousPositions:Position :: Position -> [ZKey]
$sel:halfMoveClock:Position :: Position -> Ply
$sel:phase:Position :: Position -> Score
$sel:color:Position :: Position -> Color
$sel:player:Position :: Position -> Board
$sel:enemy:Position :: Position -> Board
$sel:pawns:Position :: Position -> Board
$sel:knights:Position :: Position -> Board
$sel:bishops:Position :: Position -> Board
$sel:rooks:Position :: Position -> Board
$sel:queens:Position :: Position -> Board
$sel:kings:Position :: Position -> Board
$sel:enPassant:Position :: Position -> Board
$sel:castling:Position :: Position -> Board
$sel:attacked:Position :: Position -> Board
$sel:leapingCheckers:Position :: Position -> Board
$sel:sliderCheckers:Position :: Position -> Board
$sel:pinnedPieces:Position :: Position -> Board
..} =
  Promotion
promotion Promotion -> Promotion -> Bool
forall a. Eq a => a -> a -> Bool
/= Promotion
NoProm
    Bool -> Bool -> Bool
|| Board -> Rank -> Bool
testSquare Board
enemy Rank
end
    Bool -> Bool -> Bool
|| Piece
piece Piece -> Piece -> Bool
forall a. Eq a => a -> a -> Bool
== Piece
Pawn Bool -> Bool -> Bool
&& Board -> Rank -> Bool
testSquare Board
enPassant Rank
end


isWinningCapture :: Move -> Position -> Bool
isWinningCapture :: Move -> Position -> Bool
isWinningCapture Move
mv Position
pos =
  Move -> Position -> Bool
isCapture Move
mv Position
pos
    Bool -> Bool -> Bool
&& ContainerKey (Set Promotion) -> Set Promotion -> Bool
forall set. SetContainer set => ContainerKey set -> set -> Bool
member Move
mv.promotion Set Promotion
bestPromotions
    Bool -> Bool -> Bool
&& Move -> Position -> Score
evaluateExchange Move
mv Position
pos Score -> Score -> Bool
forall a. Ord a => a -> a -> Bool
>= Score
0


isPromotionPush :: Move -> Bool
isPromotionPush :: Move -> Bool
isPromotionPush Move{Rank
Promotion
Piece
$sel:piece:Move :: Move -> Piece
$sel:promotion:Move :: Move -> Promotion
$sel:start:Move :: Move -> Rank
$sel:end:Move :: Move -> Rank
piece :: Piece
promotion :: Promotion
start :: Rank
end :: Rank
..} =
  Piece
piece Piece -> Piece -> Bool
forall a. Eq a => a -> a -> Bool
== Piece
Pawn Bool -> Bool -> Bool
&& Rank -> Rank
toRank Rank
end Rank -> [Rank] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Rank
2, Rank
7]


isQuietMove :: Move -> Position -> Bool
isQuietMove :: Move -> Position -> Bool
isQuietMove Move
mv Position
pos =
  Bool -> Bool
not (Move -> Position -> Bool
isCheckMove Move
mv Position
pos Bool -> Bool -> Bool
|| Move -> Position -> Bool
isCapture Move
mv Position
pos)


isLegalQuietMove :: Move -> Position -> Bool
isLegalQuietMove :: Move -> Position -> Bool
isLegalQuietMove mv :: Move
mv@Move {Rank
Promotion
Piece
$sel:piece:Move :: Move -> Piece
$sel:promotion:Move :: Move -> Promotion
$sel:start:Move :: Move -> Rank
$sel:end:Move :: Move -> Rank
piece :: Piece
promotion :: Promotion
start :: Rank
end :: Rank
..} pos :: Position
pos@Position {Score
[ZKey]
Ply
Board
Color
$sel:previousPositions:Position :: Position -> [ZKey]
$sel:halfMoveClock:Position :: Position -> Ply
$sel:phase:Position :: Position -> Score
$sel:color:Position :: Position -> Color
$sel:player:Position :: Position -> Board
$sel:enemy:Position :: Position -> Board
$sel:pawns:Position :: Position -> Board
$sel:knights:Position :: Position -> Board
$sel:bishops:Position :: Position -> Board
$sel:rooks:Position :: Position -> Board
$sel:queens:Position :: Position -> Board
$sel:kings:Position :: Position -> Board
$sel:enPassant:Position :: Position -> Board
$sel:castling:Position :: Position -> Board
$sel:attacked:Position :: Position -> Board
$sel:leapingCheckers:Position :: Position -> Board
$sel:sliderCheckers:Position :: Position -> Board
$sel:pinnedPieces:Position :: Position -> Board
previousPositions :: [ZKey]
halfMoveClock :: Ply
phase :: Score
color :: Color
player :: Board
enemy :: Board
pawns :: Board
knights :: Board
bishops :: Board
rooks :: Board
queens :: Board
kings :: Board
enPassant :: Board
castling :: Board
attacked :: Board
leapingCheckers :: Board
sliderCheckers :: Board
pinnedPieces :: Board
..} =
  Board -> Rank -> Bool
testSquare Board
player Rank
start
    Bool -> Bool -> Bool
&& Bool -> Bool
not (Board -> Rank -> Bool
testSquare Board
allPieces Rank
end)
    Bool -> Bool -> Bool
&& Piece -> Rank -> Position -> Bool
isPieceAt Piece
piece Rank
start Position
pos
    Bool -> Bool -> Bool
&& Move -> [Move] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem Move
mv (Position -> [Move]
allQuietMoves Position
pos)
  where
    allPieces :: Board
allPieces = Board
enemy Board -> Board -> Board
.| Board
player