Programmer un robot (1)
Série d'exercices
Cet exercice fait partie d'une série :
-
« Programmer un robot (0) »,
-
« Programmer un robot (1) »,
-
« Programmer un robot (2) »,
-
« Programmer un robot (3) »,
-
« Programmer un robot (4) ».
On considÚre dans cet exercice un robot se déplaçant sur une grille de dimensions finies. Initialement, il se trouve sur la case en haut à gauche de la grille et est dirigé vers la droite.
Ce robot est représenté en Python par un objet de la classe Robot
. L'interface de la classe Robot
est la suivante :
-
robot = Robot(4, 5)
: instancie un objet de typeRobot
évoluant dans une grille de 4 cases de haut et 5 de large. Cet objet est affecté à la variablerobot
; -
robot.avance()
: fait avancer le robot d'une case dans la direction actuelle. Un déplacement qui ferait sortir le robot de la grille est d'ores et déjà ignoré ; robot.droite()
: fait tourner le robot d'un quart de tour vers la droite ;robot.gauche()
: fait tourner le robot d'un quart de tour vers la gauche ;robot.dessine_parcours()
: affiche la grille, les cases déjà parcourues et la position actuelle du robot dans la console.
Un objet de type Robot
contient aussi un attribut grille
. Il s'agit d'une liste de listes gardant la trace des cases visitées (marquées par "*"
) ou non (laissées vides " "
).
Exemple d'utilisation d'un Robot
>>> robot = Robot(4, 3) # la grille fait 4 case de haut sur 3 de large
>>> robot.grille # le robot est en haut Ă gauche
[['*', ' ', ' '], [' ', ' ', ' '], [' ', ' ', ' '], [' ', ' ', ' ']]
>>> robot.dessine_parcours() # le robot pointe vers la droite
âââââ
â> â
â â
â â
â â
âââââ
>>> robot.avance()
>>> robot.avance()
>>> robot.droite()
>>> robot.avance()
>>> robot.avance()
>>> robot.avance()
>>> robot.dessine_parcours()
âââââ
â***â
â *â
â *â
â vâ
âââââ
>>> robot.gauche()
>>> robot.avance()
>>> robot.dessine_parcours()
âââââ
â***â
â *â
â *â
â >â
âââââ
>>> robot.grille
[['*', '*', '*'], [' ', ' ', '*'], [' ', ' ', '*'], [' ', ' ', '*']]
La classe Robot
MOUVEMENTS = ((0, 1), (1, 0), (0, -1), (-1, 0))
class Robot:
def __init__(self, hauteur, largeur):
self.hauteur = hauteur
self.largeur = largeur
self.grille = [[" " for _ in range(largeur)] for _ in range(hauteur)]
self.i = 0
self.j = 0
self.grille[self.i][self.j] = "*"
self.direction = 0
def avance(self):
"""Fait avancer le robot d'une case (seulement si possible)"""
di, dj = MOUVEMENTS[self.direction]
if 0 <= self.i + di < self.hauteur and 0 <= self.j + dj < self.largeur:
self.i += di
self.j += dj
self.grille[self.i][self.j] = "*"
def droite(self):
"""Fait tourner le robot d'un quart de tour vers la droite"""
self.direction = (self.direction + 1) % 4
def gauche(self):
"""Fait tourner le robot d'un quart de tour vers la gauche"""
self.direction = (self.direction - 1) % 4
def dessine_parcours(self):
"""Affiche les cases parcourues et la position actuelle du robot"""
affichage = [
["" for _ in range(self.largeur + 2)] for _ in range(self.hauteur + 2)
]
for j in range(1, self.largeur + 1):
affichage[0][j] = "â"
affichage[-1][j] = "â"
for i in range(1, self.hauteur + 1):
affichage[i][0] = "â"
affichage[i][-1] = "â"
affichage[0][0] = "â"
affichage[-1][0] = "â"
affichage[0][-1] = "â"
affichage[-1][-1] = "â"
for i in range(self.hauteur):
for j in range(self.largeur):
affichage[1 + i][1 + j] = self.grille[i][j]
affichage[self.i + 1][self.j + 1] = [">", "v", "<", "^"][self.direction]
print("\n".join("".join(ligne) for ligne in affichage))
La classe Robot
est déjà chargée dans l'éditeur, vous pouvez l'utiliser sans l'importer.
On cherche à programmer ce robot en lui faisant effectuer différentes actions :
- le code
"A"
fait avancer le robot ; - le code
"D"
le fait tourner vers la droite ; - le code
"G"
le fait tourner vers la gauche.
Ăcrire la fonction execute
qui prend en paramĂštres un objet de type Robot
ainsi qu'une liste d'instructions et fait effectuer chacune de celles-ci par le robot.
On garantit que toutes les instructions sont valides ("A"
, "D"
ou "G"
).
Exemple
>>> robot = Robot(4, 3)
>>> instructions = ["A", "A", "D", "A", "A", "A", "G", "A"]
>>> execute(robot, instructions)
>>> robot.grille
[['*', '*', '*'], [' ', ' ', '*'], [' ', ' ', '*'], [' ', ' ', '*']]
>>> robot.dessine_parcours()
âââââ
â***â
â *â
â *â
â >â
âââââ
Fonction decoupe
On fournit une fonction decoupe
rudimentaire permettant de transformer une chaĂźne de caractĂšres formant une suite d'instructions en une liste.
def decoupe(instructions):
return [int(c) if c.isnumeric() else c for c in instructions]
decoupe("A3GD5") # renvoie ['A', 3, 'G', 'D', 5]
Cette fonction est déjà importée dans l'éditeur. Vous pouvez l'utiliser pour écrire des tests personnels.
Cette fonction ne gÚre que les entiers positifs strictement inférieurs à 10 et ne filtre pas les instructions incorrectes. Ainsi decoupe("Z12")
renvoie ['Z', 1, 2]
.
Le premier exercice de la série a pour objectif d'écrire une version valide de cette fonction.
# Tests
(insensible Ă la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)
# Tests
(insensible Ă la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)