Adloun

NSI (première) · Chapitre 5 · Exercice de TD

Représenter un plateau de morpion partiellement rempli par un…

Les dictionnaires · Les usages : enregistrement, comptage, index · niveau 2

Énoncé

Représenter un plateau de morpion partiellement rempli par un dictionnaire dont les clés sont des couples, en ne stockant que les cases occupées. Écrire case_libre(plateau, i, j) puis gagnant(plateau).

Corrigé


def case_libre(plateau, i, j):
    """True si la case (i, j) du plateau est libre.

    Precondition : 0 <= i < 3 et 0 <= j < 3.
    Le plateau ne stocke QUE les cases occupees : une case absente du
    dictionnaire est libre.
    """
    assert 0 <= i < 3 and 0 <= j < 3, "case hors du plateau"
    return (i, j) not in plateau


def gagnant(plateau):
    """Symbole du gagnant, ou None. Huit alignements a tester."""
    lignes = [[(i, 0), (i, 1), (i, 2)] for i in range(3)]
    colonnes = [[(0, j), (1, j), (2, j)] for j in range(3)]
    diagonales = [[(0, 0), (1, 1), (2, 2)], [(0, 2), (1, 1), (2, 0)]]
    for alignement in lignes + colonnes + diagonales:
        a, b, c = alignement
        if a in plateau and plateau[a] == plateau.get(b) == plateau.get(c):
            return plateau[a]
    return None

Pourquoi la clé est un couple, et pourquoi elle doit l'être. Un couple est non modifiable : il peut donc servir de clé, là où [i, j] lèverait TypeError: unhashable type: 'list'. C'est la contrainte du chapitre 4 devenue un pouvoir — et ici elle apporte quelque chose qu'un tableau de tableaux ne donne pas : la grille est creuse. Neuf cases, c'est peu ; mais la même écriture représente un plateau de go de intersections dont dix sont occupées, sans stocker les autres.

Le rôle de get dans gagnant. Les trois cases d'un alignement peuvent être vides. plateau[b] lèverait KeyError ; plateau.get(b) rend None, qui n'est égal à aucun symbole, et la comparaison échoue proprement. Le a in plateau en tête est indispensable : sans lui, trois cases vides donneraient None == None == None et la fonction déclarerait None gagnant sur un plateau vide.

Vérification.


p = {(0, 0): "X", (1, 1): "O", (0, 1): "X"}
assert case_libre(p, 2, 2) is True
assert case_libre(p, 0, 0) is False
assert gagnant(p) is None

p[(0, 2)] = "X"
assert gagnant(p) == "X"
assert gagnant({}) is None                              # le plateau vide
assert gagnant({(0, 0): "O", (1, 1): "O", (2, 2): "O"}) == "O"   # la diagonale

try:
    case_libre(p, 3, 0)
    assert False
except AssertionError as e:
    assert "hors" in str(e)

Le test gagnant({}) is None est celui qui démasque l'oubli du a in plateau.

100 % gratuit

Essaie le suivant avec le tuteur

Faire l'exercice suivant avec le tuteur

Sans compte : le cours, 2 minutes de podcast et de vidéo et un exercice avec le tuteur. Pour tout le reste : inscription gratuite en 30 secondes, sans carte bancaire.

Le cours du chapitre · Tous les exercices du chapitre

Exercice suivant avec le tuteur →