Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
6c0054b
Rewrite how the board is stored and moves are made
razvanfilea Nov 20, 2019
1c41cd3
Remove 'ToList' MoveGen template arg, make some fixes
razvanfilea Nov 22, 2019
2bfdff3
Fix a critical error with Board::doMove()
razvanfilea Nov 24, 2019
9db8df9
Fix getPhase always returning ENDGAME
razvanfilea Nov 24, 2019
8fd4e8c
Improve the Evaluation function performance
razvanfilea Nov 24, 2019
bee2ee1
Fix Board::hasValidState and update Pawn PSQT
razvanfilea Nov 26, 2019
68d9853
Switch to the previous Multi Threading model
razvanfilea Nov 28, 2019
7154003
Remove KING_DANGER MoveGen
razvanfilea Nov 28, 2019
eb1963c
Add age attribute to the TranspositionTable
razvanfilea Nov 29, 2019
2da9711
Fix crash when generating legal moves
razvanfilea Nov 30, 2019
f922ceb
Rewrite how the UI processes positions
razvanfilea Nov 30, 2019
220b4d7
Rename NegaMax class to Search
razvanfilea Nov 30, 2019
ee721fd
Work on the ThreadPool
razvanfilea Nov 30, 2019
9a9e5ac
Solve a bug with Castling and disable EnPassant for now
razvanfilea Nov 30, 2019
faba2c2
Add Generated Nodes to Stats
razvanfilea Dec 1, 2019
d73bb5c
Remake the Settings Screen
razvanfilea Dec 1, 2019
9b46c3e
Clean ThreadSafeQueue and ThreadPool
razvanfilea Dec 1, 2019
d5d5ae0
Revert to the old Pawn PSQT
razvanfilea Dec 8, 2019
1b60b38
Re-enable EnPassant
razvanfilea Dec 9, 2019
c0be29b
Add Platform Specific Implementations for BSF and BSR
razvanfilea Dec 10, 2019
8a64bbc
Remove StackVector
razvanfilea Dec 10, 2019
7889cfa
Fix compile errors
razvanfilea Dec 10, 2019
e35ab03
Remake the Pawn Evaluation add Connected Bonus
razvanfilea Dec 11, 2019
459400d
Merge Rays.h into Bitboard.h
razvanfilea Dec 11, 2019
9be2e38
Fix Pawn Move Generation from last commit
razvanfilea Dec 12, 2019
9a37891
Remove Light Theme, add Rook on Queen File Evaluation
razvanfilea Dec 15, 2019
b81a38c
Rewrite Piece class to only use 1 byte
razvanfilea Dec 15, 2019
3a122a9
New icon
razvanfilea Dec 15, 2019
99a93b5
Release 1.0
razvanfilea Dec 15, 2019
b8651a6
Fix issues with the Pull Request
razvanfilea Dec 15, 2019
8c8a8d9
Delete MoveOrdering.h
razvanfilea Dec 15, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix Pawn Move Generation from last commit
  • Loading branch information
razvanfilea committed Dec 12, 2019
commit 9be2e38a4926ee81d33ce647a4317e64cce888f6
2 changes: 2 additions & 0 deletions ChessAndroid/app/src/main/cpp/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,4 +306,6 @@ Java_net_theluckycoder_chess_Native_perft(JNIEnv */*pEnv*/, jclass /*type*/, jin
if (nodesCount != perftResults[i])
LOGE(TAG, "Nodes count do not match at depth %d", i);
}

