nicolaswinkler пре 7 година
родитељ
комит
3d5e272c35
5 измењених фајлова са 89 додато и 23 уклоњено
  1. 8 8
      src/BitBoard.h
  2. 53 0
      src/Board.cpp
  3. 2 1
      src/Board.h
  4. 26 13
      src/Minimax.cpp
  5. 0 1
      src/MoveGeneration.cpp

+ 8 - 8
src/BitBoard.h

@@ -163,21 +163,21 @@ struct chessy::Bitboard
     inline void     moveSouth   (int dist)  { bits >>= (8 * dist); }
     inline Bitboard south       (int dist)  { return bits >> (8 * dist); }
     inline void     moveNorthOne(void)      { bits <<= 8; }
-    inline Bitboard northOne    (void)      { return bits << 8; }
+    inline Bitboard northOne    (void) const{ return bits << 8; }
     inline void     moveSouthOne(void)      { bits >>= 8; }
-    inline Bitboard southOne    (void)      { return bits >> 8; }
+    inline Bitboard southOne    (void) const{ return bits >> 8; }
     inline void     moveEastOne (void)      { bits = (bits & ~hColumn) >> 1; }
-    inline Bitboard eastOne     (void)      { return (bits & ~hColumn) >> 1; }
+    inline Bitboard eastOne     (void) const{ return (bits & ~hColumn) >> 1; }
     inline void     moveWestOne (void)      { bits = (bits & ~aColumn) << 1; }
-    inline Bitboard westOne     (void)      { return (bits & ~aColumn) << 1; }
+    inline Bitboard westOne     (void) const{ return (bits & ~aColumn) << 1; }
     inline void     moveNWOne   (void)      { bits = (bits << 7) & ~aColumn; }
-    inline Bitboard nwOne       (void)      { return (bits << 7) & ~aColumn; }
+    inline Bitboard nwOne       (void) const{ return (bits << 7) & ~aColumn; }
     inline void     moveNEOne   (void)      { bits = (bits << 9) & ~hColumn; }
-    inline Bitboard neOne       (void)      { return (bits << 9) & ~hColumn; }
+    inline Bitboard neOne       (void) const{ return (bits << 9) & ~hColumn; }
     inline void     moveSWOne   (void)      { bits = (bits >> 9) & ~aColumn; }
-    inline Bitboard swOne       (void)      { return (bits >> 9) & ~aColumn; }
+    inline Bitboard swOne       (void) const{ return (bits >> 9) & ~aColumn; }
     inline void     moveSEOne   (void)      { bits = (bits >> 7) & ~hColumn; }
-    inline Bitboard seOne       (void)      { return (bits >> 7) & ~hColumn; }
+    inline Bitboard seOne       (void) const{ return (bits >> 7) & ~hColumn; }
 
     inline static Bitboard getColumn(int index)
     {

+ 53 - 0
src/Board.cpp

@@ -5,6 +5,8 @@
 #include <stdexcept>
 #include <sstream>
 
+#include "MoveGeneration.h"
+
 using namespace chessy;
 using namespace std;
 
@@ -241,3 +243,54 @@ Bitboard Board::getFree(void) const
 {
     return ~getOccupied();
 }
+
+
+#include <iostream>
+template<Side side>
+bool Board::isCheck(void) const
+{
+    constexpr Side enemy = otherSide(side);
+    Index kingIndex = getKing<side>().getLeastSignificantBit();
+    KnightMoveGenerator nmg{ kingIndex, 0 };
+    if (nmg.getBitboard() & getKnights<enemy>())
+        return true;
+
+    PrimitiveBishopMoveGenerator pbmg{ kingIndex, get<enemy>(), get<side>() };
+    if (pbmg.getBitboard() & (getBishops<enemy>() | getQueens<enemy>()))
+        return true;
+
+    PrimitiveRookMoveGenerator prmg{ kingIndex, get<enemy>(), get<side>() };
+    if (prmg.getBitboard() & (getRooks<enemy>() | getQueens<enemy>()))
+        return true;
+
+    if (side == WHITE_SIDE) {
+        if (kingIndex.getRow() < 6) {
+            if (kingIndex.getColumn() > 0)
+                if (getKing<side>().neOne() & getPawns<enemy>())
+                    return true;
+            if (kingIndex.getColumn() < 7)
+                if (getKing<side>().nwOne() & getPawns<enemy>())
+                    return true;
+        }
+    }
+    else {
+        if (kingIndex.getRow() > 1) {
+            if (kingIndex.getColumn() > 0)
+                if (getKing<side>().seOne() & getPawns<enemy>())
+                    return true;
+            if (kingIndex.getColumn() < 7)
+                if (getKing<side>().swOne() & getPawns<enemy>())
+                    return true;
+        }
+    }
+
+    KingMoveGenerator kmg{ getKing<side>(), 0 };
+    if (kmg.getBitboard() & getKing<enemy>())
+        return true;
+
+    return false;
+}
+
+template bool Board::isCheck<WHITE_SIDE>(void) const;
+template bool Board::isCheck<BLACK_SIDE>(void) const;
+

+ 2 - 1
src/Board.h

@@ -138,7 +138,8 @@ public:
      */
     Bitboard getFree(void) const;
 
-    
+    template<Side side>
+    bool isCheck(void) const;
 };
 
 #endif // CHESSY_BOARD_H

