Skip to content

Commit e296010

Browse files
committed
début du bot v_0
1 parent 18a7334 commit e296010

4 files changed

Lines changed: 105 additions & 91 deletions

File tree

bots/bot_v0

5.31 KB
Binary file not shown.

lib/ai/ai.h

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,10 @@ typedef struct
2424
int score; // score obtenu à la profondeur précédente
2525
} ScoredMove;
2626

27-
#pragma once
28-
typedef struct
29-
{
30-
Chessboard board;
31-
Move move;
32-
int score;
33-
unsigned long long nbmoves;
34-
int true_depth;
35-
unsigned long long nb_cuts_tt;
36-
} ThreadTask;
3727

3828
/// @brief Run the search for the best move in the position
3929
/// @param board
4030
/// @return
4131
Move get_best_move(Chessboard board);
32+
33+
int alpha_beta(Chessboard *board, int depth, int alpha, int beta, int is_maximizing);

src/ai/ai.c

Lines changed: 102 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,114 +1,136 @@
11
#include "ai.h"
2+
#include <limits.h>
23

3-
struct timespec t_start;
4-
int max_time_ms = 100;
5-
6-
typedef struct
7-
{
8-
Move best_move;
9-
int evaluation;
10-
} SearchResult;
11-
12-
/**
13-
* Recherche Alpha-Beta récursive
14-
* Retourne une évaluation numérique pour la position courante.
15-
*/
16-
static int alpha_beta(Chessboard *board, int depth, int alpha, int beta, bool maximizingPlayer)
4+
// Fonction pour trier les coups dans l'ordre décroissant
5+
static void sort_moves(ScoredMove *scored_moves, int nbmoves)
176
{
18-
if (depth == 0) // Rajouter une condition sur mat et pat
7+
for (int i = 0; i < nbmoves - 1; i++)
198
{
20-
return evaluate_position(board);
9+
for (int j = 0; j < nbmoves - i - 1; j++)
10+
{
11+
if (scored_moves[j].score < scored_moves[j + 1].score)
12+
{
13+
ScoredMove temp = scored_moves[j];
14+
scored_moves[j] = scored_moves[j + 1];
15+
scored_moves[j + 1] = temp;
16+
}
17+
}
2118
}
19+
}
2220

23-
Move moves[250];
24-
int nb_moves = get_all_legal_moves(board, moves);
25-
26-
if (nb_moves == 0)
27-
return evaluate_position(board);
21+
static int get_ending_score(Chessboard *board, int is_maximizing)
22+
{
23+
if (is_check(board))
24+
return is_maximizing ? INT_MIN + 1 : INT_MAX - 1; // Checkmate
25+
return 0; // Stalemate
26+
}
2827

29-
if (maximizingPlayer)
28+
/* Helper: simple in-place partition to put capture moves first (heuristic d'ordre) */
29+
static void order_moves_by_capture(Move moves[], int nbmoves)
30+
{
31+
if (nbmoves <= 1)
32+
return;
33+
int i = 0, j = nbmoves - 1;
34+
while (i < j)
3035
{
31-
int maxEval = -INFINI;
32-
for (int i = 0; i < nb_moves; i++)
36+
while (i < nbmoves && moves[i].piece_taken)
37+
i++;
38+
while (j >= 0 && !moves[j].piece_taken)
39+
j--;
40+
if (i < j)
3341
{
34-
Chessboard next_board = *board;
35-
play_move(&next_board, moves[i]);
36-
37-
int eval = alpha_beta(&next_board, depth - 1, alpha, beta, false);
38-
if (eval > maxEval)
39-
maxEval = eval;
40-
41-
if (maxEval > alpha)
42-
alpha = maxEval;
42+
Move tmp = moves[i];
43+
moves[i] = moves[j];
44+
moves[j] = tmp;
45+
i++;
46+
j--;
47+
}
48+
}
49+
}
4350

