CPGE MP / PSI · Informatique · 2ᵉ période

Introduction à la théorie des jeux

Pr. EL HADIQ Zouhair

Jeux d'accessibilité à deux joueurs sur un graphe biparti : positions gagnantes, attracteurs, stratégies gagnantes et algorithme Minimax.

Objectifs du chapitre

Sommaire

  1. Théorie des jeux et lien avec les graphes
  2. Jeux d'accessibilité à deux joueurs
  3. Modélisation par un graphe biparti
  4. Positions gagnantes : l'attracteur
  5. Construction des stratégies gagnantes
  6. Détermination du jeu & partition des positions
  7. L'algorithme Minimax avec heuristique
  8. Récapitulatif

1. Théorie des jeux et lien avec les graphes

La théorie des jeux étudie les situations où plusieurs joueurs prennent des décisions qui s'influencent mutuellement, chacun cherchant à atteindre son propre objectif. On se limite ici à une famille particulièrement liée à la théorie des graphes : les jeux d'accessibilité (reachability games) à deux joueurs.

L'idée clé : la situation du jeu à un instant donné est une position (un sommet d'un graphe), et un coup consiste à se déplacer le long d'un arc vers une nouvelle position. Le déroulement d'une partie est donc un chemin dans un graphe orienté. Résoudre le jeu revient à étudier ce graphe.

Idée clé. Un jeu d'accessibilité = un graphe orienté + une partition des sommets entre les deux joueurs + un ensemble de positions à atteindre. Tout le vocabulaire « jeu » se traduit en vocabulaire « graphe ».

2. Jeux d'accessibilité à deux joueurs

On considère deux joueurs : le Joueur 0 (appelons-le Atteignant) et le Joueur 1 (Adversaire). Le Joueur 0 cherche à atteindre un ensemble de positions cibles ; le Joueur 1 cherche à l'en empêcher (éviter indéfiniment ces positions).

Les ingrédients du jeu :

Notion (jeu) Définition
Position (état)Un sommet du graphe. C'est l'état courant du jeu.
État initialLa position v0 où commence la partie.
États gagnants (cible)L'ensemble F des positions à atteindre. Si la partie y arrive, le Joueur 0 gagne.
CoupUn arc (u → v). Le joueur qui contrôle u choisit le successeur v.
PartieUne suite v0, v1, v2, … de positions reliées par des arcs (un chemin).
StratégieUne règle indiquant, pour chaque position contrôlée par un joueur, le coup à jouer.
Convention. Le Joueur 0 gagne une partie si elle atteint une position de F. Sinon (la partie reste hors de F pour toujours), c'est le Joueur 1 qui gagne.

3. Modélisation par un graphe biparti

Comme les deux joueurs jouent à tour de rôle, on partitionne les positions selon le joueur qui doit jouer. On obtient une arène (graphe du jeu) :

G = (V0 ∪ V1, E)  avec  V0 ∩ V1 = ∅

Lorsque les joueurs alternent strictement (chaque arc va de V0 vers V1 ou de V1 vers V0), le graphe est biparti : aucun arc ne relie deux positions du même joueur. C'est le cadre étudié dans ce chapitre.

Hypothèse de jeu infini. Pour simplifier, on suppose qu'il y a toujours au moins un coup possible (pas de cul-de-sac), ou bien on convient qu'un joueur bloqué perd. Une partie est alors un chemin (potentiellement infini) dans G.

4. Positions gagnantes : l'attracteur

Une position est gagnante pour le Joueur 0 si, en partant de cette position, le Joueur 0 possède une manière de jouer qui force l'arrivée dans F, quoi que fasse le Joueur 1. L'ensemble de ces positions est l'attracteur de F pour le Joueur 0, noté Attr0(F).

Construction par couches (point fixe)

On construit l'attracteur de proche en proche. On note Attrk l'ensemble des positions à partir desquelles le Joueur 0 peut forcer l'arrivée dans F en au plus k coups.

Initialisation : Attr0 = F (on y est déjà).

Récurrence : on ajoute une position u à la couche suivante si :

u appartient à… Condition pour ajouter u
V0 (le Joueur 0 choisit)il existe un successeur déjà dans Attrk. (∃)
V1 (le Joueur 1 choisit)tous les successeurs sont déjà dans Attrk. (∀)

Formellement :

Attrk+1 = Attrk ∪ { u ∈ V0 : ∃ (u→v) ∈ E, v ∈ Attrk } ∪ { u ∈ V1 : ∀ (u→v) ∈ E, v ∈ Attrk }

La suite (Attrk) est croissante et bornée par V : elle se stabilise. La limite est l'attracteur :

Attr0(F) = ⋃k ≥ 0 Attrk

Lecture. Sur une position du Joueur 0, il suffit d'UNE bonne issue (il choisit). Sur une position du Joueur 1, il faut que TOUTES les issues soient déjà gagnantes (il choisira la pire pour le Joueur 0).

Algorithme (induction arrière)

On parcourt le graphe « à l'envers » depuis F. On maintient pour chaque position du Joueur 1 un compteur de successeurs restant à valider.

def attracteur(V0, V1, succ, pred, F):
    """V0, V1 : ensembles de positions ; succ[u], pred[u] : listes ;
       F : ensemble cible. Renvoie l'attracteur du Joueur 0."""
    attr = set(F)                 # Attr^0 = F
    file = list(F)                # positions à traiter
    # nb de successeurs encore hors de attr, pour les positions du Joueur 1
    reste = {u: len(succ[u]) for u in V1}
    while file:
        v = file.pop()            # v est déjà gagnant
        for u in pred[v]:         # on remonte vers les prédécesseurs
            if u in attr:
                continue
            if u in V0:           # Joueur 0 : UN successeur gagnant suffit
                attr.add(u); file.append(u)
            else:                 # Joueur 1 : il faut TOUS les successeurs
                reste[u] -= 1
                if reste[u] == 0:
                    attr.add(u); file.append(u)
    return attr
Complexité. Chaque arc est examiné une seule fois (lorsque son extrémité entre dans l'attracteur). L'algorithme est en \(O(|V| + |E|)\), comme un parcours de graphe.

Les positions hors de Attr0(F) sont exactement les positions gagnantes pour le Joueur 1 : à partir de là, le Joueur 1 peut éviter F pour toujours. C'est la détermination du jeu : chaque position est gagnante pour exactement l'un des deux joueurs.

5. Construction des stratégies gagnantes

Calculer Attr0(F) ne dit pas seulement qui gagne : il fournit aussi comment gagner. On lit la stratégie directement sur les couches de l'attracteur.

Stratégie gagnante du Joueur 0

Notons rang(u) le plus petit k tel que u ∈ Attrk (le nombre minimal de coups pour forcer F). Sur chaque position u ∈ V0 ∩ Attr0(F), la stratégie consiste à jouer vers un successeur de rang strictement inférieur :

σ0(u) = un successeur v tel que rang(v) = rang(u) − 1

À chaque coup du Joueur 0, le rang diminue d'au moins 1 ; le Joueur 1, depuis une position de l'attracteur, ne peut que rester dans l'attracteur (tous ses successeurs y sont). Le rang, entier positif, décroît : la partie atteint F en au plus rang(v0) coups. La stratégie est sans mémoire (elle ne dépend que de la position courante).

Stratégie gagnante du Joueur 1

Sur chaque position u ∈ V1 hors de l'attracteur, le Joueur 1 dispose forcément d'au moins un successeur lui aussi hors de l'attracteur (sinon u y serait entré par la règle du ∀). Sa stratégie : toujours jouer vers une position hors de Attr0(F). La partie ne touche alors jamais F.

Résumé. L'attracteur découpe les positions en deux : depuis Attr0(F) le Joueur 0 force F (stratégie : « baisser le rang ») ; depuis le complémentaire le Joueur 1 évite F (stratégie : « rester dehors »).

6. Détermination du jeu & partition des positions

Le résultat fondamental des jeux d'accessibilité (cas fini) est le théorème de détermination :

Théorème (détermination). Dans un jeu d'accessibilité fini, l'ensemble des positions se partitionne en W0 = Attr0(F) (gagnantes pour le Joueur 0) et W1 = V \ Attr0(F) (gagnantes pour le Joueur 1). Sur sa zone, chaque joueur possède une stratégie gagnante sans mémoire.

Pour savoir qui gagne la partie : on regarde simplement si l'état initial v0 appartient à Attr0(F).

7. L'algorithme Minimax avec heuristique

Le calcul exact de l'attracteur suppose qu'on peut explorer tout le graphe du jeu. Pour des jeux réels (échecs, dames, Puissance 4…), ce graphe est gigantesque : on ne peut pas le construire. On utilise alors l'algorithme Minimax, qui explore l'arbre des coups sur une profondeur limitée et évalue les positions atteintes par une heuristique.

Principe

On déroule l'arbre des parties depuis la position courante. Les deux joueurs sont supposés jouer au mieux de leur intérêt, mesuré par une valeur :

Les valeurs sont calculées au fond de l'arbre :

Pseudo-code

def minimax(position, profondeur, joueurMax):
    if profondeur == 0 or terminale(position):
        return heuristique(position)      # estimation ou score exact
    if joueurMax:                          # le joueur MAX maximise
        valeur = -infini
        for coup in coups(position):
            valeur = max(valeur, minimax(jouer(position, coup),
                                         profondeur - 1, False))
        return valeur
    else:                                  # le joueur MIN minimise
        valeur = +infini
        for coup in coups(position):
            valeur = min(valeur, minimax(jouer(position, coup),
                                         profondeur - 1, True))
        return valeur

Le coup effectivement joué par MAX à la racine est celui qui réalise le max.

Le rôle de l'heuristique

L'heuristique h estime la valeur d'une position sans explorer la suite du jeu. Elle privilégie certaines positions plutôt que d'autres. Exemples : aux échecs, la différence de matériel (somme des pièces pondérées) ; au morpion, le nombre d'alignements encore possibles. Une bonne heuristique permet de jouer correctement avec une profondeur faible, donc peu de calcul.

Lien avec l'attracteur. Si on pouvait dérouler l'arbre entièrement (profondeur infinie, scores exacts ±∞), Minimax retrouverait exactement la réponse de l'attracteur : « cette position est-elle gagnante ? ». L'heuristique n'est qu'une approximation rendue nécessaire par la taille du graphe.

Élagage α-β (pour aller plus loin)

L'élagage alpha-bêta est une amélioration de Minimax qui coupe les branches dont on sait déjà qu'elles ne changeront pas la décision. Il renvoie la même valeur que Minimax mais explore beaucoup moins de positions, ce qui permet d'augmenter la profondeur à temps de calcul égal.

8. Récapitulatif

Informatique CPGE MP/PSI · Introduction à la théorie des jeux