tensor_predictors/dataAnalysis/chess/Rchess/inst/include/SchachHoernchen/Move.h

306 lines
10 KiB
C++

#ifndef INCLUDE_GUARD_MOVE_H
#define INCLUDE_GUARD_MOVE_H
#include <iterator>
#include <algorithm>
#include <cassert>
#include "utils.h"
#include "types.h"
class Move {
public:
using base_type = uint64_t;
private:
base_type _bits;
public:
Move() = default; // required by MoveList
// Reverse of cast to base_type
Move(base_type bits) : _bits{bits} { };
explicit Move(Index from, Index to)
: Move(from, to, static_cast<enum piece>(0)) { };
explicit Move(Index from, Index to, enum piece promotion)
: Move(static_cast<enum piece>(0), static_cast<enum piece>(0), from, to,
static_cast<enum piece>(0), promotion) { };
explicit Move(enum piece color, enum piece piece, Index from, Index to,
enum piece victim)
: Move(color, piece, from, to, victim, static_cast<enum piece>(0)) { };
// General Move constructor
explicit Move(enum piece color, enum piece piece, Index from, Index to,
enum piece victim, enum piece promotion)
: _bits{static_cast<base_type>(
( color << 21)
| ( victim << 18)
| ( piece << 15)
| (promotion << 12)
| ( to << 6)
| from
)}
{
assert(((color == white)
|| (color == black)));
assert(((victim == knight)
|| (victim == bishop)
|| (victim == rook)
|| (victim == queen)
|| (victim == pawn)
|| !victim));
assert(((piece == knight)
|| (piece == bishop)
|| (piece == rook)
|| (piece == queen)
|| (piece == pawn)
|| (piece == king)
|| !piece));
assert(((promotion == knight)
|| (promotion == bishop)
|| (promotion == rook)
|| (promotion == queen)
|| !promotion));
assert(( to < 64));
assert((from < 64));
};
Index from() const { return _bits & 63U; }
Index to() const { return (_bits >> 6) & 63U; }
enum piece promote() const {
return static_cast<enum piece>((_bits >> 12) & 7U);
}
enum piece piece() const {
return static_cast<enum piece>((_bits >> 15) & 7U);
}
enum piece victim() const {
return static_cast<enum piece>((_bits >> 18) & 7U);
}
enum piece color() const {
return static_cast<enum piece>((_bits >> 21) & 7U);
}
uint32_t score() const {
return static_cast<uint32_t>(_bits >> 32);
}
static constexpr uint32_t killerScore[2] = { 4096U, 4095U };
void setScore(const uint32_t val) {
constexpr base_type mask = (1ULL << 22) - 1ULL;
_bits = (_bits & mask) | (static_cast<base_type>(val) << 32);
}
uint32_t calcScore() const {
const uint32_t mvv_lva = ((victim() << 3) + (7U - piece()));
const bool winning = victim() > piece();
// add 128 to ensure the PST values are positive
const Index t = color() == white ? to() : 63 - to();
const Index f = color() == white ? from() : 63 - from();
const uint32_t pst = PSQT[piece()][t] - PSQT[piece()][f] + 128;
return ((static_cast<bool>(victim()) * mvv_lva) << (14 + winning * 6)) + pst;
}
// Allows to be cast to the base type (as number)
operator base_type() { return _bits; }
bool operator!() const { return this->from() == this->to(); }
// Comparison of <from><to>[<promotion>] part of the move. Everything else
// is redundent and allows simple parse move routine (use Board::isLegal
// for move legality test and augmentation)
bool operator==(const Move& rhs) const {
constexpr base_type mask = (1ULL << 22) - 1ULL;
return (_bits & mask) == (rhs._bits & mask);
}
bool operator!=(const Move& rhs) const {
constexpr base_type mask = (1ULL << 22) - 1ULL;
return (_bits & mask) != (rhs._bits & mask);
}
// default sort order is decreasing (for scored moves the best move first)
friend bool operator<(const Move& lhs, const Move& rhs) {
return lhs._bits > rhs._bits;
}
};
class MoveList {
private:
static constexpr unsigned _max_size = 256;
unsigned _size;
Move _moves[_max_size]; // apparently, 218 are the max nr. of moves
public:
MoveList() : _size{0} { };
// Copy Constructor
MoveList(const MoveList& moveList) : _size{moveList._size} {
assert(_size <= _max_size);
std::copy(moveList._moves, moveList._moves + _size, _moves);
}
// Copy Assignement Operator
MoveList& operator=(const MoveList&) = default;
unsigned size() const { return _size; };
bool empty() const { return !static_cast<bool>(_size); };
static constexpr unsigned max_size() { return _max_size; };
void clear() { _size = 0; };
Move* data() { return _moves; };
const Move* data() const { return _moves; };
template <typename... Args>
void emplace_back(Args&&... args) {
assert(_size < _max_size);
_moves[_size++] = Move(std::forward<Args>(args)...);
}
void push_back(const Move& move) {
assert(_size < _max_size);
_moves[_size++] = move;
}
void append(const MoveList& list) {
assert((_size + list._size) < _max_size);
for (unsigned i = 0; i < list._size; i++) {
_moves[_size++] = list._moves[i];
}
}
bool contains(const Move& move) const {
for (unsigned i = 0; i < _size; i++) {
if (_moves[i] == move) {
return true;
}
}
return false;
}
/**
* Searches for an occurence of `move` in the list and places the `move` as
* the first element in the list. If the provided `move` is not an element
* no opperation is performed and `false` will be returned.
*
* @param move a move to be searched for and placed as first element.
* @return `true` if `move` is found and placed as first element,
* `false` otherwise.
*/
bool move_front(const Move& move) {
for (unsigned i = 0; i < _size; i++) {
if (_moves[i] == move) {
std::swap(_moves[0], _moves[i]);
return true;
}
}
return false;
}
Move& operator[](unsigned i) { return _moves[i]; }
const Move& operator[](unsigned i) const { return _moves[i]; }
struct MoveIter {
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = Move;
using pointer = value_type*;
using reference = value_type&;
MoveIter(pointer ptr) : _ptr{ptr} { };
// Dereference operators
reference operator*() { return *_ptr; };
pointer operator->() { return _ptr; };
// Arithmetic operators
MoveIter& operator++() { _ptr++; return *this; };
MoveIter operator++(int) {
MoveIter copy = *this; ++(*this); return copy;
};
MoveIter& operator--() { _ptr--; return *this; };
MoveIter operator--(int) {
MoveIter copy = *this; --(*this); return copy;
};
MoveIter& operator+=(int i) {
_ptr += i; return *this;
};
friend MoveIter operator+(MoveIter it, int i) { return (it += i); };
MoveIter& operator-=(int i) {
_ptr -= i; return *this;
};
friend MoveIter operator-(MoveIter it, int i) { return (it -= i); };
friend difference_type operator-(const MoveIter& lhs, const MoveIter& rhs) {
return lhs._ptr - rhs._ptr;
};
// Comparison operators
friend bool operator==(const MoveIter& lhs, const MoveIter& rhs) {
return lhs._ptr == rhs._ptr;
};
friend bool operator<=(const MoveIter& lhs, const MoveIter& rhs) {
return lhs._ptr <= rhs._ptr;
};
friend bool operator>=(const MoveIter& lhs, const MoveIter& rhs) {
return lhs._ptr >= rhs._ptr;
};
friend bool operator!=(const MoveIter& lhs, const MoveIter& rhs) {
return lhs._ptr != rhs._ptr;
};
friend bool operator<(const MoveIter& lhs, const MoveIter& rhs) {
return lhs._ptr < rhs._ptr;
};
friend bool operator>(const MoveIter& lhs, const MoveIter& rhs) {
return lhs._ptr > rhs._ptr;
};
private:
pointer _ptr;
};
MoveIter begin() { return MoveIter(_moves); };
MoveIter end() { return MoveIter(_moves + _size); };
struct ConstMoveIter {
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = const Move;
using pointer = const value_type*;
using reference = const value_type&;
ConstMoveIter(pointer ptr) : _ptr{ptr} { };
// Dereference operators
reference operator*() { return *_ptr; };
pointer operator->() { return _ptr; };
// Arithmetic operators
ConstMoveIter& operator++() { _ptr++; return *this; };
ConstMoveIter operator++(int) {
ConstMoveIter copy = *this; ++(*this); return copy;
};
ConstMoveIter& operator--() { _ptr--; return *this; };
ConstMoveIter operator--(int) {
ConstMoveIter copy = *this; --(*this); return copy;
};
ConstMoveIter& operator+=(int i) {
_ptr += i; return *this;
};
// Comparison operators
friend bool operator==(const ConstMoveIter& lhs, const ConstMoveIter& rhs) {
return lhs._ptr == rhs._ptr;
};
friend bool operator!=(const ConstMoveIter& lhs, const ConstMoveIter& rhs) {
return lhs._ptr != rhs._ptr;
};
private:
pointer _ptr;
};
ConstMoveIter begin() const { return ConstMoveIter(_moves); };
ConstMoveIter end() const { return ConstMoveIter(_moves + _size); };
};
#endif /* INCLUDE_GUARD_MOVE_H */