From e597f300a3af9baf2662dc5a2b507bdb41b30212 Mon Sep 17 00:00:00 2001 From: Bertrand Benjamin Date: Wed, 9 Jun 2021 08:16:50 +0200 Subject: [PATCH] =?UTF-8?q?Feat:=20Import=20du=20travail=20de=20C=C3=A9dri?= =?UTF-8?q?c?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- maze - corection.py | 276 ++++++++++++++++++++++++++++++++ maze.md | 376 ++++++++++++++++++++++++++++++++++++++++++++ maze.py | 30 ++++ maze_img01.png | Bin 0 -> 16216 bytes maze_img02.png | Bin 0 -> 9928 bytes 5 files changed, 682 insertions(+) create mode 100644 maze - corection.py create mode 100644 maze.md create mode 100644 maze.py create mode 100644 maze_img01.png create mode 100644 maze_img02.png diff --git a/maze - corection.py b/maze - corection.py new file mode 100644 index 0000000..ca3d8d1 --- /dev/null +++ b/maze - corection.py @@ -0,0 +1,276 @@ +######################################################################################## +# +# TP - Structure de données linéaire : La pile +# +######################################################################################## + +### import nécéssaires pour le TP +import random +import time +from tkinter import * + +######################################################################################## +# Classes Node() et Pile() +######################################################################################## +class Node: + def __init__(self, a=None, nxt=None) -> None: + self.value = a + self.nxt = nxt + + +class Pile: + def __init__(self) -> None: + self.current = None + self.n = 0 + + def is_empty(self): + return self.current == None + + def add(self, valeur): + self.current = Node(valeur, nxt=self.current) + self.n += 1 + + def depile(self): + if not self.is_empty(): + a = self.current.value + self.current = self.current.nxt + self.n -= 1 + return a + else: + return None + + def get_top(self): + return self.current.value if not self.is_empty() else None + + def vide_la_pile(self): + while not self.is_empty(): + self.depile() + + +#################################################################################### +# Jeu de cartes +#################################################################################### +def DeckOfCards(): + jeu_trie = [] + for valeur in [2, 3, 4, 5, 6, 7, 8, 9, 10, "Valet", "Dame", "Roi", "As"]: + for couleur in ["Pique", "Coeur", "Trèfle", "Carreau"]: + jeu_trie.append((valeur, couleur)) + jeu = Pile() + while jeu_trie != []: + # Un index du jeu trié au hasard + i = random.randint(0, len(jeu_trie) - 1) + jeu.add(jeu_trie[i]) # On ajoute la carte à la pile + jeu_trie.pop(i) # On retire la carte du jeu trié + return jeu + + +def main_bjack(jeu): + result = 0 + if jeu.n < 2: + return result + c1, c2 = jeu.depile(), jeu.depile() + for c in [c1, c2]: + if (c[0] == "Valet") or (c[0] == "Dame") or (c[0] == "Roi"): + result += 10 + elif c[0] == "As": + result += 11 + else: + result += c[0] + print(c1, c2, result) + return result + + +# Test : Distribution de toutes les cartes +j = DeckOfCards() +while not j.is_empty(): + print(j.depile()) + +# Test : Calcul de mains de blackjack +j = DeckOfCards() +while not j.is_empty(): + main_bjack(j) + +#################################################################################### +# Labyrinthe +#################################################################################### +def find_e(t): + """Permet de trouver l'entrée du labyrinthe""" + for ligne in range(len(maze)): + col = t[ligne].find("e") + if col != -1: + return ligne, col + + +def aff(t): + """Affiche le labyrinth t""" + for ligne in range(len(t)): + print(t[ligne]) + + +def avance(maze, p): + """Avance dans le labyrinthe""" + # on va sur la position du haut de la pile + l, c = p.depile() + + # on marque la position comme "exploré" + ligne = list(maze[l]) + ligne[c] = "x" + maze[l] = "".join(ligne) + + # pour toutes les cases adjacentes ... + for dl, dc in [(0, 1), (1, 0), (0, -1), (-1, 0)]: + # on empile les positions adjacentes libres + case = maze[l + dl][c + dc] + if case == " ": + p.add((l + dl, c + dc)) + # si on a trouver la sortie, on vide la pile + if case == "s": + p.vide_la_pile() + return l, c + + +# Notre labyrinthe +maze_str = """ +###################################### +#e # # # # # +###### ## # # # # # # ############## +# ## # # # # # ##s # +###### ## # # #### # # ## # # ## # +# # # # ## # # +# ############## # # ######## # # ## +# # # # # # # ## # +# ##### ############ # # # ### ## +# # # # # ## # ## +###################################### +""" + +# On transforme le labyrinthe en listes de chaînes de caractères +maze = maze_str.split("\n") + +# pile des positions inexplorées +p = Pile() +p.add(find_e(maze)) + +# Tant que la pile n'est pas vide ... on avance +AFFICHAGE_CONSOLE = False +while not p.is_empty() and AFFICHAGE_CONSOLE: + avance(maze, p) + aff(maze) + time.sleep(0.5) + +######################## +# Interface avec tkinter +######################## + +# Réinitialisation du labyrinthe +maze = maze_str.split("\n") +p.add(find_e(maze)) + +# Taille des cellules et du labyrinthe +cell_size = 16 +xmax = max([len(t) for t in maze]) * cell_size +ymax = len(maze) * cell_size + +# Affichage +root = Tk() +root.title = "Labyrinthe" + +canevas = Canvas(root, width=xmax, height=ymax, background="#FFFFFF") +canevas.pack() + +for y in range(len(maze)): + for x in range(len(maze[y])): + if maze[y][x] != " ": + canevas.create_rectangle( + cell_size * x, + cell_size * y, + cell_size * (x + 1), + cell_size * (y + 1), + fill="#111111", + ) + if maze[y][x] == "e" or maze[y][x] == "s": + canevas.create_rectangle( + cell_size * x, + cell_size * y, + cell_size * (x + 1), + cell_size * (y + 1), + fill="#005533", + ) + +# Boucle principale d'affichage +def loop(): + if not p.is_empty(): + l, c = avance(maze, p) + canevas.create_rectangle( + cell_size * c, + cell_size * l, + cell_size * (c + 1), + cell_size * (l + 1), + fill="#00FF00", + ) + root.after(50, loop) + + +root.after(50, loop) +root.mainloop() + +#################################################################################### +# Labyrinthes à tester :) +#################################################################################### + +maze_str = """ +###################################### +#e # # # # # +###### ## # # # # # # ############## +# ## # # # # # ##s # +###### ## # # #### # # ## # # ## # +# # # # ## # # +# ############## # # ######## # # ## +# # # # # # # ## # +# ##### ############ # # # ### ## +# # # # # ## # ## +###################################### +""" + +maze_str = """ + ######### #### + ## ## ##### s# + # # ## # ## + # # ## # # #### + ## # # # + #### # # # # # +##### #### ### # +# # # # # #### # # # +# # # # ## # # +###### # # ### # # + # ## # # # + #### # ##### + ## # ## # # + # # # ### ### + # # # e#### + ##### # # + ######## +""" + +maze_str = """ + #### + #e # + ## ######## + ####### # # + # # # # # # # ## + # # ## # # + ### ## # # # ######### + # # ## # ## # # # + ## # # ## # # # # + # ## # ### # # ### # # + # ### # # ## ## # ## +##### # # ## # # # +# # ### # # # ### ### ## +# ## # # # ## # +# ## ## # ## ## # # +## # # # # ## ## # ### +## ## # # # # # # ### +# ##### # # # ### +## # # # # #s### +######## ########### +""" diff --git a/maze.md b/maze.md new file mode 100644 index 0000000..c6ce66d --- /dev/null +++ b/maze.md @@ -0,0 +1,376 @@ +--- +title : TP - Structure de données linéaire - La pile +author : TODARO Cédric +date : 06 juin 2021 +--- + +# Introduction + +Cette activité a pour objectif de vous faire travailler avec la structure de données de type **pile**. + +Elle se déroule en 3 temps : + +- Élaboration de la classe ```Pile``` +- Utilisation de cette classe pour modéliser un paquet de 52 cartes +- Utilisation de cette classe pour établir un algorithme de recherche de chemin "de sortie" dans une d'un labyrinth + +Vous pouvez vous référer au cours de [Quentin Konieczko](#remerciements) en [pdf](https://qkzk.xyz/uploads/docnsitale/poo/2_cours_clean.pdf), en cas de difficulté avec la POO. + +## La classe ```Pile``` + +Avec de définir la classe ```Pile```, nous avons besoin de définir la classe ```Node``` qui sera un noeud (une case, un emplacement, ...) de notre pile. Voici ci-dessous la représentation des classes ```Node``` et ```Pile``` : + +![Représentation de la classe ```Node``` et ```Pile```](maze_img01.png) + +### La classe ```Node``` + +La classe possède donc 2 attributs : + +- ```self.value``` : Une valeur (qui peut-être de n'importe quel type) +- ```self.nxt``` : Le noeud suivant + +> Compléter le code suivant : + +```python +class Node(): + def __init__(self, valeur, suivant): + # ---------- + self.value ... + ... + # ---------- +``` + +### La classe ```Pile``` + +La classe ```Pile``` doit possèder un élément "courant" qui est l'élément sur le dessus de la pile. Dans le cas du schéma précédent, ce sera le noeud qui contient le 3 de carreau. Elle doit aussi posèder un entier ```n``` qui compte le nombre d'éléments dans la pile + +Dans la définition d constructeur ```__init__```, nous devons retrouver : + +- ```self.current``` : L'élément en haut de la pile, initialisé par défaut à ```None```. +- ```self.n``` : Nombre d'éléments dans la pile, initialisé par défaut à 0. + +> Compléter le code suivant : + +```python +class Pile(): + def __init__(self): + # ---------- + ... + # ---------- +``` + +La classe ```Pile``` doit possèder les méthodes suivantes : + +- ```is_empty(self)``` : Pour vérifier que la pile est vide. +- ```get_top(self)``` : Pour obtenir la valeur de l'élément courant. +- ```add(self, valeur)``` : Empile un noeud à la pile. +- ```depile(self)``` : Dépile l'élément courant de la pile. +- ```vide_la_pile(self)``` : Vide la pile. + +### La ```pile``` est-elle vide ? + +Il est pratique d'implanter une méthode permettant de savoir si la pile est vide. + +- ```is_empty(self)``` : Retourne ```True``` si ```self.current``` est à ```None``` (vous pouvez aussi vérifier la valeur de ```self.n```) + +> Compléter le code suivant : + +```python +class Pile(): + # .... + def is_empty(self): + # ---------- + ... + # ---------- +``` + +### On empile... + +Pour empiler un élément dans la pile, il faut ajouter un ```Node``` qui deviendra le noeud courant de la pile et dont le suivant est l'ancien noeud courant. + +- ```add(self, valeur)``` : Empile un noeud à la pile. Ne pas oublier d'incrémenter ```self.n```. + +> Compléter le code suivant : + +```python +class Pile(): + # .... + def add(self,valeur): + # ---------- + ... + # ---------- +``` + +### ... et on "dépile" + +La méthode ```depile(self)``` doit retourner la valeur de l'élément courant et faire de l'élément suivant de d'élément courant, le nouvel élément courant. + +- ```depile(self)``` : Retourne la valeur de l'élément courant et le retire de la pile. Ne pas oublier de décrémenter ```self.n```. Si la liste est vide, ```depile(self)``` retourne ```None```. + +> Compléter le code suivant : + +```python +class Pile(): + # .... + def depile(self): + # ---------- + ... + # ---------- +``` + +### Être au top ! + +La méthode ```get_top(self)``` doit retourner la valeur de l'élément courant si la liste n'est pas vide. + +- ```get_top(self)``` : Retourne la valeur de l'élément courant. Si la liste est vide, ```get_top(self)``` retourne ```None```. + +> Compléter le code suivant : + +```python +class Pile(): + # .... + def get_top(self): + # ---------- + ... + # ---------- +``` + +### Tout vider + +La méthode ```vide_la_pile(self)``` permet de vider la pile. + +- ```vide_la_pile(self)``` : Depile les éléments tant que la pile n'est pas vide. + +> Compléter le code suivant : + +```python +class Pile(): + # .... + def get_top(self): + # ---------- + ... + # ---------- +``` + +### Tests + +A ce stade, vous pouvez tester toutes les méthodes de votre ```Pile``` : + +```python +>>> p=Pile() +>>> p.is_empty() +True +>>> p.add("Patate") +>>> p.is_empty() +False +>>> p.get_top() +'Patate' +>>> p.add(6) +>>> p.get_top() +6 +>>> p.add(789) +>>> p.add(["a","b"]) +>>> p.add((1,2,3,4,5,6,7)) +>>> p.get_top() +(1, 2, 3, 4, 5, 6, 7) +>>> p.depile() +(1, 2, 3, 4, 5, 6, 7) +>>> p.depile() +['a', 'b'] +>>> p.depile() +789 +>>> p.depile() +6 +>>> p.depile() +'Patate' +>>> p.depile() +>>> p.is_empty() +True +``` + +## Un jeu de cartes + +On peut utiliser une pile pour modéliser un jeu de cartes. + +![Un jeu de cartes](maze_img02.png) + +Pour cela, il faut : + +- Générer une liste ```jeu_trie``` de tuples ```(valeur,couleur)``` de toutes les cartes d'un jeu de 52 cartes. +- Choisir au hasard un élément parmi ```jeu_trie```. +- Empiler cet élément dans une pile et le retirer de ```jeu_trie```. +- Recommencer jusqu'à ce que la liste soit vide. + +> Écrire une fonction ```DeckOfCards()``` qui retourne un jeu de cartes mélangé. + +```python +def DeckOfCards(): + jeu = Pile() + + jeu_trie = [] + for valeur in [2,3,4,5,6,7,8,9,10,"Valet","Dame","Roi","As"]: + for couleur in ["Pique","Coeur","Trèfle","Carreau"]: + # ... + # ... + return jeu +``` + +**Remarque :** ```list.pop(i)``` enlève de la liste l'élément situé à la position indiquée et le renvoie en valeur de retour. Si aucune position n'est spécifiée, a.pop() enlève et renvoie le dernier élément de la liste. + +### Blackjack + +> But du jeu : Après avoir reçu deux cartes, le joueur tire des cartes pour s’approcher de la valeur 21 sans la dépasser. Le but du joueur est de battre le croupier en obtenant un total de points supérieur à celui-ci ou en voyant ce dernier dépasser 21. Chaque joueur joue contre le croupier, qui représente la banque, ou le casino, et non contre les autres joueurs. + +A ce stade, vous pouvez écrire une fonction qui tire 2 cartes dans un jeu de cartes et qui calcule la valeur de la main de Blackjack correspondant. + +```python +def main_bjack(jeu): + # ... +``` + +La pile utilisé pour piocher les cartes étant la même pour chaque tirage, vous devriez toujours obtenir des cartes différentes. + +```python +>>> j=DeckOfCards() +>>> while(not j.is_empty()): +... main_bjack(j) +... +('Dame', 'Carreau') (3, 'Trèfle') 13 +13 +(8, 'Carreau') (5, 'Carreau') 13 +13 +(6, 'Coeur') ('As', 'Pique') 17 +17 +... +... +``` + +## Sortir d'un labyrinthe + +On peut modéliser un labyrinthe par une chaîne de caractères de la manière suivante : + +```python +maze_str=""" +################ +#e # +##### ###### ### +# # # #s# +## ##### ### # # +# # # +################ +""" +``` + +- ```e``` : Entrée du labyrinthe +- ```s``` : Sortie du labyrinthe +- ```#``` : Mur +- Une position dans le labyrinthe peut-être modèlisé par un tuple ```(ligne,colonne)``` + +Pour pouvoir accéder à une case du labyrinthe de manière plus pratique : ```maze[ligne][colonne]```, vous pouvez transformer cette chaîne de caractères en listes : + +```python +maze = maze_str.split("\n") # La première et dernière ligne sont vides (cela n'influence pas l'algorithme) +>>> maze[2][2] # Ligne n°2 , Colonne n°2 : position non explorée +' ' +>>> maze[2][1] # Ligne n°2 , Colonne n°1 : entrée du labyrinthe +'e' +>>> maze[4][0] # Ligne n°4 , Colonne n°0 : un mur +'#' +``` + +Pour trouver la sortie du labyrinthe à l'aide d'une pile : + +- Empiler la position de départ sur la pile +- Tant que la pile n'est pas vide : + - Se rendre sur la position "du haut" de la pile + - Marquer notre position comme explorée (```X```) + - Empiler les positions adjacentes inexplorées (en haut, en bas, à gauche ,à droite) + +Pour écrire l'algorithme permettant d'explorer un labyrinthe, je vous conseille d'écrire les fonctions suivantes : + +- ```aff(t)``` : Affichage du labyrinthe ```t```, ```t``` étant une liste de chaîne de caractères représentant chacune une ligne du labyrinthe. +- ```find_e(t)``` : Retourne la ligne et la colonne où se situe l'entrée dans ```t```. +- ```avance(t, p)``` : ```p``` étant la pile des positions inexplorées, cette fonction doit faire : + - Avance sur la position inexplorée suivante. + - Marque la position courante comme explorée. + - Empile les positions adjacentes inexplorées dans ```p```. + - Si on a trouvé la sortie ```s```, on vide la pile ```p```. + +> Écrire les fonctions ci-dessus et tester les à l'aide de : + +```python +import time + +... + +# Tant que la pile n'est pas vide ... on avance +p = Pile() +p.add(find_e(maze)) +while(not p.is_empty()): + avance(maze,p) + aff(maze) + time.sleep(0.5) +``` + +Vous trouverez à la fin du fichier, des exmeples de labyrithes pour tester votre algorithme : + +```python +maze_str = """ +###################################### +#e # # # # # +###### ## # # # # # # ############## +# ## # # # # # ##s # +###### ## # # #### # # ## # # ## # +# # # # ## # # +# ############## # # ######## # # ## +# # # # # # # ## # +# ##### ############ # # # ### ## +# # # # # ## # ## +###################################### +""" +... etc ... + +``` + +### Bonus : ```tkinter``` + +> Réaliser l'affichage du labyrinthe à l'aide de la bibliothèque ```tkinter```. + +Vous pouvez consulter la documentation suivante : [Tkinter pour ISN](http://tkinter.fdex.eu) notament la partie sur [```Canvas```](http://tkinter.fdex.eu/doc/caw.html) : + +```python +from tkinter import * +root = Tk() +root.title = 'Titre fenêtre' + +canevas = Canvas(root, width=400, height=400, background="#FFFFFF") +canevas.create_rectangle(10, 20, 40, 50, fill="#00FF00") +canevas.create_rectangle(40, 50, 100, 100, fill="#0000FF") +canevas.pack() + +root.mainloop() +``` + +**Remarque** : + +> ```after(delai_ms, fonc=None, *args)``` +> +> Demande à Tkinter d’appeller la fonction de rappel fonc avec les arguments args après l’écoulement du délai delai_ms donné en millisecondes. Votre fonction de rappel ne peut pas être appelée avant ce délai (même si son appel effectif peut le dépasser) et elle ne sera appelée qu’une fois. +> +> Exemple d'utilisation : +> ```python +> from tkinter import * +> +> root = Tk() +> +> def task(): +> print("hello") +> root.after(2000, task) # reschedule event in 2 seconds +> +> root.after(2000, task) +> root.mainloop() +> ``` + +# Remerciements + +Merci à [Quentin Konieczko](http://qkzk.xyz/) pour son cours sur la POO. diff --git a/maze.py b/maze.py new file mode 100644 index 0000000..7cf8ac9 --- /dev/null +++ b/maze.py @@ -0,0 +1,30 @@ +def DeckOfCards(): + """Génère un paquet de carte mélangé + + Le "jeu mélangé" devra être une pile ou un file avec toutes les cartes. + + """ + jeu = # File ou Pile() + # ----------------------- + + # ----------------------- + return jeu + + +def main_bjack(jeu): + result = 0 + # ----------------------- + + # ----------------------- + return result + + +# Test : Distribution de toutes les cartes +# j = DeckOfCards() +# while not j.is_empty(): +# print(j.depile()) + +# Test : Calcul de mains de blackjack +# j = DeckOfCards() +# while not j.is_empty(): +# main_bjack(j) diff --git a/maze_img01.png b/maze_img01.png new file mode 100644 index 0000000000000000000000000000000000000000..ce58b4e9d9a7034127d6bea9c63628325b2896da GIT binary patch literal 16216 zcmbumWmr^UxbF=ppdckB4bmVX-AH#UNF&|dLrP1DbW4MRh}00n(A^zFcQ->0@6x^Z zIq$X4`Lf^l0~fI7nP;u_-lTr zPk(!!Az{A!`-42b7;uk-B#xmVE%Dxa{xBQUfY9Q$N6m=k{96&qmR?FqnT3Vj zKB~K6?f3G<_y&s=)Gj3--NitrUJCkV`?zGOchpGi_LB_lRFzG}sQiX)~w+?>`M8LKxR z$I;+&GcTIXAByq3-X5h>D&q`4ltx{}*}aalOkF;O*0etuE~rIdzj}0FSRlK|~F+VO#8q0{w0M$Z3zEc{;wN@Q%{i1`=O^K8!a{MmbL zWd;_$TpIjDn<$sRmtoxL`9LofGj)q5GJpC1e#uGXQIA=F+n#)LabkwB!VUMj`vb4{Nb{?gzHP* z1gD1*#|@u`>jFTZzX{TO;nm$ys2?NFa4|_C^z~(#TYWW9=m_fP*#pu3+7)xvT4_{%KXSi-?tccagEL`a-AL2?(hm2U+uVvFpT&O@B zc?*S>8ybH_Lnm`#XYMdWOWy?`@_h1Rrvq10>~ zdGQ83$ZyQY_iEJPP1w9|nd?`elvmqwhaye~#3huU4NXMR=tV^|*sB`n^%2>N_`C4% z@Ww`=%`qq3h6tD5zr~i2rxx>PlSjic?jioTU4r53$5ZbrD|H$@l9iFG!Q4kA@P2uF zja9NSwc?UHhq?AsL)!hM3wR8u8E8K0=1ppuow;ZU=z;_ua~JWxpww4_pmCJ11o_u{2l}0dI(xK>pE-el+WPZtljfW{ zhH|vaWMk^eTXbb2*4$&nfXbIyYUQn>SJuo7DRBHH?aO}{-suvlP3m8=laB4*MjCmf z5JgqOZA&!$@1xjyjSK$#8TiMwy)H^MU`QMt* zGDjUxE3Ndy3uhndV`7HY;N;5{9kF8&CAkd3_?-`Y<1cpj^>nXs{4m0TQcKW1rK-M9 zq^NX@t|MqbCt7pskz(R`FW^v)~rmC5TaPOqR1!Vg>Si%Y({d-!3X|g zI3t8or}o%+rxjUs`cIk1MesB1Ce2?ivuB?tdoQC8 z#l58j4!%~cFM;vls5ZidPq4}OZQAxIY*1tFrj;B?Q3z0ID zlFHl;urR+cMQ)=}DyXdK^|$OSPtn*)ecK`@qv_@~2*tk`YTyuS?A}ss@;~t)U2pmD z8ay#Ef!AGb3`Lxeh*NQzAdU9$F-lSGQ+XbB8dibTwq^5%5UMWN-zzB`a)bsC-U@*1 zGJRWw43@Xnvy%Ig%O2~9>JIM%XEs^{#@xU=i!+RtMEt1S$hp`yucutpf>+w{Azev0 z#?w_Fw6JbI8L;L$TDl;78`;bYzDrWLOzG7(_DwKTJEG70runQdc zQ6X0F*_zW*bJTT6}%GiXLb2mQw{obQemY==GP{ zM4nsO?+@o6lUg60vQJwVY z7NZ{NU^lYD*P$vFF!AzI+KlAnshzO`DM`tIo6XcG=-7Vur#(RdosoFFyu6zJ7gx0U zajcD=hl1}>gi6ok(rAC=mFUPwildHfJBpW2UD`3-t{8pM51&&({MOB)HT^-fZGIa# zIoQVd>t#od)SpGinJD@r?vCPm?|0Jym8cpAEgt*R+c_Xr`X6rF!xP0SO}>{bUfb+K zC2BbbvqcNnjKWJb2P)Za0<6*BQ*VX^9ogBlj)b?JebmzJR!e9cZE*t*-Dkt2cQ za4~N zFm;V8HUMKtNbH4whh@J={Z|U+beYW5orIQX~V8_Xo1*8?Hg>`qllUGcBH7KwBtBsA7CyywM15++0h;m$Xy>;!*q zDl&*@)0Thibyqz49t4ZKr4xOXW~VwCXb#XHS@BmCE5ZGPL%Tu?#DU;BbO+~!ShCuWpBNq-+uTKwN;G=AIN9YYz==tYn1cb)W-f^NRBZsuU;lw_AMt}l@k$9KE z5>+j3Zr>&t19GZE3`@{`g+lF}7b$*Q297og$fO2#g_TER={Jcd8Ji{}EL>wLQ zI(ol+C7JulHhWao@3U6nrKsbk9@?%Bv0jw~$MUXoa;P$1(&7YZB$H5 zHY;cbpWP<^`P}@?&ZnsV%}qns%$cI3SpZqno9=G5qr@q6=AxB9lG{OpKm}kJ_L(dj zAW9UjUfY{NysIwr7oi(^0hCxrhtu@CW26^)X)rGG^`(#W91}jLhiUhE=|y#Ql>5E3 zbJ}rl`HoKO>~J(Nj@=0bgNq0G_&>wM00n*cQ#F#^lYSc)egaQ26~IvdwAMWFdQKlf z7ubqR22h^L8bC2Eg8$hi8inH~*pJO+?;DBf#~jVQ4CqCn98j5i5v2W2dz$oEf0x2H z&Sj)fX3S0nYRIBA)Epqxw6OrOdTjO+zkiTxL66Uc2Ar9mRt@fNe&EeQ{yqXAh79Yc zTNUW+ABDP=&y7ybQ@3HQg;w1qFS&~G!1ISMak>Rv*y{E_vWX?SpER|?J2(Dnx)^(d2D8F>_vNh z%ScTWsEol;Ju!G!=R!}+3aQOnUxSwBX{xa*O)nl;T-7O3vm{x zqCiOTr*>v$@sb@t0SWWbqgF&OuHjeA{?Yx2;-Bx3D(B;SaBf`dG{LeNkWFMxLLztd z>FJ+vYoZ5ZmJZ_d$c()X97|oHGj=LOPW-`R@_P+>fjhL2-vx>ShH>G^jlN|9_nFco zb2O|6DB8*s9cwYQ70`VcXKK0xYv?J~W%Vp->od+U0ga?j20!ble^i?qvViaF4cC|8 zw|%y{gV=3zWWy7z$vnldGGmTkS;SjhY^`RVzXvYf#p|}+H-B|Y)^83ATPE7tJpU%f z(lGd3ru*igdj0@3sIk0OcsamWA^{TY4RSU%?ioo7VBqZm zgm0=;>3&S>R5Yz=%j2cN?Itk3*X%ZBP&YraHoa#;M61k6rzE)in^w)CyU3r&e=&19 zaDT%goc?}Yh~wdL$*E)0RiUO$MSe39t0rNdK`Yz%%gn=AXR9eSF8+dZAVtVlE0JYDKNUCmrgAQak z)TJJoB(Kgsi1^etHr^I5$jrGAUV`P*>Akw1V^g99>zZT%rS^!w-z5$9@V9wZpAqft z5RVx3iDY{jwQa)6ng_LfA_B#r%=fclF@CqDvz4^f|CSu33w|=38+*N9$L+_92O)mM zp~S@6&h74R(Z+q`<6-L8=)ih(RDInSz^aJlpQ1MRVV&P~nD79Wb&K%5i(Pu38Uu`9g8MVF~@yMu=b}`Apa>2x?>f4`AcVT;>K89W`uz*HA zEnWjJY*9NDQ#E25wR4<0#8&kr4x(M_(tU?Qkm)F$;ojM&J!YI_p#?q-J?J0+AjIo* z`O8`@I zm)KwPbVT^*v?drLB5rEOI3)R2w-Qb{i2VL8bN}!L&ydsR`JDEMAPt!9>`x`Xs5Ym= zj>5OUf*su@?l}LMf9|Ac=xq5fpbxRov&2r%Gw{E-#oZuuz8I=#cg?VvJXOoHAh!&5 zDXmcGViXK*oI^JnVBHk>m8ViWz5CuA1K3$;VlMn;;nS5-&@sB4rStXxHK=sd#_IL% zfQl_1>mOWTCmDU8!;Bs%_vK5VBu_-{e$9&Ob4FS5@G?t$@12&HlEp!~y#N`wsZ0MK82APLt0&)ML-jqqeq7i2W$7xWIObesN>(rh|0V zKe%P%rFm?9$#dg~Fj7nsk4qS@4e(eXhi5hyTo(%pKR$NlZg%=M0Knumrn(*0;GcGO zBptVfZYi`Oh~92iN=lvk?zl#QEaYn5&a5Zy^73-1FOTx6kk88K7TCDSJ#!`t_qsY7 zYP`u&*FrT-8n+i_!f^-x`HMS5#4^I~kicdX=4L9QrLVt#bhPx#P&irfvKP<+SF>g; z5{pe<@bmNarx&#d<(45Aj`uB6z+nDmwD!{$>$3RhKtXauX$hMXbFa!7i-`~`6;u_v z){*9Oz7>3yBMQQ%6uIV=kcz5ucMfYp-g@^KZ;+&oe!elw>dTk-<@i51uoNZ zp$0Nrp|vXl6FGc9l<|AaC7=V5ypES3!FOM2q|h))d8~2kfR?e-8O=>kFVjXJ4X>Ji z1vi~Az~vp{eKlS*SxL&1u~pLtX@+Ahpyps1?hZED zRofwlahKn+L$yk&?2*n!{+Az~yEn|pwT3uTEr7FY7Rvj;fdXZDV-1jv(fdg)wYj-D3h@8~M7-vf)8ZQF>t_(y zjeIXz$B1S+A~HXo3EjEWD#u3_fv;CZ0l*Quo_ET&E9O*XFH#?$u&kUpZT5`K>+Z&Z zRP7bjR8%PV>|fQ^ztOLY!EeW5K9isz*nPOY)UUA~n=I3+TCC9L|ITsP+ILb>R`whV zs|!Fi7YX-}EKs3(WPHf|*#O7cgf-;w6!RLsaoD^e-FJVl(TWV6$XrPRY%%?|%L0lR9Jby2?q*qHK4+Kph|p**`J!9!Pg_0yDU&vw z7P0#ZfTmOu6RFlzwe_UF|50Z6zPho@h_JT0zUSE4;wBExk zN5Qwl-WfDyX4qIvA>18RRaIBGARuRCr=XwLBML5oX*nRTs=?0QnEFq z6IcK~kp*K-D<~+)OI*YYu^wUY!g$9RKdB`>rx0@g{rflA^H6U;la~ZeXFyPnSG1CE zzfc#8kD{Y!Q13|bQv7y@*1M{>(MGBx%_Y!Bv#6hPF0-18gL3SrbtnmuJ&#_x6~yAo z9`pexd2ff*^c@%szA+YYdyQ z(eq&U@G!RX;STO*Dn-{$ScrT2tppkkO`Z2_6(xt>d!<92AUpZ?%PkQ9yDM?THErEr zG{FlKSAM96KE!&`;$-`6JbU@X$nP7OnTvyT<#>W600FB^)^DFx>nWXI@Pmq*$Et_N z$*DG%iQ;yqOe|XNl1omH@A9u)^*nBbwvB$|yo76JNiD~b@ndUTC$s7ZRPBC&>KPf$ za`W+}#JQcWb;VH#U+qmrv;6ULxys;2`rvkYJo`PrfH#{M=;AfX9LiK1fMd8b$5V=a zSunXiStTSSoRpR_8k`y+8%Fe(E)f!Ut0RK8|pq-jiXFF&Iq7Lvs#dvor!A_v%u z47gO;*GTJ<`5*NbpyVlGJ{Se%rAXFAwicvLJjLl!^D7~^mkbR%l*_hpg zEx{iicJ=i3gZ9V^f9cDkh`<@gN__e?@~5u^%zn%W2@9K%;fa3;$;!&Y-KL|XYxSI( zno1G~xWAU8@=uy~`+mMXQg1gi41*bbaodReDOx}7=NB!oUDZPg+AT^g&1hT8npQeG z)_5Zlq)d!%d2bf>PAU!!vxm$KJcc7;?dvQIQ`D5mqnfTvIDkm=2?I z)5HVCdiHAdHpN6l$iu_*+k}{yBJt;aHsXJlqHZY~8TBwW4j$aR;;-Wer%GltNpVd2 zf>w3PIcaG-$HzGJ4pvs^(+Qf|+Op>Qy1H%7n8fVT zzSh=E?b7e10v|4QZc~)W@$p0aSI#ymIGMwDm!Z(~bdtKY0WCZ6jI3AVe_1E*zW4PT~G`bdlYG@^W5v9S~qU-J!P&9 zDrqR;U*=DOJ32wnRWFBr$U3-ljwQW36ue|ppnTR3AM;y%cX*RZmqZgpdHV4CQ%CCq zu){=+BN-VV@_ZCGx5&|_aqg1qOd0?AkTrO4(a8O4rH9I2dWZkxlI$bjMGBFIl#kkD zTrF>VX18qiyAhJlP-ta!k`MN){KiJo;`r!jyQ(eqj~_p>?x-F+*o=L=fx-HQ@B&9d=_#9WOO`Em|0|{C6mW$5JV&fi=-1n#v7z72tCDoUx>;9Vu6*dh zqWZ!+2&h&JwaNeCb=R$=vXc#^%BcSNs9WQ6C%RgNqf7d3(I}MR!oouM5{N@kFdg4t z@Iwa?n;uWVy?2@5YTc!DCC7_(jmLzQ%isV=QP|T5>31B>QTbXs4SfBO4G~-YZ%0N7 zmaydxG17IU8gNLE7~}U5(8ICO9_1q`&O>PZvPSC!e|BFs*eXQLTG8#~xqt4MXkich z#qs1BQ(%(5j{Y5-S*ui=Z}qVLXQ*B<%BUNgtD4T_Vh$Ex;je`dtl9*ZR;=nBZ97;^ zRaI3@O|wgZWC@|}rQ7Jn66hBv7&iF*X9JI1)s>u!b+l~~TIv8BLm<>OAgx7hkCIFI zs9~#eX{p(#T5}pv@WP%AV0w=W!Q#KTQ8>&u`2Vy?TjaM%k63MV2vAl_A=YmTT1Iv# zxjr5V#?l0Mh^i;uR@%89ACpO)H;y%1*q>Pcx>*_HjIO2-7o9!&ZtkBuBWm6YbK{y$ zrb>pQ9wnM_YY#2&afv#I?8o!g+ZOc&s1W(nx4I8hxj*{=jH%w@6(Tw@?yXAW+p#wR7)QEo$abb5vb?2C*5&QH_hj&f>k!ufQ4y35v-2%V^|WMq5W{^ zSn4Hc+Yo8+^FC&LitCD3a=Ay;G85}B{KI5G#USqzyCmoSucD$N*K2d+A;#A!3*d7t15$dlG>#{949a4&W z4AB%)L#{Jiw}XI&`i4h3pD_RWQV^8{q|(8i7v_QOmBvkA1)Hmf_0YBl{(Sm~~Ami+>E-+*XK%1OFLIOun$J`Xmu_ za396Woxx9;Q9Uk}$Jr@hi7gxlsZ>wm53rTBP4EJCbS1NB%g-e-^( zH$|#>VN^@?zgD$XvJdB_z;WOVaq{6}g0A6U<4^;B9-iI`n)FD3#9HuTVHzz5vC6~N zGhEj$d2s<;Tl1#-AtcJhiQE(>o(AA=n*ZUy{t9~n8m!F(Gv$wvujACJ4n2-Re19uZ zID@C;@}I-WLt0d#Tmo}#xe|N*>x#^3YW1_&z?JJ-p{aB?EnzPn{+9NSYEL@}(Tzrc zCh4zd4=Qn>hotBr$nj-jL0~`Ey1q^!JhaZo+1Km#G?BiaQ3=m{o zqEtp>z2RJ*RHV6t#*2JotJQZ7$E)1S1*wwH?b|!gd*d5=$Jo+86 zgp}C!<=6XYShVoY9RXG_=(Lu4=~a%tT8u6c)|!LJngeW2qiJZ66~DO3a(HQUiYK)3 zRb0NGY?c{Yvz5F{9A^wZO=aN8<%npRD(6R8Rc6y$FVQtdpVQ$bD}A9J{jY*|eAKoc zU_H%Ea__+?V@>fB#B&6~VMZV#kje!|w8eaaVh_U3H^T{UAi1JD5 zW1K$hICWsY6A7lA^-(P(9tG~i7E20!ox)=Ck)g3OZ;Q{yKLj}~YB%TG%tUjCT5A&&-RhYA{S<6n!#B5&jW=t2K^>gRkkT%+ z3G)a!!%~KG=uVJ7p5TpkoUT)zV2IO*`0ynC$jEb6dtLB7PG950f;Z@^_CsdWZUCLv zjgjdDd46`(FBg&q`q=P`o&F%O&U)tRlB|r1Tcj<({9pfhJU@HL(Vq}_^797?E|BEw zC(6m>1Mi2BdOZXa6i2J3Rt~c-xG=0uj-xo67lmn`Bq0D(0VoSB|&_~XKD(=e7>I!WP0VbTy|Y3RQ##xA2Jik|@RUC|Axc<#+avu=kqC}W>TApmkLh#sCZ2!NqRsS%qb2uNAP>U6nKm7m1 z?zu?_)c?Z0D*+~mrP&&Xb>yeDj@(bATE3J}B2W6xQu7@$ivTMV(O<`z%KVG}@UT@o ztV_go!Mh6qD_#pG6fk0)8R8lld~AE35Wm{IR`|OxM(aOm`RA2OR>hyd>Qiv?NS80R zZNE=UuiR(2Jk6j#)96^hLEsO>NDfG*4^kjCV2zeD7MA%8din?0EaZt7%<~v|A@?$d zjB(rQ=fhhc?*1n6a!2ZXho8G-k|d@2XUD#yQTS&yqaHprB*?QkD!S1EaNYji9?#tZ zwPA+r`(?DZe5+s1Dm<=&f&84{9C?@WKlXf@fsY}zJH5;eP9}H^wN@=%7;FVBds(B* zGRs!(a(xu}D9N}$)shHG?Qt&n#sDS;Mtes`L4Lk~ivUmm2N@aEaX@Ad^xb~tv{CAW zH2LG+fSzm^X^(Blym-caFg?JCKZ7{N00^}S`JZno4RWtSE>n#I%3jud>OhNglKdsr z{o4fqE_6adLgP8M{E)51%9Qan>FMrh zo>aZ#B0w4va&y&I#m3cg#bVw0`T1?s5Qi*Pr0=x9$J+`<$P^Oz)Jh0_HWzcHI|H@4 z1Ci%XRBjs^8vut=@Y+t=RYLeY4?Y?jFK3bONqkR4$Hs7Z>>@U9t>iFnA>R+fB!0a) zU7?@VDynH>QHh<$dj-E0E3nM>M$?&C zT!a8_AnMfwIZB^{svahuoh3+9ZY~w$*YB6FKGGcNR2s!*t>jShI~w%FQH*2@%RS2x z@=#ne`r^jtv?Stp?VN@LilY(_05n_H$Bjj>%le#E?&2Sdfjp^*CEtCvS9U9{!GINP z!x7rwM`nF@b$CLaE#%<~a1I8woEYO(<(K{;n?~e3LD1s!t)VARL_t^NBHkx5iMy9VOG-{>MM)4Bj;DKffn zP^zn|OHK5WAm(hRAU@!v4Slu*P_MI}fEO6Yb0(v<7)*OR`%dt@<}Vic*_BXC9kQ8& z-!@xoN6b#d{@R&}%e>b_A_NVqolg_+tzg^+$4*yf=Oe^;c?lO18C2S@03i7_{o=ws z3iK@M8lcUr4*<&f6&BW&s3!J&?X;@2v=r#(Sw;bYG*1CQVz0-GJ32V1us=;kZ=^4z zHMg*!u{eS?WMRX?gO#FT1GEZd48>P${xU&|Dm-k{<)!A~D>>@cPyRPaAIKD~u_lpu z5CzL=m$75U4@aFsqN6eAOcD1tzuQmOdrnV_sqFza{o<~(r^gKieu50x%IKuj>GO=C z0Zho&!aO_#!VwV>0Dd)u20+ToUxc+%OE7$_og#vN+ugu=lYwRN7sIa>xs#V`xE+oc zVZP4NG4}s}Vt90kcR~&8shd>Kt6(iHH@$Y+z# z)IXBxHqsR-!gnj(YC}Aa@PcqNr#vX>^JkPkRV(> z50?rZ$ix_Ll(f}0`b*jbjzqDgosh`q>6IrY;%|nEQ3|>~rD}T{=8lbxEiWzI`TSDv zReN`LxE-lzwin&TvCBtt=OQ;I z4vrGrx94yiFY-Tbii#MD8miVTUlnZ(jQ@xTf-vMX8uItC!5Ts9`Oc}UtLjolR-2g(k>!;_&Ot@FFvcJz7@7Bvy>aQ84KvZ}a zoa2z5nfc^stU%7}?q)kz+-)nSQPh?a( zTBtwXoBAnu%D_WmQ!gqvAN2S+OsD)~TNI4eWjISvez3RqyWD}hAnpnE>1>tRtgK0h zhoYFpB>=;54lD_9KEz7Ip z<;QL^Cu#@)|4U28b85nAcc*?5^SUb{awt7{_#kSnC0W8=j{Ql@?pk^C8#_DRyW{l3 z7mY185F@2Fy2~Hmz>GiJ)oAekH>H<0P*=SOdZzPLvQsGs!HzJpT|kDPIG!!@S_h64 z%GsoX`tG6Vse{e-Gp-xw?HI5Bvi0Ew=iX+|#1hz{&Q zBc!M}H3gJP%5?5bKWI!5h99`m3+#hn;cJkei0j5PvDf9PEPrr9#Uu+TMSZDd8~tv$ z80{8(p1nPa)$Mmyi<)#+5Ung#qv69%RENar5nxk^m3Ko(m(SAVxX&b*k&l|Zj&m|I z2LQQpL|4%xcp)9OR|^cwS=mmt#r*#TpyvQ?s3!4%I=+19cE{(MlBYLst_7VVa%mlAhd^cN++Vn!vMzN>F< zhQ8;WpL~@5w<+tuC6-x0Qt^Y*w;vTZH#bxP*Lg`|&MWWKhx=}~am)W3*==%KZec?I z8kvto2JCZtGnG`%J@vEOVZ=tQ+2I1V+r!ye2fN2o`r$54gX6!TP?vSI*LT2LZQ_40 z`*u=$;^~JEA6))e(f${y74-HYV9$eo>Iet2y|zn|5Z_A_IIw3=-D7-u0G40?f~ASo z0CCovuw~(dobO8C;NRba@Cd>}fNgy52^FTK^kkkCIt%j3ZkZaHq>o>%NgE2-2j-D= z5Y?0iANe$1P_vYywft?;XwT`b;h}&ng{*owl5Zy*So@y9omy@f6rXte*G^a~Jph{? z(-XfD_573^2aQVoJ^#|O_V#u?2|X&j5a4yV-W^Rzza0UBkra&Ei0|~DQ#g!OdC?8s z^DJOw)h}{E{(!h0S3&@rvNpYrCed$idx;wopOQz2U!wi(?abi$5g z=~9OoGyoh383c;Z_gI!^K&LExSI}mt0DH&y(_dLpSaGbWlYUSC1=WB>dSry%6h;>R z!)e<7Y-wMJd(=Yj-C8^&xVWSc>uibZR!okbj%r-}l|u~l<`XXQC)xd2N)YLs-==JF z%%r`Q@MH3M`^wa}^|O}aN=^S^=t(Q8%ClkD?}lh7>>LlL9?O|>Yjb>YuDg`u z_3Ek#BJ@PQ*K6zQ8V;Ph_+E5H^SF^}vPynWD2h%q&@1-u#7x%7O3E4)pn>GCexO4& zv<=b;Jh+@y4pMWEFK+Bvm!m)Zl8oMlsZ&L)jHF1yrj%u2!|z{odtGuP1!WU|^&G00IYqbMKUA zqf;qX1TZ=#%@2xT)YD8)Pn%Kr&@J@8?d}#`@;szbT*Z4|$E=m;{Sr7WclQIoKi#lT zuv7G2wCL4v2sdyr>gxZOS?{0APhQgsuJ_42!t&ubj9?Yw74oVt0-!?v3W%k%b4x@H z_lq4t;7;0IPp~>=j;h%x3Mv-Y?A!b)a@*sV8JaJCc>#w~l=bk#-maoo6FtC7l}@VW zjHv<^c(D-(|H@qQ2d$Kw5+T%LBUT7=j9le*RmQ*au_8G+A9w&`oZV=lW}~cK z7;NSmHL9GU@u&M+s9dOR(`qB>b#dSfZNN9;;{$+6x%q{f;ST2j=lyJSRI1sY;Wb-* zoX<_|Y2Adb6T$B`xolb}q;P?b8F<~YIzF;Z#6?SlFGsxc@EB_#zBe zD0)->v(pxdkpSgFBUTT_r}?FMo|-~}MRX6f?--d4IQKXCCvuCUn)JA{OjaN zVbjN^5W1MwcdE6Uar`g&82_jH{I6*Nuwi-ZP3}f9=A?=Ea0P@-VBG=-FH>axDMLRi zOUvTILK8C}5X%bs4kWKc%|rp6S{P(Q$8Oa8$^}nsP4#;LAu+M|<)jt|U@|F)7rSjk zr!vU}woCQmj8Cq4s#3rEbbdgUVQZ?C4nmP?9@O+n*@3bQ~6 zfb>pTO)V81@ij8OuC8tzy1lif_wl31%|;?MB~|p7FSi%FA^x93LTn1S*VfksgYN+ImTHzj0{+_TA9NQ${+J%gAtF57bo=Dwjxr-91Z4*2 zCzQ`begh*WAB_LU0?b*+y2}bU@cV}MpL(*J`6YufWtyFpC4j7W>%Gy7=l8T{(r9;O zB}iIYI!nD070$=Umo+LTHJo`biXBb6a@9IK`Lr+ym}+cFiJ-m6@ZV2=zaCAUvBSs5 zKXrkDT>y7UK@u1&Q20?#?^`ZA8(T8CL?8mcp(OL^+n1iNxXhoifX4-sQd6~R({4Zv zVbTJ(x3~T4ohQIOM!?oxGN^+h3bLnyIr@f zK?z@Tb2>(6H3aAp@!-^aiZ%||og#f%4i)x+jx~b#YDkrA92?_Hk81S;7L#J-bV>dx m;27Nge`pR>bi-u?)jrf`o0U>v1UM>>q#&az{Y%p1^Zx^olNrVU literal 0 HcmV?d00001 diff --git a/maze_img02.png b/maze_img02.png new file mode 100644 index 0000000000000000000000000000000000000000..7a2dfdd0490cf2446707262563a27452cf2763f6 GIT binary patch literal 9928 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 q%P`AzA_wSRe{fi7>Q