diff --git a/tests/test_engine.sh b/tests/test_engine.sh index d733699..d13b4d2 100644 --- a/tests/test_engine.sh +++ b/tests/test_engine.sh @@ -2,7 +2,8 @@ # Tests du moteur embarqué, via build/engine-cli (étape 0a.3) : # meilleurs coups d'ouverture connus, nombre de coups légaux, bornes et # symétrie des probabilités, décision de videau évidente, identifiants -# invalides. La comparaison systématique au gnubg de bureau est faite par +# invalides, niveaux de jeu (bruit reproductible), analyses et chance. La +# comparaison systématique au gnubg de bureau est faite par # tests/test_engine_reference.sh. # # Lance `make engine` (sans effet si tout est à jour). @@ -219,6 +220,50 @@ grep -qF '"available": true, "double": true, "take": false' <<<"$($cli cube "$co grep -qF '"available": false, "double": false' <<<"$($cli cube "$course" "$(valeur match_id "$($cli matchid 2 1)")")" \ || echouer "videau chez l'adversaire : double indisponible attendu" +# Niveaux de jeu : les neuf réglages de gnubg, seuils exposés. +sortie="$($cli levels)" +[ "$(grep -o '"name"' <<<"$sortie" | wc -l)" = 9 ] || echouer "levels : 9 niveaux attendus" +grep -qF '"name": "beginner", "plies": 0, "noise": 0.0599999987' <<<"$sortie" \ + || echouer "levels : réglage débutant inattendu" +grep -qF '"skill_thresholds": {"doubtful": 0.0299999993, "bad": 0.0599999987, "very_bad": 0.119999997}' \ + <<<"$sortie" || echouer "levels : seuils d'appréciation inattendus" +# Le bruit est déterministe : le même coup à chaque appel, et le bruit change +# le coup de cette position (vérifié contre gnubg par analysis/level-*.json). +milieu=mM/gATCw5+ABMA +milieu_mid=cAkTAAAAAAAA +for essai in 1 2 3; do + coup="$(valeur move "$($cli --level beginner bestmove "$milieu" "$milieu_mid" 64)")" + [ "$coup" = "24/20 24/18" ] || echouer "niveau débutant, essai $essai : « $coup »" +done +coup="$(valeur move "$($cli --level 0ply bestmove "$milieu" "$milieu_mid" 64)")" +[ "$coup" = "24/14" ] || echouer "niveau 0 pli : « $coup » au lieu de 24/14" +grep -qF '"level": "advanced"' <<<"$($cli --level advanced cube "$depart" "$libre_j0")" \ + || echouer "cube au niveau avancé : niveau absent de la réponse" +attendre_erreur usage --level champion bestmove "$depart" "$libre_j0" 31 +attendre_erreur usage --level beginner --ply 2 bestmove "$depart" "$libre_j0" 31 +attendre_erreur usage --level beginner eval "$depart" "$libre_j0" + +# Analyse d'un coup : le meilleur coup n'est pas une erreur ; un coup illégal +# est refusé ; sans coup possible, rien à analyser. +sortie="$($cli analysemove "$depart" "$libre_j0" 31 4HPwATCwZ/ABMA)" +[ "$(valeur rank "$sortie") $(valeur skill "$sortie")" = "1 none" ] \ + || echouer "analysemove 8/5 6/5 : rang 1 sans erreur attendus ($sortie)" +attendre_erreur invalid_move analysemove "$depart" "$libre_j0" 31 "$depart" +grep -qF '"move_count": 0, "rank": null' <<<"$($cli analysemove 27YBBwAcz8EDQA cIkWAAAAAAAA 55 27YBBwAcz8EDQA)" \ + || echouer "analysemove sans coup possible : move_count 0 attendu" + +# Analyse du videau : décision inconnue refusée ; pas d'analyse quand le +# joueur au trait ne peut pas doubler. +attendre_erreur usage analysecube "$depart" "$libre_j0" redouble +grep -qF '"analysed": false, "cube": null, "equity_loss": 0, "skill": "none"' \ + <<<"$($cli analysecube "$course" "$(valeur match_id "$($cli matchid 2 1)")" no_double)" \ + || echouer "analysecube, videau chez l'adversaire : pas d'analyse attendue" + +# Chance : même jet, même chance ; ordre des dés indifférent. +[ "$($cli luck "$milieu" "$milieu_mid" 64 | sed 's/"dice": \[[0-9], [0-9]\]//')" \ + = "$($cli luck "$milieu" "$milieu_mid" 46 | sed 's/"dice": \[[0-9], [0-9]\]//')" ] \ + || echouer "luck : l'ordre des dés change la chance" + if [ "$echecs" -gt 0 ]; then echo " $echecs vérification(s) du moteur en échec." exit 1