Moteur : classement de l'analyse d'un coup, comme gnubg de bureau
engine_analyse_move rend les dix premiers coups de la liste de l'analyse, chacun au niveau où gnubg l'a évalué, et refait d'abord l'analyse de la chance comme AnalyzeMove : son cache change les coups restés à 0 pli. Les références d'analyse gagnent le niveau de chaque coup du classement, comparé par compare.py. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c42316d9d8
commit
1d21ac15d2
+31
-9
@@ -512,6 +512,8 @@ engine_level_best_moves(const char *position_id, const char *match_id, int die1,
|
||||
|
||||
/* ------------------------------------------------- Analyse d'un coup joué */
|
||||
|
||||
static float luck_analysis(const char *position_id, position *pos, int die1, int die2);
|
||||
|
||||
engine_status
|
||||
engine_analyse_move(const char *position_id, const char *match_id, int die1, int die2,
|
||||
const char *played_position_id, int ply, engine_move_analysis *analysis)
|
||||
@@ -546,6 +548,17 @@ engine_analyse_move(const char *position_id, const char *match_id, int die1, int
|
||||
* premier.
|
||||
*/
|
||||
memset(analysis, 0, sizeof *analysis);
|
||||
/*
|
||||
* gnubg analyse la chance du jet juste avant le coup (AnalyzeMove,
|
||||
* l. 679-682), à 0 pli sans élagage, et garde ces évaluations dans son
|
||||
* cache, qui ne distingue pas une évaluation à 0 pli avec ou sans
|
||||
* réseaux d'élagage : le tri à 0 pli de FindnSaveBestMoves les reprend
|
||||
* ensuite, ce qui change l'équité des coups restés à 0 pli, et parfois
|
||||
* ceux que les filtres retiennent. Faire de même, sans garder le
|
||||
* résultat, donne le classement de gnubg de bureau.
|
||||
*/
|
||||
if (luck_analysis(position_id, &pos, die1, die2) == ERR_VAL)
|
||||
return ENGINE_ERROR_INTERNAL;
|
||||
if (FindnSaveBestMoves(&list, die1, die2, (ConstTanBoard) pos.board, &played_key, TRUE,
|
||||
DOUBTFUL_THRESHOLD, &pos.cube, &context,
|
||||
aaamfMoveFilterSettings[0]) < 0)
|
||||
@@ -565,6 +578,10 @@ engine_analyse_move(const char *position_id, const char *match_id, int die1, int
|
||||
status = ENGINE_OK;
|
||||
break;
|
||||
}
|
||||
/* Le classement : le début de la même liste, dans l'ordre de gnubg. */
|
||||
for (i = 0; i < list.cMoves && i < ENGINE_ANALYSIS_RANKING; i++)
|
||||
fill_move(&analysis->ranking[i], &list.amMoves[i], &pos, 1);
|
||||
analysis->ranking_count = (int) i;
|
||||
g_free(list.amMoves);
|
||||
return status;
|
||||
}
|
||||
@@ -1005,13 +1022,25 @@ luck_first(ConstTanBoard board, int i0, int j0, cubeinfo *cube)
|
||||
return equities[i0][j0] - mean / 30.0f;
|
||||
}
|
||||
|
||||
/* LuckAnalysis (analysis.c l. 252-268) : dés rangés du plus fort au plus
|
||||
* faible ; LuckFirst à la position de départ hors doubles. */
|
||||
static float
|
||||
luck_analysis(const char *position_id, position *pos, int die1, int die2)
|
||||
{
|
||||
int high = (die1 > die2 ? die1 : die2) - 1;
|
||||
int low = (die1 > die2 ? die2 : die1) - 1;
|
||||
|
||||
if (strcmp(position_id, START_POSITION_ID) == 0 && high != low)
|
||||
return luck_first((ConstTanBoard) pos->board, high, low, &pos->cube);
|
||||
return luck_normal((ConstTanBoard) pos->board, high, low, &pos->cube);
|
||||
}
|
||||
|
||||
engine_status
|
||||
engine_luck_of(const char *position_id, const char *match_id, int die1, int die2,
|
||||
engine_luck *luck)
|
||||
{
|
||||
position pos;
|
||||
engine_status status;
|
||||
int high, low;
|
||||
float value;
|
||||
|
||||
status = decode_position(position_id, match_id, &pos);
|
||||
@@ -1021,14 +1050,7 @@ engine_luck_of(const char *position_id, const char *match_id, int die1, int die2
|
||||
return status;
|
||||
start_evaluation();
|
||||
|
||||
/* LuckAnalysis (analysis.c l. 252-268) : dés rangés du plus fort au plus
|
||||
* faible ; LuckFirst à la position de départ hors doubles. */
|
||||
high = (die1 > die2 ? die1 : die2) - 1;
|
||||
low = (die1 > die2 ? die2 : die1) - 1;
|
||||
if (strcmp(position_id, START_POSITION_ID) == 0 && high != low)
|
||||
value = luck_first((ConstTanBoard) pos.board, high, low, &pos.cube);
|
||||
else
|
||||
value = luck_normal((ConstTanBoard) pos.board, high, low, &pos.cube);
|
||||
value = luck_analysis(position_id, &pos, die1, die2);
|
||||
if (value == ERR_VAL)
|
||||
return ENGINE_ERROR_INTERNAL;
|
||||
luck->luck = value;
|
||||
|
||||
+21
-1
@@ -207,6 +207,10 @@ typedef struct {
|
||||
* (double_take <= double_pass) */
|
||||
} engine_cube;
|
||||
|
||||
/* Coups gardés dans le classement d'une analyse : les dix premiers, comme
|
||||
* les positions de référence (tests/reference/README.md). */
|
||||
#define ENGINE_ANALYSIS_RANKING 10
|
||||
|
||||
/* Analyse d'un coup joué, comme l'analyse de partie de gnubg. */
|
||||
typedef struct {
|
||||
int move_count; /* nombre de coups légaux (0 : aucun coup
|
||||
@@ -218,6 +222,14 @@ typedef struct {
|
||||
float equity_loss; /* équité du coup joué moins celle du meilleur :
|
||||
* 0 ou négative */
|
||||
engine_skill skill; /* appréciation de gnubg pour cette perte */
|
||||
/* Le classement de l'analyse, du meilleur au moins bon : les premiers
|
||||
* coups de la liste que gnubg garde pour l'analyse de partie (ce que
|
||||
* montre son panneau d'analyse), chacun au niveau où gnubg l'a
|
||||
* évalué. Le meilleur coup et le coup joué y ont les mêmes évaluations
|
||||
* que best et played ; le coup joué n'y figure que s'il est parmi les
|
||||
* premiers. */
|
||||
engine_move ranking[ENGINE_ANALYSIS_RANKING];
|
||||
int ranking_count;
|
||||
} engine_move_analysis;
|
||||
|
||||
/* Analyse d'une décision de videau, comme l'analyse de partie de gnubg. */
|
||||
@@ -452,7 +464,15 @@ engine_luck_rating engine_luck_rating_of(float luck);
|
||||
* Analyse le coup joué par le joueur au trait avec le jet die1, die2, au
|
||||
* niveau ply, comme l'analyse de partie de gnubg (AnalyzeMove dans
|
||||
* analysis.c : FindnSaveBestMoves avec le coup joué, seuil « douteux »,
|
||||
* filtre « Normal », sans RefreshMoveList). played_position_id est la
|
||||
* filtre « Normal », sans RefreshMoveList), classement compris.
|
||||
*
|
||||
* Niveaux : gnubg n'évalue au niveau ply que les coups retenus par ses
|
||||
* filtres ; les autres gardent l'évaluation d'un niveau inférieur (champ
|
||||
* ply de chaque coup, même convention que gnubg de bureau : 0 = statique).
|
||||
* Si un seul coup passe le filtre du niveau ply - 1, gnubg s'arrête là, et
|
||||
* tout le classement reste à ce niveau, sauf quand le coup joué est une
|
||||
* erreur (écart au meilleur supérieur au seuil « douteux ») : le meilleur
|
||||
* coup et le coup joué sont alors réévalués au niveau ply. played_position_id est la
|
||||
* position après le coup, vue du joueur qui vient de le jouer (champ
|
||||
* position_id d'engine_move). ENGINE_ERROR_MOVE si ce n'est pas un coup
|
||||
* légal ; si aucun coup n'est possible, move_count vaut 0.
|
||||
|
||||
Reference in New Issue
Block a user