Skip to content

Commit 9ec1231

Browse files
committed
ajout de la log pour le bot
1 parent 78563a2 commit 9ec1231

9 files changed

Lines changed: 122 additions & 51 deletions

File tree

bots/bot_v0

16 Bytes
Binary file not shown.

documentations/bot_api.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,14 @@ Sets the board state (FEN position) in the bot’s internal memory.
6161
---
6262

6363
### `int bot_get_best_move(BotConnector *bot, char *move_str)`
64-
Requests the bot’s best move for the current position.
64+
### `int bot_get_best_move(BotConnector *bot, char *move_str, char *log_msg, int timeout_sec)`
65+
Requests the bot’s best move for the current position and optionally retrieves a log message.
6566

6667
**Parameters:**
6768
- `bot`: Active bot connection.
6869
- `move_str`: Output buffer to store the move (e.g., `"e2e4"`).
70+
- `log_msg`: Output buffer to store an optional log message from the bot (can be empty).
71+
- `timeout_sec`: Timeout (in seconds) waiting for the main move response.
6972

7073
**Returns:**
7174
- `0` if a valid move was received.

lib/ai/ai.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define MAT 900000
1717
#define INFINI 100000000
1818
#define MAX_DEPTH 50
19+
#define SEARCH_LOG_SIZE 256
1920

2021
#pragma once
2122
typedef struct
@@ -28,12 +29,12 @@ typedef struct
2829
{
2930
int depth;
3031
int nb_positions_evaluated;
31-
} SearchInfo;
32-
32+
char log[SEARCH_LOG_SIZE];
33+
ScoredMove move;
3334

35+
} SearchInfo;
3436

3537
/// @brief Run the search for the best move in the position
3638
/// @param board
3739
/// @return
38-
Move get_best_move(Chessboard board);
39-
40+
SearchInfo get_best_move(Chessboard board);

lib/api/api_connector.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
#define MOVE_SIZE 10
1616
#define FEN_SIZE 256
17+
// Taille maximale pour un message de log renvoyé par le bot
18+
#define LOG_SIZE 256
1719

