testsAndMisc/C/opening_learner/mistakes.c

103 lines
2.6 KiB
C
Raw Normal View History

2025-09-08 16:58:17 +02:00
#include "mistakes.h"
2025-11-01 20:11:45 +01:00
#include <stdio.h>
2025-09-08 16:58:17 +02:00
#include <stdlib.h>
#include <string.h>
2025-11-01 20:11:45 +01:00
void mistakes_init(MistakeList *ml)
{
ml->items = NULL;
ml->count = 0;
ml->cap = 0;
2025-09-08 16:58:17 +02:00
}
2025-11-01 20:11:45 +01:00
void mistakes_free(MistakeList *ml)
{
free(ml->items);
ml->items = NULL;
ml->count = ml->cap = 0;
2025-09-08 16:58:17 +02:00
}
2025-11-01 20:11:45 +01:00
static void ensure_cap(MistakeList *ml, size_t need)
{
if (need <= ml->cap)
return;
size_t ncap = ml->cap ? ml->cap * 2 : 16;
while (ncap < need)
ncap *= 2;
2025-09-08 16:58:17 +02:00
Mistake *ni = realloc(ml->items, ncap * sizeof(Mistake));
2025-11-01 20:11:45 +01:00
if (!ni)
return; // OOM silently ignored
ml->items = ni;
ml->cap = ncap;
2025-09-08 16:58:17 +02:00
}
2025-11-01 20:11:45 +01:00
void mistakes_add(MistakeList *ml, const MistakeEntry *entry)
{
ensure_cap(ml, ml->count + 1);
2025-09-08 16:58:17 +02:00
Mistake *m = &ml->items[ml->count++];
2025-11-01 20:11:45 +01:00
(void)snprintf(m->fen, sizeof(m->fen), "%s", entry->fen);
(void)snprintf(m->best_move, sizeof(m->best_move), "%s", entry->best_move);
(void)snprintf(m->line, sizeof(m->line), "%s", entry->line);
2025-09-08 16:58:17 +02:00
}
2025-11-01 20:11:45 +01:00
bool mistakes_save(const MistakeList *ml, const char *path)
{
2025-09-08 16:58:17 +02:00
FILE *f = fopen(path, "w");
2025-11-01 20:11:45 +01:00
if (!f)
return false;
for (size_t i = 0; i < ml->count; i++)
{
2025-09-08 16:58:17 +02:00
const Mistake *m = &ml->items[i];
2025-11-01 20:11:45 +01:00
(void)fprintf(f, "FEN:%s\nBEST:%s\nLINE:%s\n.\n", m->fen, m->best_move, m->line);
2025-09-08 16:58:17 +02:00
}
2025-11-01 20:11:45 +01:00
(void)fclose(f);
return true;
2025-09-08 16:58:17 +02:00
}
2025-11-01 20:11:45 +01:00
bool mistakes_load(MistakeList *ml, const char *path)
{
2025-09-08 16:58:17 +02:00
FILE *f = fopen(path, "r");
2025-11-01 20:11:45 +01:00
if (!f)
return false;
char buf[1024];
char fen[128] = "";
char best[16] = "";
char line[512] = "";
while (fgets(buf, sizeof(buf), f))
{
if (strncmp(buf, "FEN:", 4) == 0)
{
2025-09-08 16:58:17 +02:00
// copy up to 127 chars, strip newline
2025-11-01 20:11:45 +01:00
size_t l = strcspn(buf + 4, "\n");
if (l >= sizeof(fen))
l = sizeof(fen) - 1;
memcpy(fen, buf + 4, l);
fen[l] = '\0';
}
else if (strncmp(buf, "BEST:", 5) == 0)
{
size_t l = strcspn(buf + 5, "\n");
if (l >= sizeof(best))
l = sizeof(best) - 1;
memcpy(best, buf + 5, l);
best[l] = '\0';
}
else if (strncmp(buf, "LINE:", 5) == 0)
{
size_t l = strcspn(buf + 5, "\n");
if (l >= sizeof(line))
l = sizeof(line) - 1;
memcpy(line, buf + 5, l);
line[l] = '\0';
}
else if (buf[0] == '.')
{
MistakeEntry entry = {.fen = fen, .best_move = best, .line = line};
mistakes_add(ml, &entry);
fen[0] = best[0] = line[0] = '\0';
2025-09-08 16:58:17 +02:00
}
}
2025-11-01 20:11:45 +01:00
(void)fclose(f);
return true;
2025-09-08 16:58:17 +02:00
}