| 
					
				 | 
			
			
				@@ -208,10 +208,163 @@ CastlingGenerator<side>::CastlingGenerator(const ChessGame& game) : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<Side side> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void chessy::generatePawnPushes(const ChessGame& cg, std::vector<Move>& moves) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PawnPushGenerator<side> ppg{ cg }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (const auto& move : ppg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        moves.push_back(move); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<Side side> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void chessy::generatePawnDoublePushes(const ChessGame& cg, std::vector<Move>& moves) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PawnDoublePushGenerator<side> pdpg{ cg }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (const auto& move : pdpg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        moves.push_back(move); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<Side side> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void chessy::generatePawnCaptures(const ChessGame& cg, std::vector<Move>& moves) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PawnCaptureGenerator<side, LEFT> pcgl{ cg }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PawnCaptureGenerator<side, RIGHT> pcgr{ cg }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (const auto& move : pcgl) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        moves.push_back(move); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (const auto& move : pcgr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        moves.push_back(move); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<Side side> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void chessy::generatePawnPromotions(const ChessGame& cg, std::vector<Move>& moves) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PromotionGenerator<side> pg{ cg }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (const auto& move : pg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        moves.push_back(move); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<Side side> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void chessy::generateKnightMoves(const ChessGame& cg, std::vector<Move>& moves) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const Board& b = cg.getBoard(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PositionSet p{ b.getKnights<side>() }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (auto pos : p) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        KnightMoveGenerator g{ pos, b.get<side>() }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (auto target : g) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            moves.emplace_back(pos, target); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<Side side, typename Generator> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void generateMoves(Bitboard position, Bitboard enemies, Bitboard friendly, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    std::vector<Move>& moves) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PositionSet p{ position }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (auto pos : p) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Generator g{ pos, enemies, friendly }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (auto target : g) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            moves.emplace_back(pos, target); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<Side side> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void chessy::generateQueenMoves(const ChessGame& cg, std::vector<Move>& moves) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const Board& b = cg.getBoard(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    generateMoves<side, PrimitiveQueenMoveGenerator>( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        b.getKnights<side>(), b.get<otherSide(side)>(), b.get<side>(), moves 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<Side side> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void chessy::generateRookMoves(const ChessGame& cg, std::vector<Move>& moves) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const Board& b = cg.getBoard(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    generateMoves<side, PrimitiveRookMoveGenerator>( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        b.getKnights<side>(), b.get<otherSide(side)>(), b.get<side>(), moves 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<Side side> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void chessy::generateBishopMoves(const ChessGame& cg, std::vector<Move>& moves) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const Board& b = cg.getBoard(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    generateMoves<side,PrimitiveBishopMoveGenerator>( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        b.getKnights<side>(), b.get<otherSide(side)>(), b.get<side>(), moves 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<Side side> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void chessy::generateKingMoves(const ChessGame& cg, std::vector<Move>& moves) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const Board& b = cg.getBoard(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Bitboard king = b.getKing<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Index kingIndex = king.getLeastSignificantBit(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (auto pos : KingMoveGenerator{ king, b.get<side>() }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        moves.emplace_back(kingIndex, pos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<Side side> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void chessy::generateCastling(const ChessGame& cg, std::vector<Move>& moves) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const Board& b = cg.getBoard(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Bitboard king = b.getKing<side>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Bitboard allOccupied = b.getOccupied(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (cg.getCanCastleKingSide(side)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Bitboard target = king.bits >> 2; // move king to the right 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Bitboard rook = king.bits << 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Bitboard rookTarget = king.bits >> 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!(target & allOccupied) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            !(rookTarget & allOccupied)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            moves.emplace_back(king.getLeastSignificantBit(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                target.getLeastSignificantBit(), true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (cg.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)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            moves.emplace_back(king.getLeastSignificantBit(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                target.getLeastSignificantBit(), true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template<Side side> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void chessy::generateAllMoves(const ChessGame& cg, std::vector<Move>& moves) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    generatePawnPushes<side>(cg, moves); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    generatePawnDoublePushes<side>(cg, moves); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    generatePawnCaptures<side>(cg, moves); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    generatePawnPromotions<side>(cg, moves); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    generateKnightMoves<side>(cg, moves); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    generateQueenMoves<side>(cg, moves); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    generateBishopMoves<side>(cg, moves); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    generateRookMoves<side>(cg, moves); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    generateKingMoves<side>(cg, moves); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    generateCastling<side>(cg, moves); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // explicit instatiations 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 namespace chessy 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    template class PawnPushGenerator<WHITE_SIDE>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /*template class PawnPushGenerator<WHITE_SIDE>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     template class PawnPushGenerator<BLACK_SIDE>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     template class PromotionGenerator<WHITE_SIDE>; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -226,5 +379,8 @@ namespace chessy 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     template class PawnCaptureGenerator<BLACK_SIDE, RIGHT>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     template class CastlingGenerator<WHITE_SIDE>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    template class CastlingGenerator<BLACK_SIDE>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template class CastlingGenerator<BLACK_SIDE>;*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template void generateAllMoves<WHITE_SIDE>(const ChessGame&, std::vector<Move>&); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    template void generateAllMoves<BLACK_SIDE>(const ChessGame&, std::vector<Move>&); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |