commit 1857c3ab3da2587974a169e7414f3add950a7a5e
parent 2fb9a673b6887550d88a7d3be0cfd8df2a4e0536
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Tue, 15 Aug 2023 23:17:56 +0200
Trim Move town to 16bits
Diffstat:
5 files changed, 85 insertions(+), 62 deletions(-)
diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp
@@ -32,8 +32,11 @@ U32 ply;
Move move_list_best_move;
U32 inline move_list_score(Move move) {
- const piece::Type type = move.piece();
- if (move.is_capture()) return piece::score(type, move.captured()) + 10000;
+ const piece::Type type = board.get_square_piece_type(move.source());
+ if (move.is_capture()) {
+ const piece::Type captured = board.get_square_piece_type(move.target());
+ return piece::score(type, captured) + 10000;
+ }
if (killer[0][ply] == move) return 9000;
if (killer[1][ply] == move) return 8000;
return history[piece::get_index(type, board.get_side())][to_underlying(move.target())];
@@ -269,8 +272,8 @@ int negamax(int alpha, int beta, int depth, bool null) {
if (score > alpha) {
if (!move.is_capture()) {
- history[piece::get_index(move.piece(), board.get_side())][to_underlying(move.target())] +=
- depth;
+ const piece::Type piece = board.get_square_piece_type(move.source());
+ history[piece::get_index(piece, board.get_side())][to_underlying(move.target())] += depth;
}
alpha = score;
@@ -309,6 +312,7 @@ void move_print_UCI(Move move) {
void search_position(int depth) {
int alpha = -SCORE_INFINITY, beta = SCORE_INFINITY;
+ nodes = 0;
for (int crnt = 1; crnt <= depth;) {
follow_pv = 1;
@@ -327,7 +331,7 @@ void search_position(int depth) {
} else if (score > MATE_SCORE && score < MATE_VALUE) {
std::cout << "info score mate " << (MATE_VALUE - score) / 2 + 1;
} else {
- std::cout << "info score " << score;
+ std::cout << "info score cp " << score;
}
std::cout << " depth " << crnt;
@@ -410,6 +414,7 @@ Move parse_move(char *move_string) {
Square source = square_from_coordinates(move_string);
Square target = square_from_coordinates(move_string + 2);
+
const MoveList list(board);
for (int i = 0; i < list.size(); i++) {
const Move move = list[i];
@@ -451,7 +456,7 @@ Board *Instruction_parse(Instruction *self) {
if (strcmp(token, "moves") == 0) {
while ((token = Instruction_token_next(self))) {
Move move = parse_move(token);
- if (move == Move()) {
+ if (move != Move()) {
move.make(board, 0);
} else {
printf("Invalid move %s!\n", token);
diff --git a/src/include/move.hpp b/src/include/move.hpp
@@ -9,28 +9,47 @@
#include <vector>
struct Move {
- Move() = default;
+ enum Flag : uint8_t {
+ QUIET,
+ DOUBLE,
+ CASTLEK,
+ CASTLEQ,
+ CAPTURE,
+ ENPASSANT,
+ PKNIGHT = 8,
+ PBISHOP,
+ PROOK,
+ PQUEEN,
+ PCKNIGHT,
+ PCBISHOP,
+ PCROOK,
+ PCQUEEN,
+ };
- Move(Square source, Square target, piece::Type piece, piece::Type capture, piece::Type promote, bool dbl,
- bool enpassant, bool castle)
- : source_i(to_underlying(source)), target_i(to_underlying(target)), piece_i(to_underlying(piece)),
- capture_i(to_underlying(capture)), promote_i(to_underlying(promote)), dbl(dbl),
- enpassant(enpassant), castle(castle) {}
+ Move() = default;
+ Move(Square source, Square target, Flag flags)
+ : source_i(to_underlying(source)), target_i(to_underlying(target)), flags_i(flags) {}
- bool operator==(const Move &m) const = default;
+ bool operator==(Move &m) const {
+ return source_i == m.source_i && target_i == m.target_i && flags_i == m.flags_i;
+ }
Square source(void) const { return static_cast<Square>(source_i); }
Square target(void) const { return static_cast<Square>(target_i); }
- bool is_double(void) const { return dbl; }
- bool is_enpassant(void) const { return enpassant; }
- bool is_castle(void) const { return castle; }
- bool is_capture(void) const { return capture_i != to_underlying(piece::Type::NONE); }
- bool is_promote(void) const { return promote_i != to_underlying(piece::Type::NONE); }
+ bool is_capture(void) const { return flags_i & CAPTURE; }
+ bool is_promote(void) const { return flags_i & 0x8; }
+
+ bool is_quiet(void) const { return flags_i == QUIET; }
+ bool is_double(void) const { return flags_i == DOUBLE; }
+
+ bool is_castle(void) const { return flags_i == CASTLEK || flags_i == CASTLEQ; }
+ bool is_castle_king(void) const { return flags_i == CASTLEK; }
+ bool is_castle_queen(void) const { return flags_i == CASTLEQ; }
+
+ bool is_enpassant(void) const { return flags_i == ENPASSANT; }
- const piece::Type piece(void) const { return static_cast<piece::Type>(piece_i); }
- const piece::Type captured(void) const { return static_cast<piece::Type>(capture_i); }
- const piece::Type promoted(void) const { return static_cast<piece::Type>(promote_i); }
+ const piece::Type promoted(void) const { return static_cast<piece::Type>((flags_i & 0x3) + 1); }
bool make(Board &board, bool attack_only) const;
@@ -43,12 +62,7 @@ struct Move {
unsigned source_i : 6;
unsigned target_i : 6;
- unsigned piece_i : 3;
- unsigned capture_i : 3;
- unsigned promote_i : 3;
- bool dbl : 1;
- bool enpassant : 1;
- bool castle : 1;
+ unsigned flags_i : 4;
};
#endif
diff --git a/src/move/move.cpp b/src/move/move.cpp
@@ -20,6 +20,7 @@ void Move::piece_move(Board &board, piece::Type type, Color color, Square source
piece_set(board, type, color, target);
}
+using piece::Type::PAWN;
using piece::Type::ROOK;
bool Move::make(Board &board, bool attack_only) const {
@@ -41,41 +42,47 @@ bool Move::make(Board &board, bool attack_only) const {
return 0;
} else {
const Color color = board.get_side();
- Color colorOther = color == Color::BLACK ? Color::WHITE : Color::BLACK;
+ Color colorOther = color == Color::BLACK ? Color::WHITE : Color::BLACK;
const Square source = this->source();
const Square target = this->target();
const Square ntarget =
static_cast<Square>(to_underlying(this->target()) + (color == Color::WHITE ? -8 : +8));
+ const piece::Type piece = board.get_square_piece_type(source);
+
if (!is_capture()) {
if (is_promote()) {
- piece_remove(board, piece(), color, source);
+ piece_remove(board, piece, color, source);
piece_set(board, promoted(), color, target);
} else {
- piece_move(board, piece(), color, source, target);
+ piece_move(board, piece, color, source, target);
}
} else {
+ const piece::Type captured = board.get_square_piece_type(target);
if (is_enpassant()) {
- piece_move(board, piece(), color, source, target);
- piece_remove(board, captured(), colorOther, ntarget);
+ piece_move(board, piece, color, source, target);
+ piece_remove(board, PAWN, colorOther, ntarget);
} else if (is_promote()) {
- piece_remove(board, piece(), color, source);
- piece_remove(board, captured(), colorOther, target);
+ piece_remove(board, piece, color, source);
+ piece_remove(board, captured, colorOther, target);
piece_set(board, promoted(), color, target);
} else {
- piece_remove(board, captured(), colorOther, target);
- piece_move(board, piece(), color, source, target);
+ piece_remove(board, captured, colorOther, target);
+ piece_move(board, piece, color, source, target);
}
}
board.set_enpassant(is_double() ? ntarget : Square::no_sq);
if (is_castle()) {
- if (target == Square::g1) piece_move(board, ROOK, Color::WHITE, Square::h1, Square::f1);
- if (target == Square::c1) piece_move(board, ROOK, Color::WHITE, Square::a1, Square::d1);
- if (target == Square::g8) piece_move(board, ROOK, Color::BLACK, Square::h8, Square::f8);
- if (target == Square::c8) piece_move(board, ROOK, Color::BLACK, Square::a8, Square::d8);
+ if (color == Color::WHITE) {
+ if (is_castle_king()) piece_move(board, ROOK, Color::WHITE, Square::h1, Square::f1);
+ if (is_castle_queen()) piece_move(board, ROOK, Color::WHITE, Square::a1, Square::d1);
+ } else {
+ if (is_castle_king()) piece_move(board, ROOK, Color::BLACK, Square::h8, Square::f8);
+ if (is_castle_queen()) piece_move(board, ROOK, Color::BLACK, Square::a8, Square::d8);
+ }
}
board.xor_hash(Zobrist::key_castle(board.get_castle()));
@@ -94,8 +101,6 @@ bool Move::make(Board &board, bool attack_only) const {
std::ostream &operator<<(std::ostream &os, Move move) {
os << square_to_coordinates(move.source()) << " ";
os << square_to_coordinates(move.target()) << " ";
- os << piece::get_code(move.piece()) << " ";
- os << (move.is_capture() ? piece::get_code(move.captured()) : '.') << " ";
os << (move.is_promote() ? piece::get_code(move.promoted()) : '.') << " ";
os << move.is_double() << " ";
os << move.is_enpassant() << " ";
diff --git a/src/move/movelist.cpp b/src/move/movelist.cpp
@@ -35,17 +35,17 @@ void MoveList::generate(const Board &board) {
const Square tgt = static_cast<Square>(tgt_i = src_i + add);
if (!board.is_square_occupied(tgt)) {
if (pawn_canPromote(color, src)) {
- list.push_back(Move(src, tgt, PAWN, NONE, KNIGHT, 0, 0, 0));
- list.push_back(Move(src, tgt, PAWN, NONE, BISHOP, 0, 0, 0));
- list.push_back(Move(src, tgt, PAWN, NONE, ROOK, 0, 0, 0));
- list.push_back(Move(src, tgt, PAWN, NONE, QUEEN, 0, 0, 0));
+ list.push_back({src, tgt, Move::PKNIGHT});
+ list.push_back({src, tgt, Move::PBISHOP});
+ list.push_back({src, tgt, Move::PROOK});
+ list.push_back({src, tgt, Move::PQUEEN});
} else {
- list.push_back(Move(src, tgt, PAWN, NONE, NONE, 0, 0, 0));
+ list.push_back({src, tgt, Move::QUIET});
// two ahead
const Square tgt = static_cast<Square>(tgt_i + add);
if (pawn_onStart(color, src) && !board.is_square_occupied(tgt))
- list.push_back(Move(src, tgt, PAWN, NONE, NONE, 1, 0, 0));
+ list.push_back({src, tgt, Move::DOUBLE});
}
}
@@ -54,21 +54,20 @@ void MoveList::generate(const Board &board) {
board.get_bitboard_piece_attacks(PAWN, color, src) & board.get_bitboard_color(colorOther);
bitboard_for_each_bit(tgt_i, attack) {
const Square tgt = static_cast<Square>(tgt_i);
- const piece::Type capture = board.get_square_piece_type(tgt);
if (pawn_canPromote(color, src)) {
- list.push_back(Move(src, tgt, PAWN, capture, KNIGHT, 0, 0, 0));
- list.push_back(Move(src, tgt, PAWN, capture, BISHOP, 0, 0, 0));
- list.push_back(Move(src, tgt, PAWN, capture, ROOK, 0, 0, 0));
- list.push_back(Move(src, tgt, PAWN, capture, QUEEN, 0, 0, 0));
+ list.push_back({src, tgt, Move::PCKNIGHT});
+ list.push_back({src, tgt, Move::PCBISHOP});
+ list.push_back({src, tgt, Move::PCROOK});
+ list.push_back({src, tgt, Move::PCQUEEN});
} else {
- list.push_back(Move(src, tgt, PAWN, capture, NONE, 0, 0, 0));
+ list.push_back({src, tgt, Move::CAPTURE});
}
}
// en passant
const Square enpassant = board.get_enpassant();
if (enpassant != Square::no_sq && board.is_piece_attack_square(PAWN, color, src, enpassant))
- list.push_back(Move(src, enpassant, PAWN, PAWN, NONE, 0, 1, 0));
+ list.push_back({src, enpassant, Move::ENPASSANT});
}
// All piece move
@@ -79,7 +78,7 @@ void MoveList::generate(const Board &board) {
U64 attack = board.get_bitboard_piece_moves(type, color, src);
bitboard_for_each_bit(tgt_i, attack) {
const Square tgt = static_cast<Square>(tgt_i);
- list.push_back(Move(src, tgt, type, board.get_square_piece_type(tgt), NONE, 0, 0, 0));
+ list.push_back({src, tgt, board.is_square_occupied(tgt) ? Move::CAPTURE : Move::QUIET});
}
}
}
@@ -90,14 +89,14 @@ void MoveList::generate(const Board &board) {
if (board.get_castle() & to_underlying(Board::Castle::WK)) {
if (!board.is_square_occupied(Square::f1) && !board.is_square_occupied(Square::g1) &&
!board.is_square_attacked(Square::f1, Color::BLACK))
- list.push_back(Move(Square::e1, Square::g1, KING, NONE, NONE, 0, 0, 1));
+ list.push_back({Square::e1, Square::g1, Move::CASTLEK});
}
if (board.get_castle() & to_underlying(Board::Castle::WQ)) {
if (!board.is_square_occupied(Square::d1) && !board.is_square_occupied(Square::c1) &&
!board.is_square_occupied(Square::b1) &&
!board.is_square_attacked(Square::d1, Color::BLACK) &&
!board.is_square_attacked(Square::c1, Color::BLACK))
- list.push_back(Move(Square::e1, Square::c1, KING, NONE, NONE, 0, 0, 1));
+ list.push_back({Square::e1, Square::c1, Move::CASTLEQ});
}
}
} else {
@@ -105,14 +104,14 @@ void MoveList::generate(const Board &board) {
if (board.get_castle() & to_underlying(Board::Castle::BK)) {
if (!board.is_square_occupied(Square::f8) && !board.is_square_occupied(Square::g8) &&
!board.is_square_attacked(Square::f8, Color::WHITE))
- list.push_back(Move(Square::e8, Square::g8, KING, NONE, NONE, 0, 0, 1));
+ list.push_back({Square::e8, Square::g8, Move::CASTLEK});
}
if (board.get_castle() & to_underlying(Board::Castle::BQ)) {
if (!board.is_square_occupied(Square::d8) && !board.is_square_occupied(Square::c8) &&
!board.is_square_occupied(Square::b8) &&
!board.is_square_attacked(Square::d8, Color::WHITE) &&
!board.is_square_attacked(Square::c8, Color::WHITE))
- list.push_back(Move(Square::e8, Square::c8, KING, NONE, NONE, 0, 0, 1));
+ list.push_back({Square::e8, Square::c8, Move::CASTLEQ});
}
}
}
diff --git a/src/perft/perft.cpp b/src/perft/perft.cpp
@@ -20,7 +20,7 @@ class Perft {
Board board = board_start;
if (!move.make(board, 0)) return;
sem.acquire();
- debug(board_start, move, board);
+ // debug(board_start, move, board);
if (depth > 1) {
test(board, depth - 1);
@@ -64,7 +64,7 @@ class Perft {
for (int i = 0; i < list.size(); i++) {
Board copy = board;
if (!list[i].make(copy, 0)) continue;
- debug(board, list[i], copy);
+ // debug(board, list[i], copy);
if (depth != 1)
test(copy, depth - 1);
else