|
@@ -147,7 +147,7 @@ std::pair<Move, MoveValue> chessy::miniMax(ChessGame& cg, int depth)
|
|
|
lastValidMove = move;
|
|
|
val = -negamaxImplementation(cg, depth - 1, -beta, -alpha);
|
|
|
}
|
|
|
- //cout << move.asString() << ": " << val << endl;
|
|
|
+ cout << move.asString() << ": " << val << endl;
|
|
|
cg.undoMove(ui);
|
|
|
if(val > alpha) {
|
|
|
alpha = val;
|
|
@@ -164,9 +164,10 @@ std::pair<Move, MoveValue> chessy::miniMax(ChessGame& cg, int depth)
|
|
|
MoveValue chessy::negamaxImplementation(ChessGame& cg, int depth,
|
|
|
chessy::MoveValue alpha, chessy::MoveValue beta)
|
|
|
{
|
|
|
+ float x;
|
|
|
if (depth <= 0)
|
|
|
- //return quiescence(cg, 2, -beta, -alpha);
|
|
|
- return evaluate(cg.getTurn(), cg);
|
|
|
+ return x = quiescence(cg, 8, -beta, -alpha);
|
|
|
+ //return evaluate(cg);
|
|
|
|
|
|
const Board& b = cg.getBoard();
|
|
|
auto isCheck = [&cg, &b] (Side turn) {
|
|
@@ -175,7 +176,7 @@ MoveValue chessy::negamaxImplementation(ChessGame& cg, int depth,
|
|
|
};
|
|
|
|
|
|
std::vector<Move> moves;
|
|
|
- moves.reserve(200);
|
|
|
+ moves.reserve(80);
|
|
|
if (cg.getTurn() == WHITE_SIDE) {
|
|
|
generateAllMoves<WHITE_SIDE, false>(cg, moves);
|
|
|
orderMoves<WHITE_SIDE>(cg, moves);
|
|
@@ -209,10 +210,18 @@ MoveValue chessy::negamaxImplementation(ChessGame& cg, int depth,
|
|
|
|
|
|
|
|
|
MoveValue chessy::quiescence(ChessGame& cg, int maxDepth,
|
|
|
- MoveValue alpha, MoveValue beta)
|
|
|
+ MoveValue alpha, MoveValue beta)
|
|
|
{
|
|
|
+ MoveValue standingPat = evaluate(cg);
|
|
|
+ if (standingPat == 0.0f)
|
|
|
+ int s = 23;
|
|
|
if (maxDepth <= 0)
|
|
|
- return evaluate(cg.getTurn(), cg);
|
|
|
+ return standingPat;
|
|
|
+
|
|
|
+ if(standingPat >= beta)
|
|
|
+ return beta;
|
|
|
+ if(standingPat > alpha)
|
|
|
+ alpha = standingPat;
|
|
|
|
|
|
const Board& b = cg.getBoard();
|
|
|
auto isCheck = [&cg, &b] (Side turn) {
|
|
@@ -222,10 +231,14 @@ MoveValue chessy::quiescence(ChessGame& cg, int maxDepth,
|
|
|
|
|
|
std::vector<Move> moves;
|
|
|
moves.reserve(50);
|
|
|
- if (cg.getTurn() == WHITE_SIDE)
|
|
|
+ if (cg.getTurn() == WHITE_SIDE) {
|
|
|
generateAllMoves<WHITE_SIDE, true>(cg, moves);
|
|
|
- else
|
|
|
+ orderMoves<WHITE_SIDE>(cg, moves);
|
|
|
+ }
|
|
|
+ else {
|
|
|
generateAllMoves<BLACK_SIDE, true>(cg, moves);
|
|
|
+ orderMoves<BLACK_SIDE>(cg, moves);
|
|
|
+ }
|
|
|
|
|
|
bool thereIsMove = false;
|
|
|
for (Move move : moves) {
|
|
@@ -248,66 +261,60 @@ MoveValue chessy::quiescence(ChessGame& cg, int maxDepth,
|
|
|
return isCheck(otherSide(cg.getTurn())) ? -1e+30 : 0.0;
|
|
|
return alpha;
|
|
|
}
|
|
|
+/*
|
|
|
+MoveValue chessy::quiescence(ChessGame& cg, int maxDepth,
|
|
|
+ MoveValue alpha, MoveValue beta)
|
|
|
+{
|
|
|
+ MoveValue standingPat = evaluate(cg);
|
|
|
+ if (maxDepth <= 0)
|
|
|
+ return standingPat;
|
|
|
|
|
|
+ if (beta <= standingPat)
|
|
|
+ return beta;
|
|
|
+ if (alpha < standingPat)
|
|
|
+ alpha = standingPat;
|
|
|
|
|
|
-template<Side side>
|
|
|
-MoveValue chessy::evaluatePositives(const ChessGame& game)
|
|
|
-{
|
|
|
- MoveValue piecePoints = 0;
|
|
|
- const Board& bd = game.getBoard();
|
|
|
- Bitboard p = bd.getPawns<side>();
|
|
|
- Bitboard n = bd.getKnights<side>();
|
|
|
- Bitboard b = bd.getBishops<side>();
|
|
|
- Bitboard r = bd.getRooks<side>();
|
|
|
- Bitboard q = bd.getQueens<side>();
|
|
|
- Bitboard k = bd.getKing<side>();
|
|
|
- piecePoints += 1 * p.popcount();
|
|
|
- piecePoints += 3 * n.popcount();
|
|
|
- piecePoints += 3 * b.popcount();
|
|
|
- piecePoints += 5 * r.popcount();
|
|
|
- piecePoints += 9 * q.popcount();
|
|
|
-
|
|
|
- for (auto knight : PositionSet{ n })
|
|
|
- piecePoints += KnightMoveGenerator{ knight, bd.get<side>() }.getBitboard().popcount() * 0.05;
|
|
|
- for (auto bishop : PositionSet{ b })
|
|
|
- piecePoints += PrimitiveBishopMoveGenerator{ bishop, bd.get<otherSide(side)>(), bd.get<side>() }.getBitboard().popcount() * 0.03;
|
|
|
- for (auto rook : PositionSet{ r })
|
|
|
- piecePoints += PrimitiveRookMoveGenerator{ rook, bd.get<otherSide(side)>(), bd.get<side>() }.getBitboard().popcount() * 0.03;
|
|
|
- for (auto queen : PositionSet{ q })
|
|
|
- piecePoints += PrimitiveQueenMoveGenerator{ queen, bd.get<otherSide(side)>(), bd.get<side>() }.getBitboard().popcount() * 0.02;
|
|
|
+ const Board& b = cg.getBoard();
|
|
|
+ auto isCheck = [&cg, &b] (Side turn) {
|
|
|
+ return turn == BLACK_SIDE ? b.isCheck<WHITE_SIDE>() :
|
|
|
+ b.isCheck<BLACK_SIDE>();
|
|
|
+ };
|
|
|
|
|
|
- return piecePoints;
|
|
|
- /*
|
|
|
- constexpr Side other = otherSide(side);
|
|
|
- p = bd.getPawns<other>();
|
|
|
- n = bd.getKnights<other>();
|
|
|
- b = bd.getBishops<other>();
|
|
|
- r = bd.getRooks<other>();
|
|
|
- q = bd.getQueens<other>();
|
|
|
- k = bd.getKing<other>();
|
|
|
- piecePoints -= 1 * p.popcount();
|
|
|
- piecePoints -= 3 * n.popcount();
|
|
|
- piecePoints -= 3 * b.popcount();
|
|
|
- piecePoints -= 5 * r.popcount();
|
|
|
- piecePoints -= 9 * q.popcount();
|
|
|
-
|
|
|
- //for (auto knight : PositionSet{ n })
|
|
|
- // piecePoints -= KnightMoveGenerator{ knight, bd.get<otherSide(side)>() }.getBitboard().popcount() * 0.2;
|
|
|
- for (auto bishop : PositionSet{ b })
|
|
|
- piecePoints -= PrimitiveBishopMoveGenerator{ bishop, bd.get<side>(), bd.get<otherSide(side)>() }.getBitboard().popcount() * 0.2;
|
|
|
- */
|
|
|
-}
|
|
|
+ std::vector<Move> moves;
|
|
|
+ moves.reserve(50);
|
|
|
+ if (cg.getTurn() == WHITE_SIDE) {
|
|
|
+ generateAllMoves<WHITE_SIDE, true>(cg, moves);
|
|
|
+ orderMoves<WHITE_SIDE>(cg, moves);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ generateAllMoves<BLACK_SIDE, true>(cg, moves);
|
|
|
+ orderMoves<BLACK_SIDE>(cg, moves);
|
|
|
+ }
|
|
|
|
|
|
+ bool thereIsMove = false;
|
|
|
+ for (Move move : moves) {
|
|
|
+ MoveInfo mi{ move, cg };
|
|
|
+ UndoInfo ui = cg.doMove(mi);
|
|
|
+ MoveValue val;
|
|
|
+ if (isCheck(cg.getTurn()))
|
|
|
+ val = -1e+30;
|
|
|
+ else {
|
|
|
+ val = -quiescence(cg, maxDepth - 1, -beta, -alpha);
|
|
|
+ if (val == 0.0f)
|
|
|
+ int s = 23;
|
|
|
+ thereIsMove = true;
|
|
|
+ }
|
|
|
+ cg.undoMove(ui);
|
|
|
+ if(val >= beta)
|
|
|
+ return beta;
|
|
|
+ if(val > alpha)
|
|
|
+ alpha = val;
|
|
|
+ }
|
|
|
+ if (!thereIsMove)
|
|
|
+ return isCheck(otherSide(cg.getTurn())) ? -1e+30 : 0.0;
|
|
|
+ return alpha;
|
|
|
+}*/
|
|
|
|
|
|
-MoveValue chessy::evaluate(Side side, const ChessGame& game)
|
|
|
-{
|
|
|
- if (side == WHITE_SIDE)
|
|
|
- return evaluatePositives<WHITE_SIDE>(game) -
|
|
|
- evaluatePositives<BLACK_SIDE>(game);
|
|
|
- else
|
|
|
- return evaluatePositives<BLACK_SIDE>(game) -
|
|
|
- evaluatePositives<WHITE_SIDE>(game);
|
|
|
-}
|
|
|
|
|
|
|
|
|
/*
|