44-
if (beta <= alpha)
45-
break; // coupure Beta
51+
static int alpha_beta_search(Chessboard *board, int depth, int alpha, int beta, int is_maximizing, int nbmoves, Move *legal_moves)
52+
{
53+
if (is_maximizing)
54+
{
55+
int best = INT_MIN;
56+
for (int i = 0; i < nbmoves; ++i)
57+
{
58+
play_move(board, legal_moves[i]);
59+
int val = alpha_beta(board, depth - 1, alpha, beta, !is_maximizing);
60+
unplay_move(board, legal_moves[i]);
61+
62+
if (val > best)
63+
best = val;
64+
if (val > alpha)
65+
alpha = val;
66+
if (alpha >= beta)
67+
break; /* beta-cutoff */
4668
}
47-
return maxEval;
69+
return best;
4870
}
4971
else
5072
{
51-
int minEval = INFINI;
52-
for (int i = 0; i < nb_moves; i++)
73+
int best = INT_MAX;
74+
for (int i = 0; i < nbmoves; ++i)
5375
{
54-
Chessboard next_board = *board;
55-
play_move(&next_board, moves[i]);
56-
57-
int eval = alpha_beta(&next_board, depth - 1, alpha, beta, true);
58-
if (eval < minEval)
59-
minEval = eval;
60-
61-
if (minEval < beta)
62-
beta = minEval;
63-
76+
play_move(board, legal_moves[i]);
77+
int val = alpha_beta(board, depth - 1, alpha, beta, !is_maximizing);
78+
unplay_move(board, legal_moves[i]);
79+
80+
if (val < best)
81+
best = val;
82+
if (val < beta)
83+
beta = val;
6484
if (beta <= alpha)
65-
break; // coupure Alpha
85+
break; /* alpha-cutoff */
6686
}
67-
return minEval;
87+
return best;
6888
}
6989
}
7090

71-
/**
72-
* Recherche le meilleur coup à une profondeur donnée.
73-
*/
74-
static SearchResult search_best_move_alpha_beta(Chessboard *board, int depth)
91+
int alpha_beta(Chessboard *board, int depth, int alpha, int beta, int is_maximizing)
7592
{
76-
Move moves[250];
77-
int nb_moves = get_all_legal_moves(board, moves);
93+
if (depth == 0)
94+
return evaluate_position(board);
7895

79-
SearchResult result;
80-
result.best_move = moves[0];
81-
result.evaluation = board->white_to_play ? -INFINI : INFINI;
96+
Move legal_moves[250];
97+
int nbmoves = get_all_legal_moves(board, legal_moves);
8298

83-
bool maximizing = board->white_to_play;
99+
if (nbmoves == 0)
100+
return get_ending_score(board, is_maximizing);
84101

85-
int alpha = -INFINI;
86-
int beta = INFINI;
102+
order_moves_by_capture(legal_moves, nbmoves);
87103

88-
for (int i = 0; i < nb_moves; i++)
89-
{
90-
Chessboard next_board = *board;
91-
play_move(&next_board, moves[i]);
104+
return alpha_beta_search(board, depth, alpha, beta, is_maximizing, nbmoves, legal_moves);
105+
}
106+
107+
static int get_score(Chessboard board, Move move, int depth)
108+
{
109+
play_move(&board, move);
110+
if (depth == 0)
111+
return evaluate_position(&board);
92112

93-
int eval = alpha_beta(&next_board, depth - 1, alpha, beta, !maximizing);
113+
return alpha_beta(&board, depth - 1, INT_MIN, INT_MAX, !board.white_to_play);
114+
}
94115

95-
if (maximizing && eval > result.evaluation)
96-
{
97-
result.evaluation = eval;
98-
result.best_move = moves[i];
99-
}
100-
else if (!maximizing && eval < result.evaluation)
101-
{
102-
result.evaluation = eval;
103-
result.best_move = moves[i];
104-
}
116+
static ScoredMove search_best_move(Chessboard board, int depth)
117+
{
118+
Move legal_moves[250];
119+
int nbmoves = get_all_legal_moves(&board, legal_moves);
120+
ScoredMove scored_moves[nbmoves];
121+
122+
for (int i = 0; i < nbmoves; i++)
123+
{
124+
scored_moves[i].move = legal_moves[i];
125+
scored_moves[i].score = get_score(board, legal_moves[i], depth);
105126
}
106127

107-
return result;
128+
sort_moves(scored_moves, nbmoves);
129+
return scored_moves[0];
108130
}
109131

110132
Move get_best_move(Chessboard board)
111133
{
112-
SearchResult best_move = search_best_move_alpha_beta(&board, 5);
113-
return best_move.best_move;
134+
ScoredMove best_move = search_best_move(board, 3);
135+
return best_move.move;
114136
}

src/ui/rendering.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ static void handle_ai_turn(int color_ai, GameEnvironement env)
461461
printf("Erreur de communication avec le bot\n");
462462

463463
ui_refresh_board(env);
464-
SDL_Delay(50);
464+
SDL_Delay(10);
465465
}
466466

467467
SDL_Delay(10);

0 commit comments

Comments
 (0)