Évasions aléatoires

Reeborg le RefurbishedRobot transporte en lui quelques "dés électroniques". Il peut "lancer les dés" et décider quoi faire en se basant sur le résultat. Une telle décision, basée sur un résultat imprévisible comme le lancer de dés, est dite aléatoire. Nous allons écrire deux programmes qui vont éventuellement permettre à Reeborg de sortir d'un labyrinthe en prenant des décisions aléatoires. Voici l'algorithme de base que va suivre Reeborg :

Nous allons implémenter cet algorithme en utilisant deux types d'approches différents pour gérer les problèmes potentiels.

Évasion aléatoire 1

Notre premier programme va se baser sur les techniques que nous avons vues jusqu'à présent. Nous demandons à Reeborg de vérifier la présence d'un mur en face de lui et de n'avancer que s'il n'y en a aucun. C'est parfois décrit comme l'approche Regarder avant de sauter (Look before you leap - LBYL).

G = RefurbishedRobot()
G.set_delay(0) # avancer aussi vite que possible
while True:
if G.front_is_clear():
G.move()
if G.on_beeper():
G.turn_off()
r = G.roll_dice() # "roll dice" = "lancer les dés"
if r in [1, 2]:
G.turn_left()
elif r in [3, 4]:
G.turn_right()
Nous avons mis le délai de temps à sa valeur minimale (donc à la vitesse maximale) car cela peut prendre un moment de trouver la sortie ! Quand Reeborg "lance les dés", 6 résultats différents sont possibles (les nombres de 1 à 6). L'exemple ci-dessous montre un résultat possible.

laby : solution aléatoire

Exceptions

Pour gérer les conditions inhabituelles, les programmeurs Python utilisent souvent les "Exceptions". Par exemple, si vous essayez de diviser un nombre par zéro, Python va se plaindre de la façon suivante :

>>> x = 1/0
Traceback (most recent call last):
File "<input>", line 1, in ?
ZeroDivisionError: integer division or modulo by zero

Python a répondu en "levant" une "Exception" particulière (ZeroDivisionError) qui a aboutit au message d'erreur (ou Traceback) affiché ci-dessus. Ce processus de "lever" (raise en anglais) des exceptions est une façon pour le programme Python d'alerter l'utilisateur sur des situations qu'il ne sait pas comment gérer. Nous pouvons simuler cela en utilisant le mot-clé Python raise

>>> raise ZeroDivisionError
Traceback (most recent call last):
File "<input>", line 1, in ?
ZeroDivisionError

Quand nous savons qu'une exception particulière risque d'être levée, nous pouvons l'"intercepter" (catch en anglais) et la gérer d'une manière sensée. Voici comment nous pouvons faire cela :

>>> try:
... x = 1/0
... except:
... print "Vous avez essayé de diviser par zéro. Ce n'est pas permis."
...
Vous avez essayé de diviser par zéro. Ce n'est pas permis.

Utilisons cela afin d'écrire un deuxième programme pour faire sortir Reeborg du labyrinthe.

Évasion aléatoire 2

Quand Reeborg rencontre un problème (se cogner contre un mur, essayer de ramasser une sonnette inexistante, etc.), une exception est levée. Normalement elle termine le programme du robot et est "interceptée" par RUR-PLE pour afficher la boîte de dialogue d'erreur appropriée. Si c'est bien cela, nous pouvons écrire notre propre programme pour intercepter cette exception et l'ignorer pour permettre au programme de continuer. C'est ce que nous faisons dans le programme ci-dessous. Cela est parfois décrit comme l'approche Mieux vaut demander le pardon que la permission (Better to ask forgiveness than permission - BAFP).

G = RefurbishedRobot()
G.set_delay(0)
while True:
try:
G.move()
if G.next_to_a_beeper():
G.turn_off()
except HitWallException: # exception "se cogner contre un mur"
pass
r = G.roll_dice(3) # valeurs possibles : 1, 2, 3
if r == 1:
G.turn_left()
elif r == 2:
G.turn_right()

Dans l'exemple ci-dessus, nous avons utilisé des dés d'un genre différent, avec seulement trois résultats possibles. Vous pouvez demander à Reeborg d'utiliser des dés avec n'importe quel nombre de résultats possibles pour concevoir votre propre programme.

Quelle approche est préférable ?

Si l'on ne s'attend pas à ce qu'une condition exceptionnelle se produise souvent, la deuxième approche (BAFP) est préférée. Mais si la condition exceptionnelle risque de se produire fréquemment (comme c'est le cas ici), l'approche que nous avons utilisée dans la première solution (LBYL) est recommandée.

previousÉviter les répétitions - les choses importantes - home