| 
					
				 | 
			
			
				@@ -9,26 +9,78 @@ namespace chessy 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     template<typename T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     class Search; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    struct MoveInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     class MinimaxN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct chessy::MoveInfo 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Move move; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PieceType movedPiece; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 template<typename T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class chessy::Search 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     T& handler; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ChessGame& game; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Board& board; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Bitboard whites; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Bitboard blacks; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     inline Search(T& handler, ChessGame& game) : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        game{ game }, handler{ handler } {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handler{ handler }, game{ game }, board{ game.getBoard() }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        whites{ board.getWhites() }, blacks{ board.getBlacks() } {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    template<typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template<Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     inline void iterateAll(Args&&... args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     template<Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    inline void iterateKnights(Args&&... args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template<Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    inline void iterateBishops(Args&&... args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template<Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    inline void iterateRooks(Args&&... args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template<Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    inline void iterateQueens(Args&&... args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template<Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    inline void iterateKing(Args&&... args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template<Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     inline void iteratePawns(Args&&... args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template<Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    inline void iterateSinglePawnPushes(Args&&... args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template<Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    inline void iterateDoublePawnPushes(Args&&... args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template<Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    inline void iteratePawnCaptures(Args&&... args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template<Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    inline void iteratePromotions(Args&&... args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 private: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template<Side side> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    inline Bitboard friends(void) const 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return side == WHITE_SIDE ? whites : blacks; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template<Side side> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    inline Bitboard enemies(void) const 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return side == WHITE_SIDE ? blacks : whites; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -50,57 +102,18 @@ public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 template<typename T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-template<typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<chessy::Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 inline void chessy::Search<T>::iterateAll(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Board& board = game.getBoard(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Bitboard friends; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Bitboard enemies; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Side side = WHITE_SIDE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (side == WHITE_SIDE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        friends = board.getWhites(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        enemies = board.getBlacks(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        friends = board.getBlacks(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        enemies = board.getWhites(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    iteratePawns<side, Args...>(std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    iterateKnights<side, Args...>(std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    iterateBishops<side, Args...>(std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    iterateRooks<side, Args...>(std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    iterateQueens<side, Args...>(std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    iterateKing<side, Args...>(std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const Board temp = board; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (side == WHITE_SIDE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        iteratePawns<Args...>(std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        iteratePawns<Args...>(std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Bitboard& ns = board.getKnights<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    PositionSet knights{ ns }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (auto knight : knights) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (auto pos : KnightMoveGenerator{ knight, friends }) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            Move move = { knight, pos }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            board.removeAt(move.destination); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ns.applyMove(move); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            BestMove m = minimax<otherSide(side)>(depth - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            m.move = move; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            bestMove.overwriteIfBetter(m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            board = temp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Bitboard& bs = board.getBishops<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    PositionSet bishops { bs };  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (auto bishop : bishops) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (auto pos : PrimitiveBishopMoveGenerator{ bishop, enemies, friends }) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            Move move = { bishop, pos }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            board.removeAt(move.destination); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            bs.applyMove(move); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            BestMove m = minimax<otherSide(side)>(depth - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            m.move = move; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            bestMove.overwriteIfBetter(m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            board = temp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     Bitboard& rs = board.getRooks<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     PositionSet rooks { rs };  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -109,7 +122,7 @@ inline void chessy::Search<T>::iterateAll(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             Move move = { rook, pos }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             board.removeAt(move.destination); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             rs.applyMove(move); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            BestMove m = minimax<otherSide(side)>(depth - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //BestMove m = minimax<otherSide(side)>(depth - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             m.move = move; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             bestMove.overwriteIfBetter(m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             board = temp; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -123,7 +136,7 @@ inline void chessy::Search<T>::iterateAll(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             Move move = { queen, pos }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             board.removeAt(move.destination); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             qs.applyMove(move); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            BestMove m = minimax<otherSide(side)>(depth - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //BestMove m = minimax<otherSide(side)>(depth - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             m.move = move; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             bestMove.overwriteIfBetter(m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             board = temp; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -143,40 +156,180 @@ inline void chessy::Search<T>::iterateAll(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         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; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return -bestMove;*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 template<typename T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 template<chessy::Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-inline void chessy::Search<T>::iteratePawns(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+inline void chessy::Search<T>::iterateKnights(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const Board temp = board; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MoveInfo moveInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Bitboard& ns = board.getKnights<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PositionSet knights{ ns }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    moveInfo.movedPiece = PieceType::KNIGHT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (auto knight : knights) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (auto pos : KnightMoveGenerator{ knight, friends<side>() }) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            moveInfo.move = Move{ knight, pos }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            handler(moveInfo, std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<typename T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<chessy::Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+inline void chessy::Search<T>::iterateBishops(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MoveInfo moveInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    moveInfo.movedPiece = PieceType::BISHOP; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PositionSet bishops { board.getBishops<side>() };  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (auto bishop : bishops) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (auto pos : PrimitiveBishopMoveGenerator{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            bishop, enemies<side>(), friends<side>() }) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            moveInfo.move = Move{ bishop, pos }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            handler(moveInfo, std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<typename T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<chessy::Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+inline void chessy::Search<T>::iterateRooks(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MoveInfo moveInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    moveInfo.movedPiece = PieceType::ROOK; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PositionSet rooks { board.getRooks<side>() };  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (auto rook : rooks) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (auto pos : PrimitiveRookMoveGenerator{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            rook, enemies<side>(), friends<side>() }) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            moveInfo.move = Move{ rook, pos }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            handler(moveInfo, std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<typename T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<chessy::Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+inline void chessy::Search<T>::iterateQueens(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MoveInfo moveInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    moveInfo.movedPiece = PieceType::QUEEN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PositionSet queens { board.getQueens<side>() };  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (auto queen : queens) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (auto pos : PrimitiveQueenMoveGenerator{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            queen, enemies<side>(), friends<side>() }) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            moveInfo.move = Move{ queen, pos }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            handler(moveInfo, std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<typename T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<chessy::Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+inline void chessy::Search<T>::iterateKing(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MoveInfo moveInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    moveInfo.movedPiece = PieceType::KING; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Bitboard king = board.getKing<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (auto pos : KingMoveGenerator{ king, friends<side>() }) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        moveInfo.move = Move{ king.getLeastSignificantBit(), pos }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handler(moveInfo, std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<typename T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<chessy::Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+inline void chessy::Search<T>::iterateSinglePawnPushes(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MoveInfo moveInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    moveInfo.movedPiece = PieceType::PAWN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     PawnPushGenerator<side> mg{ game }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     for (Move push : mg) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Bitboard& pawns = board.getPawns<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Bitboard pTemp = pawns; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        pawns.applyMove(push); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        BestMove m = minimax<otherSide(side)>(depth - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m.move = push; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        bestMove.overwriteIfBetter(m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        pawns = pTemp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        moveInfo.move = push; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handler(moveInfo, std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    PawnDoublePushGenerator<side> dp{ game }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (Move push : dp) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Bitboard& pawns = board.getPawns<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Bitboard pTemp = pawns; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        pawns.applyMove(push); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        BestMove m = minimax<otherSide(side)>(depth - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m.move = push; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        bestMove.overwriteIfBetter(m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        pawns = pTemp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<typename T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<chessy::Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+inline void chessy::Search<T>::iterateDoublePawnPushes(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MoveInfo moveInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    moveInfo.movedPiece = PieceType::PAWN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PawnDoublePushGenerator<side> mg{ game }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (Move push : mg) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        moveInfo.move = push; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handler(moveInfo, std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<typename T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<chessy::Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+inline void chessy::Search<T>::iteratePawnCaptures(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MoveInfo moveInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    moveInfo.movedPiece = PieceType::PAWN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PawnCaptureGenerator<side, LEFT> mgl{ game }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (Move push : mgl) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        moveInfo.move = push; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handler(moveInfo, std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PawnCaptureGenerator<side, RIGHT> mgr{ game }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (Move push : mgr) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        moveInfo.move = push; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handler(moveInfo, std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<typename T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<chessy::Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+inline void chessy::Search<T>::iteratePromotions(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MoveInfo moveInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    moveInfo.movedPiece = PieceType::PAWN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PromotionGenerator<side> pg{ game }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (Move promotion : pg) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        moveInfo.move = promotion; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handler(moveInfo, std::forward<Args>(args)...); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<typename T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<chessy::Side side, typename... Args> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+inline void chessy::Search<T>::iteratePawns(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>(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -208,7 +361,7 @@ inline void chessy::Search<T>::iteratePawns(Args&&... args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         m.move = promotion; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         bestMove.overwriteIfBetter(m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         board = temp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |