Joueur IA Escampe (Puyaubreau/Russac) — version finale

Joueur alpha-bêta + iterative deepening pour le tournoi APP5 « IA et contraintes ».

- src/escampe/ : joueur (IJoueur), moteur (alpha-bêta + DFS bitmask, make/unmake
  sans allocation), modèle EscampeBoard (Partie1), utilitaires de test.
- Protocole arbitre vérifié (pass="E", carte des liserés identique au serveur,
  machine à états placement/jeu) ; 7/7 victoires vs joueur aléatoire, 0 illégal.
- Vérifications : VerifMoves (int≡String, 0 divergence/142k positions),
  RulesTest (21/21), Branching (facteur de branchement mesuré).
- Rapport : report/rapport.html + tools/make_report_pdf.py (PyMuPDF) → PDF, RAPPORT.md.
- Livrables buildés inclus (dist/ : jar, mainClass, tgz, rapport PDF) + lib/escampeobf.jar.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-30 16:00:29 +02:00
commit e508efa14f
50 changed files with 6521 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
#!/bin/bash
# Lot de parties arbitrées contre JoueurAleatoire, alternant les couleurs.
# Convention observée : le 1er connecté = JOUEUR 1 = Blanc, le 2e = JOUEUR 2 = Noir.
# Donc : moi en joueur A => je suis Blanc ; moi en joueur B => je suis Noir.
#
# usage: bench_vs_random.sh [N_par_couleur] [sliceMs]
set -u
ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
N="${1:-3}"; SLICE="${2:-300}"
JAR="$ROOT/lib/escampeobf.jar"; [ -f "$JAR" ] || JAR="C:/Users/Kerboul/Downloads/escampeobf.jar"
ME="escampe.JoueurPuyaubreauRussac"; RND="escampe.JoueurAleatoire"
LOG="$ROOT/scripts/logs"
port=1300; wins=0; losses=0; illegal=0; exc=0; games=0
play() { # $1 = ma couleur attendue (Blanc|Noir)
port=$((port+1)); games=$((games+1))
if [ "$1" = "Blanc" ]; then
OPTS_A="-Descampe.maxSliceMs=$SLICE" OPTS_B="" \
bash scripts/match.sh "$ME" out "$RND" "$JAR" "$port" 45 >/dev/null 2>&1
else
OPTS_A="" OPTS_B="-Descampe.maxSliceMs=$SLICE" \
bash scripts/match.sh "$RND" "$JAR" "$ME" out "$port" 45 >/dev/null 2>&1
fi
local winner; winner=$(grep -aoE "FIN! (Blanc|Noir)" "$LOG/server.log" | tail -1 | awk '{print $2}')
local il; il=$(grep -ac "illegal" "$LOG/server.log"); il=${il//[^0-9]/}; il=${il:-0}
illegal=$((illegal + il))
# exception côté MON client (A si Blanc, B si Noir)
local mylog; [ "$1" = "Blanc" ] && mylog="$LOG/playerA.log" || mylog="$LOG/playerB.log"
if grep -aqiE "exception|\bat escampe\." "$mylog" 2>/dev/null; then exc=$((exc+1)); fi
if [ "$winner" = "$1" ]; then wins=$((wins+1)); R=GAGNE; else losses=$((losses+1)); R=perdu; fi
echo " partie $games : moi=$1 vainqueur=$winner -> $R"
}
echo "=== $N parties en Blanc, $N en Noir (slice ${SLICE}ms) ==="
for i in $(seq 1 "$N"); do play Blanc; done
for i in $(seq 1 "$N"); do play Noir; done
echo "-------------------------------------------"
echo "Victoires : $wins / $games"
echo "Défaites : $losses"
echo "Coups illégaux (arbitre) : $illegal"
echo "Exceptions dans mon client : $exc"

51
scripts/match.sh Normal file
View File

@@ -0,0 +1,51 @@
#!/bin/bash
# Lance une partie ARBITRÉE entre deux IJoueur via le serveur réseau fourni.
#
# usage: match.sh [CLASS_A] [CP_A] [CLASS_B] [CP_B] [PORT] [TIMEOUT_S]
#
# Par défaut : notre joueur (depuis out/) contre escampe.JoueurAleatoire (jar).
# Le serveur (escampe.ServeurJeu) et les adversaires de référence vivent dans
# escampeobf.jar, fourni séparément (hors livrable). Seules des chaînes de
# caractères circulent sur le réseau : la divergence d'interface obfusquée
# entre le jar et nos sources est donc sans effet.
set -u
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT"
# Jar arbitre : dans le repo (lib/) en priorité, sinon dans Downloads.
JAR="$ROOT/lib/escampeobf.jar"
[ -f "$JAR" ] || JAR="C:/Users/Kerboul/Downloads/escampeobf.jar"
CLA="${1:-escampe.JoueurPuyaubreauRussac}"; CPA="${2:-out}"
CLB="${3:-escampe.JoueurAleatoire}"; CPB="${4:-$JAR}"
PORT="${5:-1234}"; TMO="${6:-60}"
OPTS_A="${OPTS_A:-}" # options JVM pour le joueur A (ex: -Descampe.debug=true)
OPTS_B="${OPTS_B:-}"
LOG="$ROOT/scripts/logs"; mkdir -p "$LOG"; rm -f "$LOG"/*.log
echo "Serveur : ServeurJeu $PORT 1"
echo "Joueur A : $CLA (cp=$CPA)"
echo "Joueur B : $CLB (cp=$CPB)"
echo "----------------------------------------"
java -cp "$JAR" escampe.ServeurJeu "$PORT" 1 > "$LOG/server.log" 2>&1 &
SRV=$!
sleep 2
java $OPTS_A -cp "$CPA" escampe.ClientJeu "$CLA" localhost "$PORT" > "$LOG/playerA.log" 2>&1 &
A=$!
sleep 1
java $OPTS_B -cp "$CPB" escampe.ClientJeu "$CLB" localhost "$PORT" > "$LOG/playerB.log" 2>&1 &
B=$!
# Chien de garde : tue tout après TMO secondes si la partie ne se termine pas.
( sleep "$TMO"; kill $A $B $SRV 2>/dev/null ) & WATCH=$!
wait $A 2>/dev/null
wait $B 2>/dev/null
kill $SRV 2>/dev/null
kill $WATCH 2>/dev/null
echo "=== SERVER ==="; cat "$LOG/server.log"
echo; echo "=== PLAYER A ($CLA) ==="; cat "$LOG/playerA.log"
echo; echo "=== PLAYER B ($CLB) ==="; cat "$LOG/playerB.log"