Browse Source

testing search

Nicolas Winkler 7 năm trước cách đây
mục cha
commit
dcecc03df5
2 tập tin đã thay đổi với 241 bổ sung71 xóa
  1. 224 71
      src/Search.h
  2. 17 0
      src/main.cpp

+ 224 - 71
src/Search.h

@@ -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;
-    }
+    }*/
 }
 
 

+ 17 - 0
src/main.cpp

@@ -2,6 +2,8 @@
 #include "EngineInfo.h"
 #include "UciParser.h"
 
+#include "Search.h"
+
 using namespace std;
 using namespace chessy;
 
@@ -11,6 +13,21 @@ using namespace chessy;
  */
 auto main(int argc, char** argv) -> int
 {
+    ChessGame cg{ "8/1pP5/3Qp2p/2K1P1P1/1p1p4/4p3/k2P3P/4b1n1 w - - 0 1" };
+    auto printer = [](const MoveInfo& mi) {
+        cout << mi.move.asString() << endl;
+    };
+
+    Search<decltype(printer)> search{ printer, cg };
+    search.iterateAll<WHITE_SIDE>();
+    cout << endl << endl;
+    search.iterateAll<BLACK_SIDE>();
+    cin.get();
+
+    return 0;
+
+
+
     if (argc > 1 && (string(argv[1]) == "-h" || string(argv[1]) == "--help")) {
         cout << info::helpText << endl;
         return 0;