+ 26 - 13
src/Minimax.cpp

@@ -74,14 +74,27 @@ std::pair<Move, MoveValue> chessy::miniMax(ChessGame& cg, int depth)
         generateAllMoves<WHITE_SIDE>(cg, moves);
     else
         generateAllMoves<BLACK_SIDE>(cg, moves);
+
+    const Board& b = cg.getBoard();
+    auto isCheck = [&cg, &b] () {
+        return cg.getTurn() == BLACK_SIDE ? b.isCheck<WHITE_SIDE>() :
+            b.isCheck<BLACK_SIDE>();
+    };
+
     Move bestMove{ 0, 0 };
-    //MoveValue best = -1e+30;
     MoveValue alpha = -1e+30;
     MoveValue beta = 1e+30;
     for (Move move : moves) {
         MoveInfo mi{ move, cg };
         UndoInfo ui = cg.doMove(mi);
-        MoveValue val = -negamaxImplementation(cg,  depth - 1, -beta, -alpha);
+        MoveValue val;
+        if (isCheck()) {
+            cg.undoMove(ui);
+            continue;
+        }
+        else {
+            val = -negamaxImplementation(cg,  depth - 1, -beta, -alpha);
+        }
         //cout << move.asString() << ": " << val << ", " << best << ((val > best) ? " good" : " bad") << endl;
         //MoveValue val = 0.0;
         cg.undoMove(ui);
@@ -104,26 +117,26 @@ MoveValue chessy::negamaxImplementation(ChessGame& cg, int depth,
             return evaluate<BLACK_SIDE>(cg);
     }
 
+    const Board& b = cg.getBoard();
+    auto isCheck = [&cg, &b] () {
+        return cg.getTurn() == BLACK_SIDE ? b.isCheck<WHITE_SIDE>() :
+            b.isCheck<BLACK_SIDE>();
+    };
+
     std::vector<Move> moves;
     if (cg.getTurn() == WHITE_SIDE)
         generateAllMoves<WHITE_SIDE>(cg, moves);
     else
         generateAllMoves<BLACK_SIDE>(cg, moves);
 
-    const Board& b = cg.getBoard();
     for (Move move : moves) {
         MoveInfo mi{ move, cg };
         UndoInfo ui = cg.doMove(mi);
-        /*Index king = b.getKing<side>().getLeastSignificantBit();
-        if((KnightMoveGenerator{ king }.getBitboard() &
-                b.getKnights<otherSide(side)>()) ||
-                (PrimitiveBishopMoveGenerator{ king, b.get<otherSide(side)>(),
-                b.get<side>() }.getBitboard() & (b.getBishops<otherSide(side)>() |
-                    b.getQueens<otherSide(side)>())) ||
-                PrimitiveRookMoveGenerator{ king, b.get<otherSide(side)>(),
-                b.get<side>() }.getBitboard() & (b.getRooks<otherSide(side)>() |
-                    b.getQueens<otherSide(side)>()))*/
-        MoveValue val = -negamaxImplementation(cg, depth - 1, -beta, -alpha);
+        MoveValue val;
+        if (isCheck())
+            val = -1e+30;
+        else
+            val = -negamaxImplementation(cg, depth - 1, -beta, -alpha);
         cg.undoMove(ui);
         if(val >= beta)
             return beta;

+ 0 - 1
src/MoveGeneration.cpp

@@ -274,7 +274,6 @@ void chessy::generatePawnPromotions(const ChessGame& cg, std::vector<Move>& move
     PromotionGenerator<side> pg{ cg };
     for (const auto& move : pg)
         moves.push_back(move);
-
 }