浏览代码

added a bit to move generation

nicolaswinkler 7 年之前
父节点
当前提交
aaab7fe687
共有 5 个文件被更改,包括 110 次插入38 次删除
  1. 3 3
      src/BitBoard.h
  2. 18 17
      src/ChessGame.cpp
  3. 50 7
      src/MoveGeneration.cpp
  4. 27 6
      src/MoveGeneration.h
  5. 12 5
      src/main.cpp

+ 3 - 3
src/BitBoard.h

@@ -23,10 +23,10 @@ union chessy::Index
     int8_t index;
 
     Index(void) = default;
-    inline Index(int8_t ind) : index{ ind } {}
+    inline constexpr Index(int8_t ind) : index{ ind } {}
     inline Index(const std::string& name) :
         Index{ '8' - name[0], name[1] - 'a' } {}
-    inline Index(int row, int column) :
+    inline constexpr Index(int row, int column) :
         index{int8_t(((row & 0x7) << 3) + (column & 0x7))} {}
 
 
@@ -50,7 +50,7 @@ struct chessy::Bitboard
     Bitboard        (const Bitboard&)       = default;
     ~Bitboard       (void)                  = default;
 
-    inline Bitboard(U64 bits) : bits{ bits } {}
+    inline constexpr Bitboard(U64 bits) : bits{ bits } {}
     inline static Bitboard fromIndex(Index i) { return U64(1) << i; }
 
     inline void     setBit      (Index i)     { bits |= 1ULL << i.index; }

+ 18 - 17
src/ChessGame.cpp

@@ -56,24 +56,25 @@ void ChessGame::loadFromFen(const std::string& fenString)
     canCastleQueenSideBlack = false;
     canCastleKingSideBlack = false;
 
