module MoveGen.PieceQuietMoves (allQuietMoves) where
import AppPrelude
import Models.Move
import Models.Piece
import Models.Position
import MoveGen.PieceAttacks
import MoveGen.PieceCaptures
import Utils.Board
allQuietMoves :: Position -> [Move]
allQuietMoves :: Position -> [Move]
allQuietMoves pos :: Position
pos@Position {Phase
[ZKey]
Ply
Board
Color
previousPositions :: [ZKey]
halfMoveClock :: Ply
phase :: Phase
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 -> Phase
$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
..}
| Board
allCheckers Board -> Board -> Bool
forall a. Eq a => a -> a -> Bool
== Board
0 = (Board -> Board) -> [Move]
genMoves Board -> Board
forall a. a -> a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
| Board
leapingCheckers Board -> Board -> Bool
forall a. Eq a => a -> a -> Bool
/= Board
0 Bool -> Bool -> Bool
|| Board -> Int
popCount Board
allCheckers Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 = [Move]
allKingMoves
| Bool
otherwise = (Board -> Board) -> [Move]
genMoves Board -> Board
blockChecker
where
genMoves :: (Board -> Board) -> [Move]
genMoves = Board -> Board -> [Move] -> Position -> (Board -> Board) -> [Move]
quietMovesHelper Board
allPieces Board
king [Move]
allKingMoves Position
pos
blockChecker :: Board -> Board
blockChecker Board
board = Board
board Board -> Board -> Board
& Board
checkerRay
checkerRay :: Board
checkerRay = Board -> Int -> Board
getKingQueenRay Board
king Int
checkerSquare
Board -> Board -> Board
& Board -> Int -> Board
queenAttacks Board
allPieces Int
kingSquare
Board -> Board -> Board
& Board -> Int -> Board
queenAttacks Board
allPieces Int
checkerSquare
checkerSquare :: Int
checkerSquare = Board -> Int
lsb Board
allCheckers
allKingMoves :: [Move]
allKingMoves =
Piece -> (Int -> Board) -> [Move] -> Int -> [Move]
foldBoardSquares Piece
King
(Board -> Board -> Board -> Board -> Board -> Int -> Board
kingQuietMoves Board
allPieces Board
attacked Board
castling (Board
playerBoard -> Board -> Board
&Board
rooks) Board
king) [] Int
kingSquare
allCheckers :: Board
allCheckers = Board
leapingCheckers Board -> Board -> Board
.| Board
sliderCheckers
allPieces :: Board
allPieces = Board
player Board -> Board -> Board
.| Board
enemy
kingSquare :: Int
kingSquare = Board -> Int
lsb Board
king
king :: Board
king = Board
playerBoard -> Board -> Board
&Board
kings
quietMovesHelper :: Board -> Board -> [Move] -> Position -> (Board -> Board)
-> [Move]
quietMovesHelper :: Board -> Board -> [Move] -> Position -> (Board -> Board) -> [Move]
quietMovesHelper Board
allPieces Board
king [Move]
allKingMoves Position {Phase
[ZKey]
Ply
Board
Color
$sel:previousPositions:Position :: Position -> [ZKey]
$sel:halfMoveClock:Position :: Position -> Ply
$sel:phase:Position :: Position -> Phase
$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 :: Phase
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 -> Board
f =
Piece -> (Int -> Board) -> Board -> [Move] -> [Move]
foldBoardMoves Piece
Pawn (Board -> Board
f (Board -> Board) -> (Int -> Board) -> Int -> Board
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Board -> Color -> Board -> Board
pawnAdvances Board
noPieces Color
color
(Board -> Board) -> (Int -> Board) -> Int -> Board
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int -> Board
toBoard)
(Board
unpinnedBoard -> Board -> Board
&Board
pawns Board -> Board -> Board
.| Board
filePinnedPawns)
([Move] -> [Move]) -> [Move] -> [Move]
forall a b. (a -> b) -> a -> b
$ Piece -> (Int -> Board) -> Board -> [Move] -> [Move]
foldBoardMoves Piece
Knight (Board -> Board
f (Board -> Board) -> (Int -> Board) -> Int -> Board
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Board -> Int -> Board
knightCaptures Board
noPieces)
(Board
unpinnedBoard -> Board -> Board
&Board
knights)
([Move] -> [Move]) -> [Move] -> [Move]
forall a b. (a -> b) -> a -> b
$ Piece -> (Int -> Board) -> Board -> [Move] -> [Move]
foldBoardMoves Piece
Bishop (Board -> Board
f (Board -> Board) -> (Int -> Board) -> Int -> Board
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Board -> Board -> Board -> Board -> Int -> Board
bishopQuietMoves Board
noPieces
Board
allPieces Board
pinnedPieces Board
king)
(Board
playerBoard -> Board -> Board
&Board
bishops)
([Move] -> [Move]) -> [Move] -> [Move]
forall a b. (a -> b) -> a -> b
$ Piece -> (Int -> Board) -> Board -> [Move] -> [Move]
foldBoardMoves Piece
Rook (Board -> Board
f (Board -> Board) -> (Int -> Board) -> Int -> Board
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Board -> Board -> Board -> Board -> Int -> Board
rookQuietMoves Board
noPieces
Board
allPieces Board
pinnedPieces Board
king)
(Board
playerBoard -> Board -> Board
&Board
rooks)
([Move] -> [Move]) -> [Move] -> [Move]
forall a b. (a -> b) -> a -> b
$ Piece -> (Int -> Board) -> Board -> [Move] -> [Move]
foldBoardMoves Piece
Queen (Board -> Board
f (Board -> Board) -> (Int -> Board) -> Int -> Board
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Board -> Board -> Board -> Board -> Int -> Board
queenQuietMoves Board
noPieces
Board
allPieces Board
pinnedPieces Board
king)
(Board
playerBoard -> Board -> Board
&Board
queens)
[Move]
allKingMoves
where
unpinned :: Board
unpinned = Board
player Board -> Board -> Board
.\ Board
pinnedPieces
pinnedPawns :: Board
pinnedPawns = Board
pinnedPieces Board -> Board -> Board
& Board
pawns
filePinnedPawns :: Board
filePinnedPawns = Board
pinnedPawns Board -> Board -> Board
& Board
kingFile
kingFile :: Board
kingFile = Vector Board
rankMovesVec Vector Board -> Int -> Board
forall a. Storable a => Vector a -> Int -> a
!! Int
kingSquare
kingSquare :: Int
kingSquare = Board -> Int
lsb Board
king
noPieces :: Board
noPieces = Board -> Board
(~) Board
allPieces
pawnAdvances :: Board -> Color -> Board -> Board
pawnAdvances :: Board -> Color -> Board -> Board
pawnAdvances Board
noPieces Color
color Board
board = Board
advances Board -> Board -> Board
& Board
noPieces
where
advances :: Board
advances = case Color
color of
Color
White -> (Board
board Board -> Board -> Board
.\ Board
rank_7) Board -> Int -> Board
forall a. Bits a => a -> Int -> a
<< Int
8
Board -> Board -> Board
.| ((Board
board Board -> Board -> Board
& Board
rank_2) Board -> Int -> Board
forall a. Bits a => a -> Int -> a
<< Int
8 Board -> Board -> Board
& Board
noPieces) Board -> Int -> Board
forall a. Bits a => a -> Int -> a
<< Int
8
Color
Black -> (Board
board Board -> Board -> Board
.\ Board
rank_2) Board -> Int -> Board
forall a. Bits a => a -> Int -> a
>> Int
8
Board -> Board -> Board
.| ((Board
board Board -> Board -> Board
& Board
rank_7) Board -> Int -> Board
forall a. Bits a => a -> Int -> a
>> Int
8 Board -> Board -> Board
& Board
noPieces) Board -> Int -> Board
forall a. Bits a => a -> Int -> a
>> Int
8
bishopQuietMoves :: Board -> Board -> Board -> Board -> Square -> Board
bishopQuietMoves :: Board -> Board -> Board -> Board -> Int -> Board
bishopQuietMoves Board
noPieces Board
allPieces Board
pinnedPieces Board
king Int
n =
Board -> Board -> Board -> Int -> Board
bishopMoves Board
allPieces Board
pinnedPieces Board
king Int
n Board -> Board -> Board
& Board
noPieces
rookQuietMoves :: Board -> Board -> Board -> Board -> Square -> Board
rookQuietMoves :: Board -> Board -> Board -> Board -> Int -> Board
rookQuietMoves Board
noPieces Board
allPieces Board
pinnedPieces Board
king Int
n =
Board -> Board -> Board -> Int -> Board
rookMoves Board
allPieces Board
pinnedPieces Board
king Int
n Board -> Board -> Board
& Board
noPieces
queenQuietMoves :: Board -> Board -> Board -> Board -> Square -> Board
queenQuietMoves :: Board -> Board -> Board -> Board -> Int -> Board
queenQuietMoves Board
noPieces Board
allPieces Board
pinnedPieces Board
king Int
n =
Board -> Board -> Board -> Int -> Board
queenMoves Board
allPieces Board
pinnedPieces Board
king Int
n Board -> Board -> Board
& Board
noPieces
kingQuietMoves :: Board -> Board -> Board -> Board -> Board -> Square -> Board
kingQuietMoves :: Board -> Board -> Board -> Board -> Board -> Int -> Board
kingQuietMoves Board
allPieces Board
attacked Board
castling Board
rooks Board
king Int
n =
(Int -> Board
kingAttacks Int
n
Board -> Board -> Board
.| Board -> Board -> Board -> Board -> Board -> Int -> Board
kingCastlingMoves Board
allPieces Board
attacked Board
castling Board
rooks Board
king Int
n)
Board -> Board -> Board
.\ (Board
attacked Board -> Board -> Board
.| Board
allPieces)
kingCastlingMoves :: Board -> Board -> Board -> Board -> Board -> Square -> Board
kingCastlingMoves :: Board -> Board -> Board -> Board -> Board -> Int -> Board
kingCastlingMoves Board
allPieces Board
attacked Board
castling Board
rooks Board
king Int
n =
(Board
shortCastlingCond
Board -> Board -> Board
forall a. Num a => a -> a -> a
* Int -> Board
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Board -> Int
popCount (Board
castling Board -> Board -> Board
& Board
rooks Board -> Board -> Board
& Board
file_H))
Board -> Board -> Board
forall a. Num a => a -> a -> a
* ((Board
castling Board -> Board -> Board
& Board
king) Board -> Int -> Board
forall a. Bits a => a -> Int -> a
<< Int
2))
Board -> Board -> Board
.|
(Board
longCastlingCond
Board -> Board -> Board
forall a. Num a => a -> a -> a
* Int -> Board
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Board -> Int
popCount (Board
castling Board -> Board -> Board
& Board
rooks Board -> Board -> Board
& Board
file_A))
Board -> Board -> Board
forall a. Num a => a -> a -> a
* ((Board
castling Board -> Board -> Board
& Board
king) Board -> Int -> Board
forall a. Bits a => a -> Int -> a
>> Int
2))
where
shortCastlingCond :: Board
shortCastlingCond =
Board -> Board
forall a. (Num a, Ord a) => a -> a
toReverseCondition (Board
shortCastleSlidingFiles Board -> Board -> Board
& Board
collisions Board -> Board -> Board
.| Board
inCheck)
longCastlingCond :: Board
longCastlingCond =
Board -> Board
forall a. (Num a, Ord a) => a -> a
toReverseCondition (Board
longCastleSlidingFiles Board -> Board -> Board
& Board
collisions
Board -> Board -> Board
.| Board
inCheck
Board -> Board -> Board
.| Board
allPieces Board -> Board -> Board
& Board
kingRank Board -> Board -> Board
& Board
file_B)
collisions :: Board
collisions = Board
kingRank Board -> Board -> Board
& (Board
attacked Board -> Board -> Board
.| Board
allPieces)
kingRank :: Board
kingRank = Vector Board
fileMovesVec Vector Board -> Int -> Board
forall a. Storable a => Vector a -> Int -> a
!! Int
n
inCheck :: Board
inCheck = Board
king Board -> Board -> Board
& Board
attacked