/* * engine.h -- interface C du moteur de backgammon d'Ustagammon. * * Copyright (C) 2026 les auteurs d'Ustagammon. * Licence : GPLv3 ou ultérieure (voir LICENSE). * * Le moteur est le cœur de GNU Backgammon (engine/gnubg/), seule autorité * pour les règles, les coups, le videau et les évaluations. Cette interface * n'expose aucun type de gnubg. * * Positions : une position est décrite par deux identifiants de gnubg, * - le Position ID (14 caractères), qui code le plateau du point de vue du * joueur au trait ; * - le Match ID (12 caractères), qui code le reste : longueur du match (0 en * partie libre), score, videau et son propriétaire, joueur au trait, * Crawford, Jacoby. Les dés éventuellement codés dans le Match ID sont * ignorés : les dés sont passés à part. * * Niveaux (« ply ») : réglages prédéfinis de gnubg, sans bruit, de 0 * (évaluation statique du réseau) à 4. gnubg compte les plis à partir de 0. * * Équités : toujours du point de vue du joueur au trait, normalisées pour * un videau de 1. En match, gnubg convertit les chances de gain du match en * équité normalisée, comme il l'affiche par défaut. * * Probabilités, dans l'ordre de gnubg : gain, gain gammon, gain backgammon, * perte gammon, perte backgammon (les gammons incluent les backgammons). * * Contraintes : une seule instance du moteur (état global de gnubg) et des * appels sérialisés, jamais concurrents. Toutes les fonctions renvoient un * code engine_status ; aucune ne termine le programme pour une erreur * d'utilisation. */ #ifndef USTAGAMMON_ENGINE_H #define USTAGAMMON_ENGINE_H #ifdef __cplusplus extern "C" { #endif typedef enum { ENGINE_OK = 0, ENGINE_ERROR_NOT_INITIALISED, /* engine_init n'a pas réussi */ ENGINE_ERROR_DATA, /* données absentes ou invalides */ ENGINE_ERROR_POSITION_ID, /* Position ID invalide */ ENGINE_ERROR_MATCH_ID, /* Match ID invalide */ ENGINE_ERROR_DICE, /* dés hors de 1..6 */ ENGINE_ERROR_PLY, /* niveau hors de 0..ENGINE_MAX_PLY */ ENGINE_ERROR_TOO_MANY_MOVES, /* tableau de coups trop petit */ ENGINE_ERROR_INTERNAL /* échec signalé par gnubg */ } engine_status; #define ENGINE_MAX_PLY 4 /* Nombre maximal de coups légaux pour un jet (MAX_MOVES de gnubg). */ #define ENGINE_MAX_MOVES 3060 /* Indices du tableau probabilities. */ enum { ENGINE_WIN = 0, ENGINE_WIN_GAMMON, ENGINE_WIN_BACKGAMMON, ENGINE_LOSE_GAMMON, ENGINE_LOSE_BACKGAMMON, ENGINE_NUM_PROBABILITIES }; /* Un coup, avec son évaluation quand il a été classé. */ typedef struct { char notation[32]; /* notation de gnubg, ex. « 8/5 6/5 » */ char position_id[16]; /* Position ID après le coup, plateau vu du * joueur qui vient de jouer */ int ply; /* niveau de l'évaluation (-1 : non évalué) */ float probabilities[ENGINE_NUM_PROBABILITIES]; float equity; /* équité de classement (avec videau) */ } engine_move; /* Évaluation d'une position, joueur au trait avant de lancer les dés. */ typedef struct { float probabilities[ENGINE_NUM_PROBABILITIES]; float cubeless_equity; /* équité sans videau */ float cubeful_equity; /* équité avec videau */ } engine_evaluation; /* Décision de videau du joueur au trait, avant de lancer les dés. */ typedef struct { float probabilities[ENGINE_NUM_PROBABILITIES]; float no_double; /* équité si pas de double */ float double_take; /* équité si double et prend */ float double_pass; /* équité si double et passe */ float optimal; /* équité après les meilleures décisions des deux * joueurs */ const char *decision; /* nom de la décision dans l'énumération * cubedecision de gnubg : « NODOUBLE_TAKE », * « DOUBLE_TAKE », « DOUBLE_PASS », * « TOOGOOD_PASS », « NOT_AVAILABLE »… */ const char *decision_text; /* libellé anglais de gnubg, ex. « Double, take » */ } engine_cube; /* Description lisible d'un Match ID décodé. */ typedef struct { int match_length; /* 0 : partie libre (money game) */ int score[2]; int cube_value; int cube_owner; /* -1 : videau au centre ; sinon 0 ou 1 */ int player_on_roll; /* 0 ou 1 */ int crawford; /* partie Crawford en cours */ int jacoby; /* règle Jacoby (partie libre) */ } engine_match; /* * Charge les données du moteur depuis data_dir : gnubg.wd (réseaux), * gnubg_os0.bd et gnubg_ts0.bd (fins de partie), Kazaross-XG2.xml (table * d'équité de match). À appeler une fois avant toute autre fonction. */ engine_status engine_init(const char *data_dir); /* Libère les ressources. Le moteur ne peut pas être réinitialisé ensuite. */ void engine_shutdown(void); /* Message d'erreur en français pour un code de retour. */ const char *engine_status_message(engine_status status); /* Décode un Match ID. */ engine_status engine_decode_match(const char *match_id, engine_match *match); /* * Coups légaux pour une position et un jet (die1, die2 dans 1..6), sans * évaluation (ply vaut -1). moves doit pouvoir contenir max_moves coups ; * ENGINE_MAX_MOVES suffit toujours. *count reçoit le nombre de coups (0 si * le joueur ne peut pas jouer). */ engine_status engine_legal_moves(const char *position_id, const char *match_id, int die1, int die2, engine_move *moves, int max_moves, int *count); /* * Coups légaux classés du meilleur au moins bon, au niveau ply, exactement * comme la commande « hint » de gnubg (filtre de coups « Normal »). Les coups * écartés par les filtres gardent l'évaluation du niveau inférieur (voir * leur champ ply) et sont classés après ceux évalués plus profondément. */ engine_status engine_best_moves(const char *position_id, const char *match_id, int die1, int die2, int ply, engine_move *moves, int max_moves, int *count); /* Évaluation d'une position au niveau ply. */ engine_status engine_evaluate(const char *position_id, const char *match_id, int ply, engine_evaluation *evaluation); /* Décision de videau au niveau ply. */ engine_status engine_cube_decision(const char *position_id, const char *match_id, int ply, engine_cube *cube); #ifdef __cplusplus } #endif #endif /* USTAGAMMON_ENGINE_H */