-    for (auto character : castling) {
-        switch (character) {
-            case 'k':
-                canCastleKingSideWhite = true;
-                break;
-            case 'q':
-                canCastleQueenSideWhite = true;
-                break;
-            case 'K':
-                canCastleKingSideBlack = true;
-                break;
-            case 'Q':
-                canCastleQueenSideBlack = true;
-                break;
-            default:
-                throw runtime_error("invalid castling right: "s + character);
+    if (castling != "-")
+        for (auto character : castling) {
+            switch (character) {
+                case 'k':
+                    canCastleKingSideWhite = true;
+                    break;
+                case 'q':
+                    canCastleQueenSideWhite = true;
+                    break;
+                case 'K':
+                    canCastleKingSideBlack = true;
+                    break;
+                case 'Q':
+                    canCastleQueenSideBlack = true;
+                    break;
+                default:
+                    throw runtime_error("invalid castling right: "s + character);
+            }
         }
-    }
 
     if (enPassant == "-"s) {
         this->enPassant = -1;

+ 50 - 7
src/MoveGeneration.cpp

@@ -3,8 +3,8 @@
 
 using namespace chessy;
 
-template class MoveGenerator<0>;
-template class MoveGenerator<1>;
+template class PawnPushGenerator<WHITE_SIDE>;
+template class PawnPushGenerator<BLACK_SIDE>;
 
 
 std::string chessy::Move::asString(void) const
@@ -12,18 +12,61 @@ std::string chessy::Move::asString(void) const
     return origin.getName() + "-" + destination.getName();
 }
 
-
+#include <iostream>
 template<int side>
-typename MoveGenerator<side>::MoveIterator MoveGenerator<side>::begin(void) const
+typename PawnPushGenerator<side>::MoveIterator PawnPushGenerator<side>::begin(void) const
 {
-    return MoveIterator{ chessGame.getBoard().getWhitePawns() };
+    const Board& board = chessGame.getBoard();
+    Bitboard movedPieces = side == WHITE_SIDE ?
+        board.getWhitePawns() :
+        board.getBlackPawns();
+    if (side == WHITE_SIDE)
+        movedPieces.moveNorthOne();
+    else
+        movedPieces.moveSouthOne();
+    
+    movedPieces &= ~(side == WHITE_SIDE ? board.getBlacks() : board.getWhites());
+
+    std::cout << movedPieces << std::endl;
+    return MoveIterator{ movedPieces };
 }
 
 
 template<int side>
-typename MoveGenerator<side>::MoveIterator chessy::MoveGenerator<side>::end(void) const
+typename PawnPushGenerator<side>::MoveIterator PawnPushGenerator<side>::end(void) const
 {
-    return MoveIterator{ PositionSet::end() };
+    return MoveIterator{ 0 };
 }
 
 
+const std::array<Bitboard, 64> KnightMoveGenerator::moveSets = generateKnightMoves();
+
+Bitboard KnightMoveGenerator::generateFromIndex(Index i) {
+    int row = i.getRow();
+    int column = i.getColumn();
+    Bitboard result = 0;
+    auto makeBitboardIfValid = [](int row, int column) -> Bitboard {
+        return row < 8 && column < 8 && row >= 0 && column >= 0 ?
+            Bitboard::fromIndex({row, column}) : Bitboard{ 0 };
+    };
+    result |= makeBitboardIfValid(row - 2, column - 1);
+    result |= makeBitboardIfValid(row - 1, column - 2);
+    result |= makeBitboardIfValid(row + 2, column - 1);
+    result |= makeBitboardIfValid(row + 1, column - 2);
+    result |= makeBitboardIfValid(row - 2, column + 1);
+    result |= makeBitboardIfValid(row - 1, column + 2);
+    result |= makeBitboardIfValid(row + 2, column + 1);
+    result |= makeBitboardIfValid(row + 1, column + 2);
+    return result;
+}
+
+
+std::array<Bitboard, 64> KnightMoveGenerator::generateKnightMoves(void)
+{
+    std::array<Bitboard, 64> moves{};
+    for (int8_t i = 0; i < moves.size(); i++) {
+        moves[i] = generateFromIndex(Index{ i });
+    }
+    return moves;
+}
+

+ 27 - 6
src/MoveGeneration.h

@@ -3,6 +3,7 @@
 
 #include "BitBoard.h"
 #include <string>
+#include <array>
 
 namespace chessy
 {
@@ -13,8 +14,14 @@ namespace chessy
 
     class PositionSet;
 
+    const int WHITE_SIDE = 0;
+    const int BLACK_SIDE = 1;
+
     template<int side>
-    class MoveGenerator;
+    class PawnPushGenerator;
+
+    class KnightMoveGenerator;
+    class RookMoveGenerator;
 }
 
 
@@ -75,17 +82,16 @@ public:
 
 
 template<int side>
-class chessy::MoveGenerator
+class chessy::PawnPushGenerator
 {
     const ChessGame& chessGame;
-
     struct MoveIterator
     {
         PositionSet::PositionSetIterator pawnPushes;
         inline Move operator *(void) const
         {
             Index pp = *pawnPushes;
-            return Move{ pp, int8_t(pp + (side == 0 ? 8 : -8)) };
+            return Move{ int8_t(pp + (side == BLACK_SIDE ? 8 : -8)), pp };
         }
 
         inline void operator ++(void)
@@ -99,14 +105,29 @@ class chessy::MoveGenerator
         }
     };
 public:
-    inline MoveGenerator(const ChessGame& cg) : chessGame{ cg } {}
+    inline PawnPushGenerator(const ChessGame& cg) : chessGame{ cg } {}
 
     MoveIterator begin(void) const;
     MoveIterator end(void) const;
+};
+
 
-    //PawnPushProducer generatePawnPushes(void) const;
+class chessy::KnightMoveGenerator :
+    public PositionSet
+{
+    static const std::array<Bitboard, 64> moveSets;
+
+public:
+    inline KnightMoveGenerator(Index knight, Bitboard occupied) :
+        PositionSet{ moveSets[knight] & ~occupied } {}
+
+private:
+    static Bitboard generateFromIndex(Index i);
+    static std::array<Bitboard, 64> generateKnightMoves(void);
 };
 
 
+class chessy::
+
 
 #endif // CHESSY_MOVEGENERATION_H

+ 12 - 5
src/main.cpp

@@ -4,18 +4,25 @@
 #include "MoveGeneration.h"
 
 using namespace std;
+using namespace chessy;
 
-auto main() -> int
+auto main(int argc, char** argv) -> int
 {
-    chessy::ChessGame cg;
+    ChessGame cg;
     string line;
     getline(cin, line);
     try {
         cg.loadFromFen(line);
         cout << cg.generateFen() << endl;
-        chessy::MoveGenerator<0> mg{ cg };
-        for (auto pos : mg) {
-            cout << pos.asString() << endl;
+        PawnPushGenerator<BLACK_SIDE> mg{ cg };
+        for (auto push : mg) {
+            cout << "pawn: " << push.asString() << endl;
+        }
+        PositionSet knights = cg.getBoard().getBlackKnights();
+        for (auto knight : knights) {
+            for (auto pos : KnightMoveGenerator{ knight, cg.getBoard().getBlacks() }) {
+                cout << "knight: " << Move(knight, pos).asString() << endl;
+            }
         }
     }
     catch (runtime_error& re) {