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
Add Platform Specific Implementations for BSF and BSR
BitScanForward and BitScanReverse
  • Loading branch information
razvanfilea committed Dec 10, 2019
commit c0be29b0a3c5e8b826e05dc316b0b59056ca4bbf
10 changes: 5 additions & 5 deletions ChessAndroid/app/src/main/cpp/chess/algorithm/Evaluation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,19 +192,19 @@ Score Evaluation::evaluatePawn(const Piece &piece, const byte square, const Boar

const Color color = toColor(piece.isWhite);
const byte behind = color ? -1 : 1;
const int supported = board.at(pos.x - 1u, pos.y + behind).isSameType(piece)
+ board.at(pos.x + 1u, pos.y + behind).isSameType(piece);
const int supported = int(piece == board.at(pos.x - 1u, pos.y + behind))
+ int(piece == board.at(pos.x + 1u, pos.y + behind));

bool isolated = !static_cast<bool>(supported);

if (board.getPiece(pos.x, pos.y + behind).isSameType(piece))
if (piece == board.getPiece(pos.x, pos.y + behind))
value -= PAWN_DOUBLED;

if (isolated)
{
for (byte y = 0u ; y < 8u; y++) {
if (board.at(pos.x - 1u, y).isSameType(piece) ||
board.at(pos.x + 1u, y).isSameType(piece))
if (piece == board.at(pos.x - 1u, y) ||
piece == board.at(pos.x + 1u, y))
{
isolated = false;
break;
Expand Down
10 changes: 5 additions & 5 deletions ChessAndroid/app/src/main/cpp/chess/algorithm/PieceAttacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ constexpr auto rookMasks = [] {
return masks;
}();

constexpr U64 getBlockersFromIndex(const int index, U64 mask)
U64 getBlockersFromIndex(const int index, U64 mask)
{
U64 blockers{};
const int bits = Bitboard::popCount(mask);
Expand All @@ -108,23 +108,23 @@ constexpr U64 getBlockersFromIndex(const int index, U64 mask)
return blockers;
}

constexpr U64 getRayAttacksForwards(const byte square, const U64 occupied, const Rays::Dir direction)
U64 getRayAttacksForwards(const byte square, const U64 occupied, const Rays::Dir direction)
{
const U64 attacks = Rays::getRay(direction, square);
const U64 blocker = attacks & occupied;
const byte index = Bitboard::bitScanForward(blocker | 0x8000000000000000);
return attacks ^ Rays::getRay(direction, index);
}

constexpr U64 getRayAttacksBackwards(const byte square, const U64 occupied, const Rays::Dir direction)
U64 getRayAttacksBackwards(const byte square, const U64 occupied, const Rays::Dir direction)
{
const U64 attacks = Rays::getRay(direction, square);
const U64 blocker = attacks & occupied;
const byte index = Bitboard::bitScanReverse(blocker | 1ULL);
return attacks ^ Rays::getRay(direction, index);
}

constexpr U64 generateBishopAttacks(const byte square, const U64 blockers) noexcept
U64 generateBishopAttacks(const byte square, const U64 blockers) noexcept
{
U64 attacks{};

Expand All @@ -136,7 +136,7 @@ constexpr U64 generateBishopAttacks(const byte square, const U64 blockers) noexc
return attacks;
}

constexpr U64 generateRookAttacks(const byte square, const U64 blockers) noexcept
U64 generateRookAttacks(const byte square, const U64 blockers) noexcept
{
U64 attacks{};

Expand Down
27 changes: 8 additions & 19 deletions ChessAndroid/app/src/main/cpp/chess/algorithm/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ bool Player::onlyKingsLeft(const Board &board)

bool Player::hasNoValidMoves(const Color color, const Board &board)
{
const auto pieces = getAllOwnedPieces(color, board);

for (const auto &pair : pieces)
for (byte startSq = 0u; startSq < SQUARE_NB; ++startSq)
{
const byte startSq = pair.first;
const Piece &selectedPiece = pair.second;
U64 possibleMoves = selectedPiece.getPossibleMoves(startSq, board);
const Piece &attacker = board.getPiece(startSq);
if (attacker.type == NO_PIECE_TYPE || attacker.isWhite != board.colorToMove)
continue;

U64 possibleMoves = attacker.getPossibleMoves(startSq, board);

while (possibleMoves)
{
Expand Down Expand Up @@ -74,22 +74,11 @@ bool Player::isInCheck(const Color color, const Board &board)
return isAttacked(oppositeColor(color), Bitboard::bitScanForward(king), board);
}

StackVector<std::pair<byte, Piece>, 32> Player::getAllOwnedPieces(const Color color, const Board &board)
{
StackVector<std::pair<byte, Piece>, 32> pieces;

for (byte sq = 0u; sq < 64u; ++sq)
if (const Piece &piece = board.getPiece(sq); piece && piece.isWhite == color)
pieces.emplace_back(sq, piece);

return pieces;
}

AttacksMap Player::getAttacksPerColor(const bool white, const Board &board)
{
AttacksMap attacks{};

for (byte startSq = 0; startSq < 64u; ++startSq)
for (byte startSq = 0u; startSq < SQUARE_NB; ++startSq)
{
const Piece &piece = board.getPiece(startSq);
if (piece && piece.isWhite == white)
Expand Down Expand Up @@ -117,7 +106,7 @@ AttacksMap Player::getAttacksPerColor(const bool white, const Board &board)
case PieceType::KING:
moves = Generator::generateKingMoves(piece, startSq, board);
break;
case PieceType::NONE:
default:
break;
}

Expand Down
3 changes: 1 addition & 2 deletions ChessAndroid/app/src/main/cpp/chess/algorithm/Player.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#include "../containers/Containers.h"
#include "Defs.h"
#include "../data/Defs.h"
#include "../data/Pos.h"

class Piece;
Expand All @@ -18,6 +18,5 @@ class Player
static bool onlyKingsLeft(const Board &board);
static bool hasNoValidMoves(Color color, const Board &board);
static bool isInCheck(Color color, const Board &board);
static StackVector<std::pair<byte, Piece>, 32> getAllOwnedPieces(Color color, const Board &board);
static AttacksMap getAttacksPerColor(bool white, const Board &board);
};
108 changes: 81 additions & 27 deletions ChessAndroid/app/src/main/cpp/chess/data/Bitboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,9 @@

#include "Defs.h"

constexpr byte row(const byte pos) noexcept { return static_cast<byte>(pos / 8u); }

constexpr byte col(const byte pos) noexcept { return static_cast<byte>(pos % 8u); }

constexpr byte toSquare(const byte x, const byte y) noexcept
{
return static_cast<byte>((y << 3u) + x);
}
#ifdef _MSC_VER
# include <intrin.h> // Microsoft header for _BitScanForward64()
#endif

namespace Bitboard
{
Expand All @@ -35,23 +30,81 @@ namespace Bitboard
/**
* Table of precalculated shifted bitboards indexed by the times 1 has been shifted to the left
*/
constexpr std::array<U64, 64> shiftedBoards = [] {
std::array<U64, 64> array{};
constexpr std::array<U64, 64> shiftedBoards = []
{
std::array<U64, 64> array{};

for (auto i = 0u; i < 64u; ++i)
array[i] = 1ULL << i;

return array;
}();

#if defined(__GNUC__) // GCC, Clang

inline byte bitScanForward(const U64 bb) noexcept
{
assert(bb);
return static_cast<byte>(__builtin_ctzll(bb));
}

inline byte bitScanReverse(U64 bb) noexcept
{
assert(bb);
return static_cast<byte>(63 ^ __builtin_clzll(bb));
}

#elif defined(_MSC_VER)

inline byte bitScanForward(const U64 bb) noexcept
{
assert(bb);
unsigned long index{};

# ifdef _WIN64 // 64-bit
_BitScanForward64(&index, bb);
return static_cast<byte>(index);
# else // 32-bit
if (bb & 0xffffffff) // If the bit is in the lower 32 bits
{
_BitScanForward(&index, static_cast<unsigned long>(bb));
return static_cast<byte>(index);
}

_BitScanForward(&index, static_cast<unsigned long>(bb >> 32));
return static_cast<byte>(index + 32u); // The bit is in the upper 32 bits
# endif
}

inline byte bitScanReverse(const U64 bb) noexcept
{
assert(bb);
unsigned long index{};

for (auto i = 0u; i < 64u; ++i)
array[i] = 1ULL << i;
# ifdef _WIN64 // 64-bit
_BitScanReverse64(&index, bb);
return static_cast<byte>(index);
# else // 32-bit
if (bb >> 32u) // If the bit is in the upper 32 bits
{
_BitScanReverse(&index, static_cast<unsigned long>(bb >> 32u));
return static_cast<byte>(index + 32u);
}

_BitScanReverse(&index, static_cast<unsigned long>(bb));
return static_cast<byte>(index);
# endif
}

return array;
}();
#else

/**
* bitScanForward
* @author Kim Walisch (2012)
* @param bb bitboard to scan
* @precondition bb != 0
* @return index (0..63) of least significant one bit
*/
constexpr byte bitScanForward(const U64 bb) noexcept
inline byte bitScanForward(const U64 bb) noexcept
{
assert(bb);

Expand All @@ -71,15 +124,14 @@ namespace Bitboard
}

/**
* bitScanReverse
* @authors Kim Walisch, Mark Dickinson
* @param bb bitboard to scan
* @precondition bb != 0
* @return index (0..63) of most significant one bit
*/
constexpr byte bitScanReverse(U64 bb) noexcept
inline byte bitScanReverse(U64 bb) noexcept
{
assert (bb != 0);
assert(bb);

constexpr U64 debruijn64{ 0x03f79d71b4cb0a89 };
constexpr byte index64[64] = {
Expand All @@ -103,7 +155,9 @@ namespace Bitboard
return index64[(bb * debruijn64) >> 58];
}

constexpr byte popLsb(U64 &bb) noexcept
#endif

inline byte popLsb(U64 &bb) noexcept
{
const byte lsbIndex = bitScanForward(bb);
bb &= bb - 1;
Expand All @@ -116,23 +170,23 @@ namespace Bitboard
* @param x bitboard to count the bits from
* @return number of 1 bits in the bitboard
*/
constexpr int popCount(U64 x) noexcept
{
int count = 0;
inline int popCount(U64 x) noexcept
{
int count = 0;

while (x)
{
x &= x - 1; // clear the least significant bit set
++count;
}

return count;
}
return count;
}

constexpr byte findNextSquare(U64 &bb)
inline byte findNextSquare(U64 &bb)
{
const byte square = Bitboard::bitScanForward(bb);
bb &= ~Bitboard::shiftedBoards[square];
bb ^= Bitboard::shiftedBoards[square];
return square;
}
}
Loading