LOGV(TAG, "Test Finished");
}
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ Score Evaluation::evaluateQueen(const Piece &piece, const byte square, const Boa
Pos dPos(pos, d * ix, d * iy);
if (dPos.isValid())
{
const Piece &other = board[dPos];
const Piece &other = board.getPiece(dPos.toSquare());
if (other.type == ROOK && (ix == 0 || iy == 0) && count == 1) return true;
if (other.type == BISHOP && (ix != 0 && iy != 0) && count == 1) return true;
if (other) count++;
Expand Down
39 changes: 21 additions & 18 deletions ChessAndroid/app/src/main/cpp/chess/algorithm/MoveGen.inl
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@ U64 MoveGen<T>::generatePawnMoves(const Piece &piece, const byte square, const B

if (board.enPassantSq < 64u)
{
Pos capturedPos(board.enPassantSq);
capturedPos.y += static_cast<byte>(piece.color ? -1 : 1);
// Keep the en-passant capture if it intersect with one of our potential attacks
if (attacks & Bitboard::shiftedBoards[capturedPos.toSquare()])
captures |= Bitboard::shiftedBoards[board.enPassantSq];
const U64 enPassant = shiftedBoards[board.enPassantSq];
const U64 capturedPawn = piece.color ? shift<SOUTH>(enPassant) : shift<NORTH>(enPassant);

if (board.getType(~piece.color, PAWN) & capturedPawn)
{
// Keep the en-passant capture if it intersect with one of our potential attacks
captures |= attacks & enPassant;
}
}

attacks = captures;
}
else if (T == ATTACKS_DEFENSES)
else if constexpr (T == ATTACKS_DEFENSES)
attacks &= board.occupied;

if constexpr (T == ALL)
Expand All @@ -42,10 +45,10 @@ U64 MoveGen<T>::generatePawnMoves(const Piece &piece, const byte square, const B
const U64 initialRank = piece.color ? RANK_2 : RANK_7;
if (initialRank & bitboard)
{
const U64 doubleMove = piece.color ? shift<NORTH>(bitboard) : shift<SOUTH>(bitboard);
const U64 doubleMove = piece.color ? shift<NORTH>(move) : shift<SOUTH>(move);

if (!(board.occupied & doubleMove))
attacks |= move;
attacks |= doubleMove;
}
}
}
Expand All @@ -60,9 +63,9 @@ U64 MoveGen<T>::generateKnightMoves(const Piece &piece, const byte square, const

if constexpr (T == ALL)
attacks &= ~board.allPieces[piece.color]; // Remove our pieces
else if (T == CAPTURES)
else if constexpr (T == CAPTURES)
attacks &= board.allPieces[~piece.color]; // Keep only their pieces
else if (T == ATTACKS_DEFENSES)
else if constexpr (T == ATTACKS_DEFENSES)
attacks &= board.occupied; // Keep only the pieces

return attacks;
Expand All @@ -75,9 +78,9 @@ U64 MoveGen<T>::generateBishopMoves(const Piece &piece, const byte square, const

if constexpr (T == ALL)
attacks &= ~board.allPieces[piece.color]; // Remove our pieces
else if (T == CAPTURES)
else if constexpr (T == CAPTURES)
attacks &= board.allPieces[~piece.color]; // Keep only their pieces
else if (T == ATTACKS_DEFENSES)
else if constexpr (T == ATTACKS_DEFENSES)
attacks &= board.occupied; // Keep only the pieces

return attacks;
Expand All @@ -90,9 +93,9 @@ U64 MoveGen<T>::generateRookMoves(const Piece &piece, const byte square, const B

if constexpr (T == ALL)
attacks &= ~board.allPieces[piece.color]; // Remove our pieces
else if (T == CAPTURES)
else if constexpr (T == CAPTURES)
attacks &= board.allPieces[~piece.color]; // Keep only their pieces
else if (T == ATTACKS_DEFENSES)
else if constexpr (T == ATTACKS_DEFENSES)
attacks &= board.occupied; // Keep only the pieces

return attacks;
Expand All @@ -106,9 +109,9 @@ U64 MoveGen<T>::generateQueenMoves(const Piece &piece, const byte square, const

if constexpr (T == ALL)
attacks &= ~board.allPieces[piece.color]; // Remove our pieces
else if (T == CAPTURES)
else if constexpr (T == CAPTURES)
attacks &= board.allPieces[~piece.color]; // Keep only their pieces
else if (T == ATTACKS_DEFENSES)
else if constexpr (T == ATTACKS_DEFENSES)
attacks &= board.occupied; // Keep only the pieces

return attacks;
Expand All @@ -121,9 +124,9 @@ U64 MoveGen<T>::generateKingMoves(const Piece &piece, const byte square, const B

if constexpr (T == ALL)
attacks &= ~board.allPieces[piece.color]; // Remove our pieces
else if (T == CAPTURES)
else if constexpr (T == CAPTURES)
attacks &= board.allPieces[~piece.color]; // Keep only their pieces
else if (T == ATTACKS_DEFENSES)
else if constexpr (T == ATTACKS_DEFENSES)
attacks &= board.occupied; // Keep only the pieces

if constexpr (T == CAPTURES || T == ATTACKS_DEFENSES)
Expand Down
65 changes: 18 additions & 47 deletions ChessAndroid/app/src/main/cpp/chess/algorithm/PieceAttacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ constexpr std::array<U64, 64> rookMagics = {
*/
constexpr auto bishopMasks = [] {
using namespace Bitboard;

const U64 edgeSquares = FILE_A | FILE_H | RANK_1 | RANK_8;
std::array<U64, 64> masks{};
std::array<U64, SQUARE_NB> masks{};

for (byte square = 0u; square < SQUARE_NB; ++square)
{
Expand All @@ -83,7 +83,7 @@ constexpr auto bishopMasks = [] {
constexpr auto rookMasks = [] {
using namespace Bitboard;

std::array<U64, 64> masks{};
std::array<U64, SQUARE_NB> masks{};

for (byte square = 0u; square < 64u; ++square)
{
Expand Down Expand Up @@ -129,7 +129,6 @@ U64 getRayAttacksBackwards(const byte square, const U64 occupied, const Dir dire

U64 generateBishopAttacks(const byte square, const U64 blockers) noexcept
{
using namespace Bitboard;
return getRayAttacksForwards(square, blockers, NORTH_WEST)
| getRayAttacksForwards(square, blockers, NORTH_EAST)
| getRayAttacksBackwards(square, blockers, SOUTH_EAST)
Expand All @@ -138,44 +137,23 @@ U64 generateBishopAttacks(const byte square, const U64 blockers) noexcept

U64 generateRookAttacks(const byte square, const U64 blockers) noexcept
{
using namespace Bitboard;
return getRayAttacksForwards(square, blockers, NORTH)
| getRayAttacksForwards(square, blockers, EAST)
| getRayAttacksBackwards(square, blockers, SOUTH)
| getRayAttacksBackwards(square, blockers, WEST);
}

const std::array<std::array<U64, 64>, 2> PieceAttacks::s_PawnAttacks = [] {
using namespace Bitboard;
std::array<std::array<U64, 64>, 2> moves{};

for (byte i = 0u; i < 64u; i++)
for (byte i = 0u; i < SQUARE_NB; i++)
{
const Pos start(i);

U64 whiteAttackBb{};
{
const Pos leftPos = start + Pos(-1, 1u);
const Pos rightPos = start + Pos(1u, 1u);

if (leftPos.isValid())
whiteAttackBb |= leftPos.toBitboard();
if (rightPos.isValid())
whiteAttackBb |= rightPos.toBitboard();
}

U64 blackAttackBb{};
{
const Pos leftPos = start + Pos(-1, -1);
const Pos rightPos = start + Pos(1u, -1);

if (leftPos.isValid())
blackAttackBb |= leftPos.toBitboard();
if (rightPos.isValid())
blackAttackBb |= rightPos.toBitboard();
}
const U64 bb = shiftedBoards[i];
const U64 attacks = shift<EAST>(bb) | shift<WEST>(bb);

moves[true][i] = whiteAttackBb;
moves[false][i] = blackAttackBb;
moves[true][i] = shift<NORTH>(attacks);
moves[false][i] = shift<SOUTH>(attacks);
}

return moves;
Expand All @@ -191,7 +169,7 @@ const std::array<U64, 64> PieceAttacks::s_KnightAttacks = [] {
moves[startSquare] |= pos.toBitboard();
};

for (byte i = 0u; i < 64u; i++)
for (byte i = 0u; i < SQUARE_NB; i++)
{
addAttack(i, -2, -1);
addAttack(i, -2, 1u);
Expand All @@ -214,28 +192,21 @@ std::array<std::array<U64, 1024>, SQUARE_NB> PieceAttacks::s_BishopAttacks{};
std::array<std::array<U64, 4096>, SQUARE_NB> PieceAttacks::s_RookAttacks{};

const std::array<U64, SQUARE_NB> PieceAttacks::s_KingAttacks = [] {
std::array<U64, SQUARE_NB> moves{};

const auto addAttack = [&](const byte startSquare, const byte x, const byte y) {
const Pos pos(col(startSquare) + x, row(startSquare) + y);
using namespace Bitboard;

if (pos.isValid())
moves[startSquare] |= pos.toBitboard();
};
std::array<U64, SQUARE_NB> moves{};

for (byte i = 0u; i < SQUARE_NB; i++)
{
const U64 bb = shiftedBoards[i];

// Vertical and Horizontal
addAttack(i, -1, 0u);
addAttack(i, 1u, 0u);
addAttack(i, 0u, -1);
addAttack(i, 0u, 1u);
U64 attacks = shift<NORTH>(bb) | shift<SOUTH>(bb) | shift<EAST>(bb) | shift<WEST>(bb);

// Diagonals
addAttack(i, 1u, -1);
addAttack(i, 1u, 1u);
addAttack(i, -1, -1);
addAttack(i, -1, 1u);
attacks |= shift<NORTH_EAST>(bb) | shift<NORTH_WEST>(bb) | shift<SOUTH_EAST>(bb) | shift<SOUTH_WEST>(bb);

moves[i] = attacks;
}

return moves;
Expand Down
15 changes: 12 additions & 3 deletions ChessAndroid/app/src/main/cpp/chess/data/Bitboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,13 +254,22 @@ namespace Bitboard
{
if constexpr (D == NORTH)
return bb << 8u;
else if (D == SOUTH)
else if constexpr (D == SOUTH)
return bb >> 8u;
else if (D == EAST)
else if constexpr (D == EAST)
return (bb & ~FILE_H) << 1u;
else if (D == WEST)
else if constexpr (D == WEST)
return (bb & ~FILE_A) >> 1u;

else if constexpr (D == NORTH_EAST)
return (bb & ~FILE_H) << 9u;
else if constexpr (D == NORTH_WEST)
return (bb & ~FILE_A) << 7u;
else if constexpr (D == SOUTH_EAST)
return (bb & ~FILE_H) >> 7u;
else if constexpr (D == SOUTH_WEST)
return (bb & ~FILE_A) >> 9u;

return {};
}

Expand Down
37 changes: 10 additions & 27 deletions ChessAndroid/app/src/main/cpp/chess/data/Board.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,6 @@ U64 Board::getType(const Color color, const PieceType type) const noexcept
return pieces[color][type];
}

Piece &Board::operator[](const Pos &pos) noexcept
{
return data[pos.toSquare()];
}

const Piece &Board::operator[](const Pos &pos) const noexcept
{
return data[pos.toSquare()];
}

bool Board::operator<(const Board &other) const noexcept
{
return score < other.score;
Expand Down Expand Up @@ -256,7 +246,7 @@ std::vector<Board> Board::listQuiescenceMoves() const
return moves;
}

bool Board::movePawn(const byte startSq, const byte destSq)
void Board::movePawn(const byte startSq, const byte destSq)
{
Piece &pawn = getPiece(startSq);

Expand All @@ -272,25 +262,20 @@ bool Board::movePawn(const byte startSq, const byte destSq)

getType(pawn.color, PieceType::PAWN) &= ~destBb;
getType(pawn.color, newPieceType) |= destBb;
return true;
}

if (enPassantSq < 64u)
if (enPassantSq < 64u && destSq == enPassantSq)
{
if (destSq == enPassantSq)
{
isCapture = true;
isCapture = true;

Pos capturedPos(enPassantSq);
capturedPos.y += static_cast<byte>(pawn.color ? -1 : 1);
Piece &capturedPiece = getPiece(capturedPos.toSquare());
Pos capturedPos(enPassantSq);
capturedPos.y += static_cast<byte>(pawn.color ? -1 : 1);
Piece &capturedPiece = getPiece(capturedPos.toSquare());

// Remove the captured Pawn
Hash::xorPiece(zKey, capturedPos.toSquare(), capturedPiece);
getType(capturedPiece.color, capturedPiece.type) &= ~capturedPos.toBitboard();
capturedPiece = Piece();
return true;
}
// Remove the captured Pawn
Hash::xorPiece(zKey, capturedPos.toSquare(), capturedPiece);
getType(capturedPiece.color, capturedPiece.type) &= ~capturedPos.toBitboard();
capturedPiece = Piece();
}

enPassantSq = 64u;
Expand All @@ -302,8 +287,6 @@ bool Board::movePawn(const byte startSq, const byte destSq)
newEnPassant.y -= static_cast<byte>(distance / 2);
enPassantSq = newEnPassant.toSquare();
}

return false;
}

void Board::moveRook(const byte startSq)
Expand Down
5 changes: 1 addition & 4 deletions ChessAndroid/app/src/main/cpp/chess/data/Board.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ class Board final
Board &operator=(Board&&) noexcept = default;
Board &operator=(const Board &other) = default;

Piece &operator[](const Pos &pos) noexcept;
const Piece &operator[](const Pos &pos) const noexcept;

bool operator<(const Board &other) const noexcept;
bool operator>(const Board &other) const noexcept;

Expand Down Expand Up @@ -73,7 +70,7 @@ class Board final
std::vector<Board> listQuiescenceMoves() const;

private:
bool movePawn(byte startSq, byte destSq);
void movePawn(byte startSq, byte destSq);
void moveRook(byte startSq);
void moveKing(const Piece &king, byte startSq, byte destSq);

Expand Down