1820
typedef struct
1921
{
@@ -29,8 +31,11 @@ int is_bot_connected(BotConnector *bot);
2931

3032
int bot_set_fen(BotConnector *bot, const char *fen);
3133

32-
// Demande au bot le meilleur coup pour un FEN et une couleur
33-
int bot_get_best_move(BotConnector *bot, char *move_str);
34+
// Demande au bot le meilleur coup pour un FEN et récupère aussi un message de log éventuel
35+
// - `move_str` doit avoir la taille MOVE_SIZE
36+
// - `log_msg` doit avoir la taille LOG_SIZE (peut être vide si aucun message)
37+
// - `timeout_sec` délai (en secondes) pour la lecture du coup principal
38+
int bot_get_best_move(BotConnector *bot, char *move_str, char *log_msg, int timeout_sec);
3439

3540
// Envoie un coup au bot pour mise à jour de son état interne
3641
int bot_play_move(BotConnector *bot, const char *move_str);

src/ai/ai.c

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
#include "ai.h"
22
#include <limits.h>
33

4-
SearchInfo info = {0};
5-
64
// ==================== Move Ordering ====================
75

86
static int get_move_score(Chessboard *board, const Move *move)
@@ -37,10 +35,10 @@ static void order_moves(Chessboard *board, Move *moves, int count)
3735

3836
// ==================== Quiescence Search ====================
3937

40-
static int quiescence_search(Chessboard *board, int alpha, int beta)
38+
static int quiescence_search(Chessboard *board, int alpha, int beta, SearchInfo *info)
4139
{
4240
int stand_pat = evaluate_position(board);
43-
info.nb_positions_evaluated += 1;
41+
info->nb_positions_evaluated += 1;
4442

4543
if (stand_pat >= beta)
4644
return beta;
@@ -56,7 +54,7 @@ static int quiescence_search(Chessboard *board, int alpha, int beta)
5654
continue;
5755

5856
play_move(board, moves[i]);
59-
int score = -quiescence_search(board, -beta, -alpha);
57+
int score = -quiescence_search(board, -beta, -alpha, info);
6058
unplay_move(board, moves[i]);
6159

6260
if (score >= beta)
@@ -70,10 +68,10 @@ static int quiescence_search(Chessboard *board, int alpha, int beta)
7068

7169
// ==================== Alpha-Beta ====================
7270

73-
int alpha_beta(Chessboard *board, int depth, int alpha, int beta)
71+
int alpha_beta(Chessboard *board, int depth, int alpha, int beta, SearchInfo *info)
7472
{
7573
if (depth == 0)
76-
return quiescence_search(board, alpha, beta);
74+
return quiescence_search(board, alpha, beta, info);
7775

7876
Move moves[250];
7977
int count = get_all_legal_moves(board, moves);
@@ -92,7 +90,7 @@ int alpha_beta(Chessboard *board, int depth, int alpha, int beta)
9290
for (int i = 0; i < count; i++)
9391
{
9492
play_move(board, moves[i]);
95-
int score = -alpha_beta(board, depth - 1, -beta, -alpha);
93+
int score = -alpha_beta(board, depth - 1, -beta, -alpha, info);
9694
unplay_move(board, moves[i]);
9795

9896
if (score > best)
@@ -109,21 +107,21 @@ int alpha_beta(Chessboard *board, int depth, int alpha, int beta)
109107

110108
// ==================== Root Search ====================
111109

112-
static int get_score(Chessboard *board, Move move, int depth)
110+
static int get_score(Chessboard *board, Move move, int depth, SearchInfo *info)
113111
{
114112
play_move(board, move);
115113
int score;
116114

117115
if (depth == 0)
118116
score = evaluate_position(board); // Potentiellement quiecence search au lieu de evaluate mais probablement pas d'impact
119117
else
120-
score = -alpha_beta(board, depth - 1, -INFINI, INFINI);
118+
score = -alpha_beta(board, depth - 1, -INFINI, INFINI, info);
121119

122120
unplay_move(board, move);
123121
return score;
124122
}
125123

126-
static ScoredMove search_best_move(Chessboard *board, int depth)
124+
static ScoredMove search_best_move(Chessboard *board, int depth, SearchInfo *info)
127125
{
128126
Move legal_moves[250];
129127
int nbmoves = get_all_legal_moves(board, legal_moves);
@@ -136,14 +134,11 @@ static ScoredMove search_best_move(Chessboard *board, int depth)
136134

137135
ScoredMove best;
138136
best.move = legal_moves[0];
139-
best.score = get_score(board, legal_moves[0], depth);
137+
best.score = get_score(board, legal_moves[0], depth, info);
140138

141139
for (int i = 1; i < nbmoves; i++)
142140
{
143-
int score = get_score(board, legal_moves[i], depth);
144-
145-
//print_move(&legal_moves[i]);
146-
//printf("score: %i\n", score);
141+
int score = get_score(board, legal_moves[i], depth, info);
147142

148143
if (score > best.score)
149144
{
@@ -152,14 +147,17 @@ static ScoredMove search_best_move(Chessboard *board, int depth)
152147
}
153148
}
154149

155-
//printf("nb_pos: %i, score: %i\n", info.nb_positions_evaluated, best.score);
156-
157150
return best;
158151
}
159152

160-
Move get_best_move(Chessboard board)
153+
SearchInfo get_best_move(Chessboard board)
161154
{
155+
SearchInfo info = {0};
162156
info.nb_positions_evaluated = 0;
163-
ScoredMove best_move = search_best_move(&board, 3);
164-
return best_move.move;
157+
info.depth = 3;
158+
info.log[0] = '\0';
159+
160+
info.move = search_best_move(&board, info.depth, &info);
161+
snprintf(info.log, SEARCH_LOG_SIZE, "depth=%d evaluations=%d", info.depth, info.nb_positions_evaluated);
162+
return info;
165163
}

src/api/api_connector.c

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,64 @@
11
#include "api_connector.h"
2+
#include <sys/time.h>
23

34
static int read_line_timeout(FILE *stream, char *buf, int size, int timeout_sec)
45
{
56
int fd = fileno(stream);
6-
fd_set readfds;
7-
struct timeval tv;
7+
int total = 0;
8+
struct timeval start, now, tv;
89

9-
FD_ZERO(&readfds);
10-
FD_SET(fd, &readfds);
10+
if (size <= 1)
11+
return -3;
1112

12-
tv.tv_sec = timeout_sec;
13-
tv.tv_usec = 0;
13+
if (gettimeofday(&start, NULL) == -1)
14+
return -1;
1415

15-
int ret = select(fd + 1, &readfds, NULL, NULL, &tv);
16-
if (ret == -1)
17-
return -1; // erreur
18-
if (ret == 0)
19-
return -2; // timeout
16+
while (total < size - 1)
17+
{
18+
fd_set readfds;
19+
FD_ZERO(&readfds);
20+
FD_SET(fd, &readfds);
21+
22+
if (gettimeofday(&now, NULL) == -1)
23+
return -1;
24+
25+
long elapsed = now.tv_sec - start.tv_sec;
26+
if (elapsed >= timeout_sec)
27+
return -2;
28+
29+
tv.tv_sec = timeout_sec - elapsed;
30+
tv.tv_usec = 0;
31+
32+
int ret = select(fd + 1, &readfds, NULL, NULL, &tv);
33+
if (ret == -1)
34+
{
35+
if (errno == EINTR)
36+
continue;
37+
return -1;
38+
}
39+
if (ret == 0)
40+
return -2;
41+
42+
char c;
43+
ssize_t n = read(fd, &c, 1);
44+
if (n == 0)
45+
return -3;
46+
if (n == -1)
47+
{
48+
if (errno == EINTR)
49+
continue;
50+
return -3;
51+
}
52+
53+
buf[total++] = c;
54+
if (c == '\n')
55+
break;
56+
}
2057

21-
if (fgets(buf, size, stream) == NULL)
22-
return -3; // EOF ou erreur
58+
buf[total] = '\0';
59+
while (total > 0 && (buf[total - 1] == '\n' || buf[total - 1] == '\r'))
60+
buf[--total] = '\0';
2361

24-
buf[strcspn(buf, "\r\n")] = '\0';
2562
return 0;
2663
}
2764

@@ -86,19 +123,38 @@ int bot_set_fen(BotConnector *bot, const char *fen)
86123
return 0;
87124
}
88125

89-
int bot_get_best_move(BotConnector *bot, char *move_str)
126+
int bot_get_best_move(BotConnector *bot, char *move_str, char *log_msg, int timeout_sec)
90127
{
91128
if (!is_bot_connected(bot))
92129
return -1;
93130

94131
fprintf(bot->bot_in, "get move\n");
95132
fflush(bot->bot_in);
96133

97-
int res = read_line_timeout(bot->bot_out, move_str, MOVE_SIZE, 3); // timeout 3s
98-
134+
int res = read_line_timeout(bot->bot_out, move_str, MOVE_SIZE, timeout_sec);
99135
if (res != 0)
100136
return -1;
101137

138+
// Essayer de lire un message de log optionnel provenant du bot.
139+
// On laisse un petit timeout pour le log afin de ne pas bloquer.
140+
if (log_msg)
141+
{
142+
int res2 = read_line_timeout(bot->bot_out, log_msg, LOG_SIZE, 1);
143+
if (res2 != 0)
144+
log_msg[0] = '\0';
145+
else
146+
{
147+
// Attendu: ligne de log préfixée par "LOG:". Si présent, on strip le préfixe.
148+
if (strncmp(log_msg, "LOG:", 4) == 0)
149+
{
150+
char *p = log_msg + 4;
151+
while (*p == ' ')
152+
p++;
153+
memmove(log_msg, p, strlen(p) + 1);
154+
}
155+
}
156+
}
157+
102158
return 0;
103159
}
104160

src/api_bot.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
int is_bot_killed(char *command, size_t size)
1313
{
1414
if (fgets(command, size, stdin) == NULL)
15-
return 1;
15+
return 1;
1616

1717
command[strcspn(command, "\r\n")] = '\0';
1818

@@ -26,9 +26,11 @@ void handle_commands(const char *command, Chessboard *board, char *fen)
2626
{
2727
if (strncmp(command, "get move", 8) == 0)
2828
{
29-
Move best_move = get_best_move(*board);
30-
print_move(&best_move);
29+
SearchInfo infos = get_best_move(*board);
30+
print_move(&infos.move.move);
3131
printf("\n");
32+
if (infos.log[0] != '\0')
33+
printf("LOG:%s\n", infos.log);
3234
fflush(stdout);
3335
}
3436
else if (strncmp(command, "fen ", 4) == 0)

src/ui/rendering.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,11 +440,15 @@ static int load_positions(OpeningBook *book)
440440
static int get_and_play_best_move(int color, GameEnvironement env)
441441
{
442442
char best_move[MOVE_SIZE];
443+
char bot_log[256];
443444
BotConnector *bot = color == WHITE ? env.bot1 : env.bot2;
444445

445-
if (bot_get_best_move(bot, best_move) != 0)
446+
if (bot_get_best_move(bot, best_move, bot_log, 3) != 0)
446447
return 1;
447448

449+
if (bot_log[0] != '\0')
450+
printf("Bot log: %s\n", bot_log);
451+
448452
Move move = get_move(best_move);
449453
play_move_all(env, move);
450454

tests/test_api_connector.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@ Test(api_connector, connect_and_get_move)
1515
printf("TEST BOT API (STARTPOS)... \n");
1616
BotConnector bot;
1717
char best_move[6];
18+
char log_msg[LOG_SIZE];
1819

1920
int res = bot_connect(&bot, bot_path);
2021
cr_assert_eq(res, 0, "Échec de la connexion au bot");
2122

2223
// Demande du meilleur coup
23-
res = bot_get_best_move(&bot, best_move);
24+
res = bot_get_best_move(&bot, best_move, log_msg, 3);
2425
cr_assert_eq(res, 0, "bot_get_best_move a échoué");
2526
cr_assert_neq(best_move[0], '\0', "Le bot n’a pas renvoyé de coup");
2627

@@ -37,6 +38,7 @@ Test(api_connector, reconnect_after_disconnect)
3738
{
3839
BotConnector bot;
3940
char best_move[MOVE_SIZE];
41+
char log_msg[LOG_SIZE];
4042

4143
int res = bot_connect(&bot, bot_path);
4244
cr_assert_eq(res, 0);
@@ -46,7 +48,7 @@ Test(api_connector, reconnect_after_disconnect)
4648
res = bot_connect(&bot, bot_path);
4749
cr_assert_eq(res, 0);
4850

49-
res = bot_get_best_move(&bot, best_move);
51+
res = bot_get_best_move(&bot, best_move, log_msg, 3);
5052
cr_assert_eq(res, 0);
5153
cr_assert_neq(best_move[0], '\0', "Le bot n’a pas renvoyé de coup");
5254

0 commit comments

Comments
 (0)