| 
					
				 | 
			
			
				@@ -15,23 +15,36 @@ namespace chessy 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/*! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * This structure holds additional information about a move. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 struct chessy::MoveInfo 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //! the move itself 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     Move move; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //! the type of the piece that was moved 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     PieceType movedPiece; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //! if the move is an en-passant move, this field holds the square of 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //! the pawn, that was captured. Otherwise this index should be zero. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Index enPassantTarget; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    inline MoveInfo(void) : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        enPassantTarget{ 0 } {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 template<typename T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class chessy::Search 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    T& handler; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    T handler; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ChessGame& game; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     Board& board; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     Bitboard whites; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     Bitboard blacks; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    inline Search(T& handler, ChessGame& game) : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    inline Search(T&& handler, ChessGame& game) : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         handler{ handler }, game{ game }, board{ game.getBoard() }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         whites{ board.getWhites() }, blacks{ board.getBlacks() } {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -71,6 +84,9 @@ public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     template<Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     inline void iteratePromotions(Args&&... args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template<Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    inline void iterateEnPassant(Args&&... args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 private: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     template<Side side> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -115,68 +131,6 @@ inline void chessy::Search<T>::iterateAll(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     iterateQueens<side, Args...>(std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     iterateKing<side, Args...>(std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     iterateCastling<side, Args...>(std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Bitboard& rs = board.getRooks<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    PositionSet rooks { rs };  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (auto rook : rooks) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (auto pos : PrimitiveRookMoveGenerator{ rook, enemies, friends }) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            Move move = { rook, pos }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            board.removeAt(move.destination); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            rs.applyMove(move); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            //BestMove m = minimax<otherSide(side)>(depth - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            m.move = move; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            bestMove.overwriteIfBetter(m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            board = temp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Bitboard& qs = board.getQueens<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    PositionSet queens { qs }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (auto queen : queens) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (auto pos : PrimitiveQueenMoveGenerator{ queen, enemies, friends }) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            Move move = { queen, pos }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            board.removeAt(move.destination); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            qs.applyMove(move); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            //BestMove m = minimax<otherSide(side)>(depth - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            m.move = move; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            bestMove.overwriteIfBetter(m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            board = temp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Bitboard& king = board.getKing<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Index kingIndex = king.getLeastSignificantBit(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (auto pos : KingMoveGenerator{ king, friends }) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Move move = { kingIndex, pos }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        board.removeAt(pos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        king.applyMove(move); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        BestMove m = minimax<otherSide(side)>(depth - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m.move = move; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        //if (depth >= 3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        //    std::cout << m.move.asString() << " " << bestMove.value << " -> " << m.value << std::endl; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        bestMove.overwriteIfBetter(m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        board = temp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (side == WHITE_SIDE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (game.getCanCastleKingSide(side)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if((friends.bits & 0x6) == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Move kingMove = {3, 1}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Move rookMove = {0, 2}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                king.applyMove(kingMove); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                rs.applyMove(rookMove); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                board = temp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    float v = evaluate<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    bestMove.value *= 0.9f; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    bestMove.value += v * 0.2f; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return -bestMove;*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -268,18 +222,31 @@ template<typename T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 template<chessy::Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 inline void chessy::Search<T>::iterateCastling(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Bitboard king = board.getKing<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Bitboard allOccupied = whites | blacks; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     MoveInfo moveInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     moveInfo.movedPiece = PieceType::KING; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (game.getCanCastleKingSide(side)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Bitboard king = board.getKing<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Bitboard target = king.bits >> 2; // move king to the right 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Bitboard rook = king.bits >> 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Bitboard rook = king.bits << 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Bitboard rookTarget = king.bits >> 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!(target | friends<WHITE_SIDE>() | friends<BLACK_SIDE>()) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            !(rookTarget | friends<WHITE_SIDE>() | friends<BLACK_SIDE>())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!(target & allOccupied) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            !(rookTarget & allOccupied)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            moveInfo.move = Move{ king.getLeastSignificantBit(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                target.getLeastSignificantBit(), true }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            handler(moveInfo, std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (game.getCanCastleQueenSide(side)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Bitboard target = king.bits << 2; // move king to the left 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Bitboard rook = king.bits >> 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Bitboard rookTarget = king.bits << 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!(target & allOccupied) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            !(rookTarget & allOccupied)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            moveInfo.move = Move{ king.getLeastSignificantBit(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                target.getLeastSignificantBit(), true }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            handler(moveInfo, std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        moveInfo.move = Move{ king, target, true }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -347,45 +314,43 @@ inline void chessy::Search<T>::iteratePromotions(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 template<typename T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 template<chessy::Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-inline void chessy::Search<T>::iteratePawns(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+inline void chessy::Search<T>::iterateEnPassant(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    iterateSinglePawnPushes<side, Args...>(std::forward(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    iterateDoublePawnPushes<side, Args...>(std::forward(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    iteratePawnCaptures<side, Args...>(std::forward(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    iteratePromotions<side, Args...>(std::forward(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    PawnCaptureGenerator<side, LEFT> pl{ game }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (Move capture : pl) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Bitboard& pawns = board.getPawns<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        board.removeAt(capture.destination); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        pawns.applyMove(capture); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        BestMove m = minimax<otherSide(side)>(depth - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m.move = capture; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        bestMove.overwriteIfBetter(m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        board = temp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MoveInfo moveInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    moveInfo.movedPiece = PieceType::PAWN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Index enPassant = game.getEnPassantIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (enPassant.index != -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Bitboard pawns = board.getPawns<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int rowIndex = side == WHITE_SIDE ? 4 : 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int targetRowIndex = side == WHITE_SIDE ? 5 : 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int columnIndex = enPassant.index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Bitboard pawnColumns = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (columnIndex > 0)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            pawnColumns |= Bitboard::getColumn(columnIndex - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (columnIndex < 7)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            pawnColumns |= Bitboard::getColumn(columnIndex + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        pawns &= rowIndex & pawnColumns; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        moveInfo.enPassantTarget = Index{ enPassant.index, rowIndex }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Index target{ enPassant.index, targetRowIndex }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        PositionSet sources = pawns; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (auto source : sources) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            moveInfo.move = Move{ source, target }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            handler(moveInfo, std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    PawnCaptureGenerator<side, RIGHT> pr{ game }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (Move capture : pr) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Bitboard& pawns = board.getPawns<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        board.removeAt(capture.destination); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        pawns.applyMove(capture); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        BestMove m = minimax<otherSide(side)>(depth - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m.move = capture; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        bestMove.overwriteIfBetter(m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        board = temp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    PromotionGenerator<side> pg{ game }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (Move promotion : pg) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Bitboard& pawns = board.getPawns<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        board.removeAt(promotion.destination); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        pawns.applyMove(promotion); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        BestMove m = minimax<otherSide(side)>(depth - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m.move = promotion; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        bestMove.overwriteIfBetter(m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        board = temp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<typename T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<chessy::Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+inline void chessy::Search<T>::iteratePawns(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    iterateSinglePawnPushes<side, Args...>(std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    iterateDoublePawnPushes<side, Args...>(std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    iteratePawnCaptures<side, Args...>(std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    iteratePromotions<side, Args...>(std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    iterateEnPassant<side, Args...>(std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |