commit 230e0f6374341c54629f35d513ab86f28966ecdb
parent 8ee739e565ef8447d12b35d9ffe09bae73f6937d
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Sat, 1 Oct 2022 16:55:31 +0200
Improve move evaluation by sorting MovesList and checking for following capturing attacks
Diffstat:
3 files changed, 138 insertions(+), 17 deletions(-)
diff --git a/include/CBoard.h b/include/CBoard.h
@@ -15,9 +15,10 @@ eColor Piece_color(Piece_T self);
ePiece Piece_piece(Piece_T self);
int Piece_index(Piece_T self);
+Piece_T Piece_get(ePiece piece, eColor color);
Piece_T Piece_fromCode(char code);
Piece_T Piece_fromIndex(int index);
-Piece_T Piece_get(ePiece piece, eColor color);
+ePiece Piece_piece_fromCode(int index);
typedef struct CBoard_T *CBoard_T;
@@ -42,6 +43,7 @@ void CBoard_piece_move(CBoard_T self, Piece_T Piece, Square square,
Square target);
void CBoard_piece_pop(CBoard_T self, Piece_T Piece, Square square);
void CBoard_piece_set(CBoard_T self, Piece_T Piece, Square square);
+int CBoard_piece_get(CBoard_T self, Square square);
U64 CBoard_colorBB_get(CBoard_T self, eColor color, Square target);
void CBoard_colorBB_pop(CBoard_T self, eColor color, Square target);
diff --git a/src/CBoard.c b/src/CBoard.c
@@ -58,6 +58,10 @@ Piece_T Piece_fromCode(char code) {
return NULL;
}
+ePiece Piece_piece_fromCode(int index) {
+ return Pieces[WHITE][index % 8].piece;
+}
+
Piece_T Piece_fromIndex(int index) { return &Pieces[index / 8][index % 8]; }
Piece_T Piece_get(ePiece piece, eColor color) { return &Pieces[color][piece]; }
@@ -111,6 +115,15 @@ U64 CBoard_colorBB_get(CBoard_T self, eColor color, Square target) {
return bit_get(self->colorBB[color], target);
}
+int CBoard_piece_get(CBoard_T self, Square square) {
+ for (int i = 0; i < 6; i++) {
+ if (bit_get(self->pieceBB[i], square)) {
+ return i;
+ }
+ }
+ return -1;
+}
+
void CBoard_piece_pop(CBoard_T self, Piece_T Piece, Square square) {
bit_pop(self->pieceBB[Piece->piece], square);
bit_pop(self->colorBB[Piece->color], square);
diff --git a/src/engine.c b/src/engine.c
@@ -330,6 +330,7 @@ void init_all() {
struct Score_T {
int value;
int score[64];
+ int capture[6];
};
// clang-format off
@@ -344,8 +345,10 @@ struct Score_T Scores[] = {
10, 10, 10, 20, 20, 10, 10, 10,
20, 20, 20, 30, 30, 30, 20, 20,
30, 30, 30, 40, 40, 30, 30, 30,
- 90, 90, 90, 90, 90, 90, 90, 90,
- }},
+ 90, 90, 90, 90, 90, 90, 90, 90, },
+.capture = { [PAWN] = 105, [KNIGHT] = 205,
+ [BISHOP] = 305, [ROOK] = 405,
+ [QUEEN] = 505, [KING] = 605} },
[KNIGHT] = {
.value = 300,
.score = {
@@ -356,8 +359,10 @@ struct Score_T Scores[] = {
-5, 10, 20, 30, 30, 20, 10, -5,
-5, 5, 20, 20, 20, 20, 5, -5,
-5, 0, 0, 10, 10, 0, 0, -5,
- -5, 0, 0, 0, 0, 0, 0, -5,
- }},
+ -5, 0, 0, 0, 0, 0, 0, -5, },
+.capture = { [PAWN] = 104, [KNIGHT] = 204,
+ [BISHOP] = 304, [ROOK] = 404,
+ [QUEEN] = 504, [KING] = 604} },
[BISHOP] = {
.value = 350,
.score = {
@@ -368,8 +373,10 @@ struct Score_T Scores[] = {
0, 0, 10, 20, 20, 10, 0, 0,
0, 0, 0, 10, 10, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- }},
+ 0, 0, 0, 0, 0, 0, 0, 0, },
+.capture = { [PAWN] = 103, [KNIGHT] = 203,
+ [BISHOP] = 303, [ROOK] = 403,
+ [QUEEN] = 503, [KING] = 603} },
[ROOK] = {
.value = 500,
.score = {
@@ -380,8 +387,10 @@ struct Score_T Scores[] = {
0, 0, 10, 20, 20, 10, 0, 0,
0, 0, 10, 20, 20, 10, 0, 0,
50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50,
- }},
+ 50, 50, 50, 50, 50, 50, 50, 50, },
+.capture = { [PAWN] = 102, [KNIGHT] = 202,
+ [BISHOP] = 302, [ROOK] = 402,
+ [QUEEN] = 502, [KING] = 602} },
[QUEEN] = {
.value = 1000,
.score = {
@@ -392,8 +401,10 @@ struct Score_T Scores[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- }},
+ 0, 0, 0, 0, 0, 0, 0, 0, },
+.capture = { [PAWN] = 101, [KNIGHT] = 201,
+ [BISHOP] = 301, [ROOK] = 401,
+ [QUEEN] = 501, [KING] = 601} },
[KING] = {
.value = 10000,
.score = {
@@ -404,8 +415,10 @@ struct Score_T Scores[] = {
0, 5, 10, 20, 20, 10, 5, 0,
0, 5, 5, 10, 10, 5, 5, 0,
0, 0, 5, 5, 5, 5, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- }},
+ 0, 0, 0, 0, 0, 0, 0, 0, },
+.capture = { [PAWN] = 100, [KNIGHT] = 200,
+ [BISHOP] = 300, [ROOK] = 400,
+ [QUEEN] = 500, [KING] = 600} },
};
const int mirror_score[128] =
@@ -454,22 +467,109 @@ int evaluate(CBoard_T board) {
int ply;
int best_move;
+int move_score(CBoard_T board, Move move) {
+ if (Move_capture(move)) {
+ return Scores[CBoard_piece_get(board, Move_source(move))]
+ .capture[CBoard_piece_get(board, Move_target(move))];
+ } else {
+ }
+
+ return 0;
+}
+
+void MoveList_sort(CBoard_T board, MoveList_T list) {
+ int score[list->count];
+ for (int i = 0; i < list->count; i++)
+ score[i] = move_score(board, list->moves[i]);
+
+ for (int i = 0; i < list->count; i++)
+ for (int j = i + 1; j < list->count; j++)
+ if (score[i] < score[j]) {
+ Move t = list->moves[i];
+ list->moves[i] = list->moves[j];
+ list->moves[j] = t;
+
+ int s = score[i];
+ score[i] = score[j];
+ score[j] = s;
+ }
+}
+
+int quiescence(CBoard_T board, int alpha, int beta) {
+ MoveList_T moves;
+ CBoard_T backup;
+
+ int eval = evaluate(board);
+ nodes++;
+
+ if (eval >= beta) {
+ MoveList_free(&moves);
+ CBoard_free(&backup);
+ return beta;
+ }
+
+ if (eval > alpha) {
+ alpha = eval;
+ }
+
+ backup = CBoard_new();
+ moves = generate_moves(board, NULL);
+ MoveList_sort(board, moves);
+
+ int legal_moves = 0;
+ for (int i = 0; i < moves->count; i++) {
+ CBoard_copy(board, backup);
+ ply++;
+
+ if (make_move(board, moves->moves[i], 1) == 0) {
+ CBoard_copy(backup, board);
+ ply--;
+ continue;
+ }
+
+ int score = -quiescence(board, -beta, -alpha);
+ CBoard_copy(backup, board);
+ ply--;
+
+ if (score >= beta) {
+ MoveList_free(&moves);
+ CBoard_free(&backup);
+ return beta;
+ }
+
+ if (score > alpha) {
+ alpha = score;
+ }
+ }
+
+ MoveList_free(&moves);
+ CBoard_free(&backup);
+ return alpha;
+}
+
int negamax(CBoard_T board, int alpha, int beta, int depth) {
MoveList_T moves;
CBoard_T backup;
+ int isCheck = 0;
// tmp
Move best;
int old_alpha = alpha;
if (depth == 0) {
- return evaluate(board);
+ return quiescence(board, alpha, beta);
}
nodes++;
backup = CBoard_new();
moves = generate_moves(board, NULL);
+ isCheck = CBoard_isCheck(board);
+
+ if (isCheck)
+ depth++;
+
+ MoveList_sort(board, moves);
int legal_moves = 0;
for (int i = 0; i < moves->count; i++) {
@@ -502,7 +602,7 @@ int negamax(CBoard_T board, int alpha, int beta, int depth) {
}
if (legal_moves == 0) {
- if (CBoard_isCheck(board))
+ if (isCheck)
return -49000 + ply;
else
return 0;
@@ -718,9 +818,15 @@ int main(void) {
printf("debugging!\n");
CBoard_T board = NULL;
Instruction_T inst = NULL;
- board = CBoard_fromFEN(board, start_position);
+ MoveList_T list = NULL;
+ board = CBoard_fromFEN(board, tricky_position);
+ list = generate_moves(board, list);
+ MoveList_print(list);
+ MoveList_sort(board, list);
+ MoveList_print(list);
+
CBoard_print(board);
- search_position(board, 5);
+ search_position(board, 7);
} else
uci_loop();
return 0;