def __init__(self): super(FenetrePrincipale,self).__init__() # Charge un labyrinthe vide self.labyrinthe = Labyrinthe() # Charge les images correspondantes aux type de case self.ICONE_VIDE = QPixmap("Icones/floor.png") self.ICONE_ENTREE = QPixmap("Icones/entry.png") self.ICONE_SORTIE = QPixmap("Icones/exit.png") self.ICONE_MUR = QPixmap("Icones/wall.png") self.ICONE_PIEGE = QPixmap("Icones/trap.png") self.ICONE_PERSO = QPixmap("Icones/perso_front.png") self.case_perso = None # Position courante du personnage self.nb_coups = 0 # Numéro de l'itération en cours self.nb_coups_max = 0 # Nb d'itérations max self.nb_coups_en_suivant = 0 # Nb d'itérations choisies dans la zone de texte self.toggleAlgo = False # Permet de switcher entre exploration et exploitation self.case_init = None # Position initiale du personnage self.politique_choisie = 0 # Politique d'apprentissage choisie depuis les paramètres self.apprentissage_termine = False # Indique la fin de l'apprentissage self.lecture_en_cours = False # Indique si une lecture (bouton play) est en cours self.deplacement_en_cours = False self.last_move = None self.moyenne_renforcement = [0,0,0,0,0,0] # Enregistre les moyennes de renforcement pour un labyrinthe pour chaque politique self.chargerParametresQLearning() self.apprentissage_fini.connect(self.reinitialiserApprentissage) # Signal emit lors d'une fin d'apprentissage # Initialise les éléments de la fenêtre self.initUI()
def nouveauLabyrinthe(self): # Lance une fenêtre pour créer un nouveau labyrinthe f = FenetreNewLabyrinthe(self) aleatoire = False if (f.exec_()): # Récupère les choix dès que la FenetreNewLabyrinthe est validée nb_lignes,nb_colonnes, aleatoire = f.getChoix() self.labyrinthe = Labyrinthe(nb_lignes,nb_colonnes,aleatoire) # Charge les paramètres du QLearning self.chargerParametresQLearning() # Estime un nombre de coups maximum pour le labrinthe self.nb_coups_max = self.labyrinthe.nb_lignes*self.labyrinthe.nb_colonnes*20 my_settings = QSettings("Bazerque-Vigie", "Labyrinthe"); my_settings.beginGroup("General"); my_settings.setValue("nb_coups", self.nb_coups_max) my_settings.endGroup() # Initialise la grille suivant les choix effectués self.grille.setRowCount(nb_lignes) self.grille.setColumnCount(nb_colonnes) brush = QBrush() brush.setTexture(self.ICONE_VIDE) for ligne in range(nb_lignes): for colonne in range(nb_colonnes): # Ajoute un item vide à la grille self.grille.setItem(ligne,colonne,QTableWidgetItem()) self.grille.item(ligne,colonne).setTextAlignment(Qt.AlignCenter) self.grille.item(ligne,colonne).setForeground(Qt.black) # Suivant le type de case modifie l'image de la case if(self.labyrinthe.grille[ligne][colonne].type==MUR): brush.setTexture(self.ICONE_MUR) self.grille.item(ligne,colonne).setBackground(brush) elif(self.labyrinthe.grille[ligne][colonne].type==VIDE): brush.setTexture(self.ICONE_VIDE) self.grille.item(ligne,colonne).setBackground(brush) # Empêche l'utilisateur de cliquer sur le bouton play self.playAction.setEnabled(False) self.nextAction.setEnabled(False) self.saveAction.setEnabled(True) self.nb_coups_simules.setEnabled(False) # Affiche ou masque les MaxQ selon l'état du bouton MaxQ self.triggerMaxQ() # Reinitialise le perso si un labyrinthe avait déjà été utilisé self.case_perso = None self.changeStatus() self.moyenne_renforcement=[0,0,0,0,0,0]
def creer_labyrinthe_depuis_chaine(chaine): elements = {} robot = 0 lignes = chaine.split("\n") for ligne in enumerate(lignes): for char in enumerate(ligne[1]): if char[1] == "X": robot = (ligne[0], char[0]) elements[(ligne[0], char[0])] = char[1] elif char[1] == 'U': sortie = (ligne[0], char[0]) elements[(ligne[0], char[0])] = char[1] else: elements[(ligne[0], char[0])] = char[1] elements[(ligne[0], (char[0] + 1))] = "\n" return Labyrinthe(robot, elements, sortie)
def chargerLabyrinthe(self): # Instancie un labyrinthe à partir d'un fichier path_labyrinthe = QFileDialog.getOpenFileName(self,'Charger un labyrinthe','./') if (path_labyrinthe!=""): self.labyrinthe = Labyrinthe() self.labyrinthe.loadMaze(path_labyrinthe) # Charge les paramètres du QLearning self.chargerParametresQLearning() # Estime un nombre de coups maximum pour le labrinthe self.nb_coups_max = self.labyrinthe.nb_lignes*self.labyrinthe.nb_colonnes*20 my_settings = QSettings("Bazerque-Vigie", "Labyrinthe"); my_settings.beginGroup("General"); my_settings.setValue("nb_coups", self.nb_coups_max) my_settings.endGroup() # Initialise la grille du labyrinthe selon le labyrinthe chargé self.grille.setRowCount(self.labyrinthe.nb_lignes) self.grille.setColumnCount(self.labyrinthe.nb_colonnes) brush = QBrush() for ligne in range(self.labyrinthe.nb_lignes): for colonne in range(self.labyrinthe.nb_colonnes): # Ajoute un item vide à la grille self.grille.setItem(ligne,colonne,QTableWidgetItem()) self.grille.item(ligne,colonne).setTextAlignment(Qt.AlignCenter) self.grille.item(ligne,colonne).setForeground(Qt.black) # Suivant le type de case modifie l'image de la case if(self.labyrinthe.grille[ligne][colonne].type==ENTREE): brush.setTexture(self.ICONE_ENTREE) self.grille.item(ligne,colonne).setBackground(brush) elif(self.labyrinthe.grille[ligne][colonne].type==SORTIE): brush.setTexture(self.ICONE_SORTIE) self.grille.item(ligne,colonne).setBackground(brush) elif(self.labyrinthe.grille[ligne][colonne].type==MUR): brush.setTexture(self.ICONE_MUR) self.grille.item(ligne,colonne).setBackground(brush) elif(self.labyrinthe.grille[ligne][colonne].type==PIEGE): brush.setTexture(self.ICONE_PIEGE) self.grille.item(ligne,colonne).setBackground(brush) elif(self.labyrinthe.grille[ligne][colonne].type==VIDE): brush.setTexture(self.ICONE_VIDE) self.grille.item(ligne,colonne).setBackground(brush) self.saveAction.setEnabled(False) # Affiche ou masque les MaxQ selon l'état du bouton MaxQ self.triggerMaxQ() # Reinitialise le perso si un labyrinthe avait déjà été utilisé self.case_perso = None self.changeStatus() self.moyenne_renforcement=[0,0,0,0,0,0]
class FenetrePrincipale(QMainWindow): apprentissage_fini = pyqtSignal() def __init__(self): super(FenetrePrincipale,self).__init__() # Charge un labyrinthe vide self.labyrinthe = Labyrinthe() # Charge les images correspondantes aux type de case self.ICONE_VIDE = QPixmap("Icones/floor.png") self.ICONE_ENTREE = QPixmap("Icones/entry.png") self.ICONE_SORTIE = QPixmap("Icones/exit.png") self.ICONE_MUR = QPixmap("Icones/wall.png") self.ICONE_PIEGE = QPixmap("Icones/trap.png") self.ICONE_PERSO = QPixmap("Icones/perso_front.png") self.case_perso = None # Position courante du personnage self.nb_coups = 0 # Numéro de l'itération en cours self.nb_coups_max = 0 # Nb d'itérations max self.nb_coups_en_suivant = 0 # Nb d'itérations choisies dans la zone de texte self.toggleAlgo = False # Permet de switcher entre exploration et exploitation self.case_init = None # Position initiale du personnage self.politique_choisie = 0 # Politique d'apprentissage choisie depuis les paramètres self.apprentissage_termine = False # Indique la fin de l'apprentissage self.lecture_en_cours = False # Indique si une lecture (bouton play) est en cours self.deplacement_en_cours = False self.last_move = None self.moyenne_renforcement = [0,0,0,0,0,0] # Enregistre les moyennes de renforcement pour un labyrinthe pour chaque politique self.chargerParametresQLearning() self.apprentissage_fini.connect(self.reinitialiserApprentissage) # Signal emit lors d'une fin d'apprentissage # Initialise les éléments de la fenêtre self.initUI() ''' Initialise l'interface de la fenêtre ''' def initUI(self): # Crée les boutons de la barre d'outil self.newAction = QAction(QIcon('Icones/new.png'),u'&Nouveau labyrinthe',self) self.newAction.setShortcut('Ctrl+N') self.newAction.triggered.connect(self.nouveauLabyrinthe) self.openAction = QAction(QIcon('Icones/open.png'),u'&Ouvrir un labyrinthe',self) self.openAction.setShortcut('Ctrl+O') self.openAction.triggered.connect(self.chargerLabyrinthe) self.saveAction = QAction(QIcon('Icones/save.png'),u'&Enregistrer le labyrinthe',self) self.saveAction.setEnabled(False) self.saveAction.setShortcut('Ctrl+S') self.saveAction.triggered.connect(self.enregistrerLabyrinthe) self.playAction = QAction(QIcon('Icones/play.png'),u'&Lancer l\'apprentissage jusqu\'à atteindre le nb d\'itérations max',self) self.playAction.setEnabled(False) self.playAction.setShortcut('Ctrl+P') self.playAction.triggered.connect(self.runPlayPause) self.nextAction = QAction(QIcon('Icones/next.png'),u"&Exécuter une étape d'apprentissage",self) self.nextAction.setEnabled(False) self.nextAction.setShortcut('Ctrl+E') self.nextAction.triggered.connect(self.runPolitique1Coup) self.nb_coups_simules = QLineEdit(self) self.nb_coups_simules.setFixedWidth(90) self.nb_coups_simules.setEnabled(False) self.nb_coups_simules.setValidator( QIntValidator(self) ) self.nb_coups_simules.setToolTip(u"Entrez un nb d'itération à effectuer puis valider") self.nb_coups_simules.returnPressed.connect(self.runPolitiqueNbCoups) self.stopAction = QAction(QIcon('Icones/stop.png'),'&Arreter',self) self.stopAction.setEnabled(False) self.stopAction.setShortcut('Ctrl+S') self.stopAction.triggered.connect(self.stopPolitique) self.moyAction = QAction(QIcon('Icones/moy.png'),'&Afficher les moyennes de renforcement',self) self.moyAction.setShortcut('Ctrl+M') self.moyAction.triggered.connect(self.showMoy) self.maxQAction = QAction(QIcon('Icones/maxQ.png'),'&Afficher/Masquer les max(Q)',self) self.maxQAction.setCheckable(True) self.maxQAction.setShortcut('Ctrl+Q') self.maxQAction.triggered.connect(self.triggerMaxQ) self.settingsAction = QAction(QIcon('Icones/settings.png'),u'&Modifier les paramètres d\'apprentissage',self) self.settingsAction.setShortcut('Ctrl+U') self.settingsAction.triggered.connect(self.modifierParametres) # Ajoute un spacer spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding) # Ajoute les boutons à la barre d'outil self.toolbar = self.addToolBar('toolbar') self.toolbar.setAllowedAreas(Qt.TopToolBarArea) self.toolbar.setFloatable(False) self.toolbar.addAction(self.newAction) self.toolbar.addAction(self.openAction) self.toolbar.addAction(self.saveAction) self.toolbar.addAction(self.playAction) self.toolbar.addAction(self.nextAction) self.toolbar.addAction(self.stopAction) self.toolbar.addWidget(self.nb_coups_simules) self.toolbar.addWidget(spacer) self.toolbar.addAction(self.moyAction) self.toolbar.addAction(self.maxQAction) self.toolbar.addAction(self.settingsAction) self.toolbar.setContextMenuPolicy(Qt.CustomContextMenu) # Ajoute une barre de setStatusTip self.lbl_status = QLabel(u"Politique " + str(self.politique_choisie+1) + u" | Nb passes max = 0" + u" | Itération n° " + str(self.nb_coups)) self.statusBar().addPermanentWidget(self.lbl_status,1) # Ajoute une grille pour le labyrinthe self.grille = QTableWidget() self.grille.setFrameShape(QFrame.NoFrame) self.grille.setShowGrid(False) self.grille.horizontalHeader().hide() self.grille.verticalHeader().hide() self.grille.setSelectionMode(QAbstractItemView.NoSelection) self.grille.setEditTriggers(QAbstractItemView.NoEditTriggers) self.grille.cellDoubleClicked.connect(self.drawCase) self.grille.setFocusPolicy(Qt.NoFocus) self.grille.verticalHeader().setResizeMode(QHeaderView.Fixed) self.grille.horizontalHeader().setResizeMode(QHeaderView.Fixed) self.grille.verticalHeader().setDefaultSectionSize(32) self.grille.horizontalHeader().setDefaultSectionSize(32) self.entreeAction = QAction(QIcon(self.ICONE_ENTREE),u'Entrée',self) self.entreeAction.setIconVisibleInMenu(True) self.entreeAction.setCheckable(True) self.sortieAction = QAction(QIcon(self.ICONE_SORTIE),u'Sortie',self) self.sortieAction.setIconVisibleInMenu(True) self.sortieAction.setCheckable(True) self.murAction = QAction(QIcon(self.ICONE_MUR),u'Mur',self) self.murAction.setIconVisibleInMenu(True) self.murAction.setCheckable(True) self.piegeAction = QAction(QIcon(self.ICONE_PIEGE),u'Piège',self) self.piegeAction.setIconVisibleInMenu(True) self.piegeAction.setCheckable(True) self.videAction = QAction(QIcon(self.ICONE_VIDE),u'Vide',self) self.videAction.setIconVisibleInMenu(True) self.videAction.setCheckable(True) self.persoAction = QAction(QIcon(self.ICONE_PERSO),u'Placer le personnage',self) self.persoAction.setIconVisibleInMenu(True) self.persoAction.setCheckable(True) self.groupe_action = QActionGroup(self) self.groupe_action.addAction(self.persoAction) self.groupe_action.addAction(self.entreeAction) self.groupe_action.addAction(self.sortieAction) self.groupe_action.addAction(self.murAction) self.groupe_action.addAction(self.piegeAction) self.groupe_action.addAction(self.videAction) self.persoAction.setChecked(True) # Ajoute les boutons à la barre d'outil self.toolbar2 = QToolBar(self) self.addToolBar(Qt.RightToolBarArea,self.toolbar2) self.toolbar2.setFloatable(False) self.toolbar2.addAction(self.persoAction) self.toolbar2.addAction(self.entreeAction) self.toolbar2.addAction(self.sortieAction) self.toolbar2.addAction(self.murAction) self.toolbar2.addAction(self.piegeAction) self.toolbar2.addAction(self.videAction) self.toolbar2.setContextMenuPolicy(Qt.CustomContextMenu) # Initialise et centre la fenêtre bureau = QDesktopWidget(); largeur = self.sizeHint().width() self.setGeometry((bureau.screen().width()/2)-(largeur/2),(bureau.screen().height()/2)-(largeur/2),largeur,largeur); self.setCentralWidget(self.grille) self.setWindowIcon(QIcon('Icones/maze.png')) self.setWindowTitle("Labyrinthe QLearning") self.show() ''' Actualise l'affichage de la barre de status ''' def changeStatus(self): self.lbl_status.setText(u"Politique " + str(self.politique_choisie+1) + u" | Nb passes max " + str(self.nb_coups_max) + u" | Itération n° " + str(self.nb_coups)) ''' Affiche/Masque les q de chaque case ''' def triggerMaxQ(self): # Affiche les q de chaque case if(self.maxQAction.isChecked()): for ligne in range(self.labyrinthe.nb_lignes): for colonne in range(self.labyrinthe.nb_colonnes): maxq = max(self.qlearning.table_q[ligne,colonne]) self.grille.item(ligne,colonne).setText(str(round(maxq,1))) liste_Q = [] self.grille.item(ligne,colonne).setToolTip("G:"+str(self.qlearning.table_q[ligne,colonne][0])+" D:"+str(self.qlearning.table_q[ligne,colonne][1])+" H:"+str(self.qlearning.table_q[ligne,colonne][2])+" B:"+str(self.qlearning.table_q[ligne,colonne][3])) # Masque les q de chaque case else: for ligne in range(self.labyrinthe.nb_lignes): for colonne in range(self.labyrinthe.nb_colonnes): self.grille.item(ligne,colonne).setText('') ''' Colorie la case double cliquée suivant le type de case choisi ''' def drawCase(self,row,column): brush = QBrush() brush.setTexture(self.ICONE_VIDE) if(self.persoAction.isChecked()): # Positionne le personnage self.positionnerPerso(row,column) self.case_perso = self.labyrinthe.grille[row][column] self.case_init = self.case_perso self.qlearning.case_init = self.case_perso # Active les actions self.playAction.setEnabled(True) self.nextAction.setEnabled(True) self.nb_coups_simules.setEnabled(True) elif(self.entreeAction.isChecked()): brush.setTexture(self.ICONE_ENTREE) type_case = ENTREE elif(self.sortieAction.isChecked()): brush.setTexture(self.ICONE_SORTIE) type_case = SORTIE elif(self.murAction.isChecked()): brush.setTexture(self.ICONE_MUR) type_case = MUR elif(self.piegeAction.isChecked()): brush.setTexture(self.ICONE_PIEGE) type_case = PIEGE elif(self.videAction.isChecked()): brush.setTexture(self.ICONE_VIDE) type_case = VIDE # Le labyrinthe a été modifié, on autorise donc l'enregistrement if(self.persoAction.isChecked()==False): if(self.labyrinthe.grille[row][column].type!=type_case): self.saveAction.setEnabled(True) # Met à jour le labyrinthe self.labyrinthe.grille[row][column].type=type_case # Change la couleur de la case suivant son nouveau type self.grille.item(row, column).setBackground(brush) ''' Récupère les paramètres enregistrés du QLearning ''' def chargerParametresQLearning(self): my_settings = QSettings("Bazerque-Vigie", "Labyrinthe"); # Charge les paramètres généraux my_settings.beginGroup("General") if (my_settings.contains("politique")): self.politique_choisie = my_settings.value("politique").toInt()[0] if (my_settings.contains("nb_coups")): self.nb_coups_max = my_settings.value("nb_coups").toInt()[0] if (my_settings.contains("vitesse")): self.vitesse = my_settings.value("vitesse").toInt()[0] my_settings.endGroup() # Charge les coûts des déplacements my_settings.beginGroup("Couts") if (my_settings.contains("deplacement_normal")): deplacement_normal = my_settings.value("deplacement_normal").toFloat()[0] if (my_settings.contains("deplacement_piege")): deplacement_piege = my_settings.value("deplacement_piege").toFloat()[0] if (my_settings.contains("deplacement_sortie")): deplacement_sortie = my_settings.value("deplacement_sortie").toFloat()[0] self.qlearning = QLearning(self.labyrinthe, deplacement_normal,deplacement_piege,deplacement_sortie,self.case_init) ''' Modifie les paramètres ''' def modifierParametres(self): f = FenetreParametres(self) if (f.exec_()): # Récupère les choix dès que la FenetreParametres est validée self.politique_choisie,self.nb_coups_max, self.vitesse, deplacement_normal,deplacement_piege,deplacement_sortie = f.getChoix() # Modifie les paramètres initiaux du QLearning self.qlearning = QLearning(self.labyrinthe, deplacement_normal,deplacement_piege,deplacement_sortie,self.case_init) # Actualise la barre de status self.changeStatus() ''' Affiche les moyennes d'apprentissage calculées pour le labyrinthe actuel ''' def showMoy(self): # Lance une fenêtre pour créer un nouveau labyrinthe f = FenetreMoyennes(self,self.moyenne_renforcement[0],self.moyenne_renforcement[1],self.moyenne_renforcement[2],self.moyenne_renforcement[3],self.moyenne_renforcement[4],self.moyenne_renforcement[5]) f.exec_() ''' Initialise le labyrinthe à partir d'un fichier ''' def chargerLabyrinthe(self): # Instancie un labyrinthe à partir d'un fichier path_labyrinthe = QFileDialog.getOpenFileName(self,'Charger un labyrinthe','./') if (path_labyrinthe!=""): self.labyrinthe = Labyrinthe() self.labyrinthe.loadMaze(path_labyrinthe) # Charge les paramètres du QLearning self.chargerParametresQLearning() # Estime un nombre de coups maximum pour le labrinthe self.nb_coups_max = self.labyrinthe.nb_lignes*self.labyrinthe.nb_colonnes*20 my_settings = QSettings("Bazerque-Vigie", "Labyrinthe"); my_settings.beginGroup("General"); my_settings.setValue("nb_coups", self.nb_coups_max) my_settings.endGroup() # Initialise la grille du labyrinthe selon le labyrinthe chargé self.grille.setRowCount(self.labyrinthe.nb_lignes) self.grille.setColumnCount(self.labyrinthe.nb_colonnes) brush = QBrush() for ligne in range(self.labyrinthe.nb_lignes): for colonne in range(self.labyrinthe.nb_colonnes): # Ajoute un item vide à la grille self.grille.setItem(ligne,colonne,QTableWidgetItem()) self.grille.item(ligne,colonne).setTextAlignment(Qt.AlignCenter) self.grille.item(ligne,colonne).setForeground(Qt.black) # Suivant le type de case modifie l'image de la case if(self.labyrinthe.grille[ligne][colonne].type==ENTREE): brush.setTexture(self.ICONE_ENTREE) self.grille.item(ligne,colonne).setBackground(brush) elif(self.labyrinthe.grille[ligne][colonne].type==SORTIE): brush.setTexture(self.ICONE_SORTIE) self.grille.item(ligne,colonne).setBackground(brush) elif(self.labyrinthe.grille[ligne][colonne].type==MUR): brush.setTexture(self.ICONE_MUR) self.grille.item(ligne,colonne).setBackground(brush) elif(self.labyrinthe.grille[ligne][colonne].type==PIEGE): brush.setTexture(self.ICONE_PIEGE) self.grille.item(ligne,colonne).setBackground(brush) elif(self.labyrinthe.grille[ligne][colonne].type==VIDE): brush.setTexture(self.ICONE_VIDE) self.grille.item(ligne,colonne).setBackground(brush) self.saveAction.setEnabled(False) # Affiche ou masque les MaxQ selon l'état du bouton MaxQ self.triggerMaxQ() # Reinitialise le perso si un labyrinthe avait déjà été utilisé self.case_perso = None self.changeStatus() self.moyenne_renforcement=[0,0,0,0,0,0] ''' Crée un nouveau labyrinthe ''' def nouveauLabyrinthe(self): # Lance une fenêtre pour créer un nouveau labyrinthe f = FenetreNewLabyrinthe(self) aleatoire = False if (f.exec_()): # Récupère les choix dès que la FenetreNewLabyrinthe est validée nb_lignes,nb_colonnes, aleatoire = f.getChoix() self.labyrinthe = Labyrinthe(nb_lignes,nb_colonnes,aleatoire) # Charge les paramètres du QLearning self.chargerParametresQLearning() # Estime un nombre de coups maximum pour le labrinthe self.nb_coups_max = self.labyrinthe.nb_lignes*self.labyrinthe.nb_colonnes*20 my_settings = QSettings("Bazerque-Vigie", "Labyrinthe"); my_settings.beginGroup("General"); my_settings.setValue("nb_coups", self.nb_coups_max) my_settings.endGroup() # Initialise la grille suivant les choix effectués self.grille.setRowCount(nb_lignes) self.grille.setColumnCount(nb_colonnes) brush = QBrush() brush.setTexture(self.ICONE_VIDE) for ligne in range(nb_lignes): for colonne in range(nb_colonnes): # Ajoute un item vide à la grille self.grille.setItem(ligne,colonne,QTableWidgetItem()) self.grille.item(ligne,colonne).setTextAlignment(Qt.AlignCenter) self.grille.item(ligne,colonne).setForeground(Qt.black) # Suivant le type de case modifie l'image de la case if(self.labyrinthe.grille[ligne][colonne].type==MUR): brush.setTexture(self.ICONE_MUR) self.grille.item(ligne,colonne).setBackground(brush) elif(self.labyrinthe.grille[ligne][colonne].type==VIDE): brush.setTexture(self.ICONE_VIDE) self.grille.item(ligne,colonne).setBackground(brush) # Empêche l'utilisateur de cliquer sur le bouton play self.playAction.setEnabled(False) self.nextAction.setEnabled(False) self.saveAction.setEnabled(True) self.nb_coups_simules.setEnabled(False) # Affiche ou masque les MaxQ selon l'état du bouton MaxQ self.triggerMaxQ() # Reinitialise le perso si un labyrinthe avait déjà été utilisé self.case_perso = None self.changeStatus() self.moyenne_renforcement=[0,0,0,0,0,0] ''' Enregistre le labyrinthe dessiné dans un fichier ''' def enregistrerLabyrinthe(self): # Lance une fenêtre pour récupérer l'endroit ou enregistrer le labyrinthe path_labyrinthe = QFileDialog.getSaveFileName(self,'Enregistrer le labyrinthe','./') if(path_labyrinthe!=""): try: with open(path_labyrinthe,'w') as f: # Ecrit le labyrinthe caractère par caractère suivant la couleur (donc le type) de chaque case for ligne in range(self.grille.rowCount()): for colonne in range(self.grille.columnCount()): if (self.labyrinthe.grille[ligne][colonne].type==ENTREE): f.write('E ') elif (self.labyrinthe.grille[ligne][colonne].type==SORTIE): f.write('S ') elif (self.labyrinthe.grille[ligne][colonne].type==MUR): f.write('M ') elif (self.labyrinthe.grille[ligne][colonne].type==PIEGE): f.write('P ') elif (self.labyrinthe.grille[ligne][colonne].type==VIDE): f.write('. ') f.write('\n') f.close() # Désactive le bouton sauvegarder et active le bouton play self.saveAction.setEnabled(False) except IOError: # Si le fichier est illisible print "Impossible de sauvegarder le labyrinthe dans ce fichier" ''' Efface le personnage de son ancienne case et le dessine sur la nouvelle ''' def deplacerPerso(self,ligne,colonne): brush = QBrush() # Efface le personnage de sa case actuelle # Suivant le type de case modifie l'image de la case if(self.labyrinthe.grille[ligne][colonne].type==ENTREE): brush.setTexture(self.ICONE_ENTREE) self.grille.item(ligne,colonne).setBackground(brush) elif(self.labyrinthe.grille[ligne][colonne].type==SORTIE): brush.setTexture(self.ICONE_SORTIE) self.grille.item(ligne,colonne).setBackground(brush) elif(self.labyrinthe.grille[ligne][colonne].type==PIEGE): brush.setTexture(self.ICONE_PIEGE) self.grille.item(ligne,colonne).setBackground(brush) elif(self.labyrinthe.grille[ligne][colonne].type==VIDE): brush.setTexture(self.ICONE_VIDE) self.grille.item(ligne,colonne).setBackground(brush) # Dessine le personnage sur sa nouvelle case brush.setTexture(self.ICONE_PERSO) # self.position_perso = (ligne,colonne) self.grille.item(self.case_perso.position[0],self.case_perso.position[1]).setBackground(brush) ''' Efface le personnage de sa dernière case ''' def effacerPerso(self): brush = QBrush() if(self.case_perso!=None): # Efface le personnage de sa case actuelle # Suivant le type de case modifie l'image de la case if(self.labyrinthe.grille[self.case_perso.position[0]][self.case_perso.position[1]].type==ENTREE): brush.setTexture(self.ICONE_ENTREE) self.grille.item(self.case_perso.position[0],self.case_perso.position[1]).setBackground(brush) elif(self.labyrinthe.grille[self.case_perso.position[0]][self.case_perso.position[1]].type==SORTIE): brush.setTexture(self.ICONE_SORTIE) self.grille.item(self.case_perso.position[0],self.case_perso.position[1]).setBackground(brush) elif(self.labyrinthe.grille[self.case_perso.position[0]][self.case_perso.position[1]].type==PIEGE): brush.setTexture(self.ICONE_PIEGE) self.grille.item(self.case_perso.position[0],self.case_perso.position[1]).setBackground(brush) elif(self.labyrinthe.grille[self.case_perso.position[0]][self.case_perso.position[1]].type==VIDE): brush.setTexture(self.ICONE_VIDE) self.grille.item(self.case_perso.position[0],self.case_perso.position[1]).setBackground(brush) ''' Place le personnage à l'endroit choisi par l'utilisateur ''' def positionnerPerso(self,ligne,colonne): brush = QBrush() if (self.labyrinthe.grille[ligne][colonne].type==ENTREE): self.effacerPerso() # Dessine le personnage sur sa nouvelle case brush.setTexture(self.ICONE_PERSO) self.grille.item(ligne,colonne).setBackground(brush) else: msg_warning = QMessageBox() msg_warning.setIcon(QMessageBox.Warning) msg_warning.setText(u"Le personnage doit être placé sur une entrée du labyrinthe !") msg_warning.exec_() ''' Stoppe l'apprentissage en cours ''' def stopPolitique(self): self.apprentissage_termine = True self.deplacement_en_cours = False self.lecture_en_cours = False # Fait un tour de plus pour arreter l'algo si click sur suivant self.runPolitique1Coup() ''' Lance l'apprentissage ou le met en pause suivant l'état du bouton ''' def runPlayPause(self): # Si le bouton est en mode play et click, et qu'il n'y a pas de déplacement en cours, lance l'algo if(self.lecture_en_cours==False and self.deplacement_en_cours==False): self.deplacement_en_cours = True # Empeche l'utilisateur de mofifier les parametres, de créer ou d'ouvrir un labyrinthe self.newAction.setEnabled(False) self.openAction.setEnabled(False) self.settingsAction.setEnabled(False) # Autorise l'utilisateur à cliquer sur le bouton stop self.stopAction.setEnabled(True) self.lecture_en_cours = True self.playAction.setIcon(QIcon('Icones/pause.png')) # Lance l'apprentissage avec la politique choisie self.runPolitiqueNbCoupsMax() # Sinon met en pause else: self.lecture_en_cours = False self.deplacement_en_cours = False self.playAction.setIcon(QIcon('Icones/play.png')) ''' Exécute la politique choisie ''' def runPolitiqueChoisie(self): if(self.politique_choisie==0): self.politique1() elif(self.politique_choisie==1): self.politique2() elif(self.politique_choisie==2): self.politique3() elif(self.politique_choisie==3): self.politique4() elif(self.politique_choisie==4): self.politique5() elif(self.politique_choisie==5): self.politique6() ''' Execute la politique choisie une fois ''' def runPolitique1Coup(self): if(self.apprentissage_termine==False): self.stopAction.setEnabled(True) self.newAction.setEnabled(False) self.openAction.setEnabled(False) self.settingsAction.setEnabled(False) # Effectue la politique choisie self.runPolitiqueChoisie() else: self.apprentissage_fini.emit() # Met à jour les QMAX self.triggerMaxQ() # Met à jour la barre de status self.changeStatus() ''' Execute la politique tant que le nb max de coups n'est pas atteint ''' ''' ou que l'utilisateur ne clique pas sur pause ou sur stop ''' def runPolitiqueNbCoupsMax(self): if(self.apprentissage_termine==False): if(self.lecture_en_cours==True): # Effectue la politique choisie self.runPolitiqueChoisie() # Exécute l'étape suivante au bout d'un délai définit par la vitesse du perso QTimer.singleShot(int(1000/self.vitesse), self.runPolitiqueNbCoupsMax) else: self.apprentissage_fini.emit() # Met à jour les QMAX self.triggerMaxQ() # Met à jour la barre de status self.changeStatus() ''' Execute la politique tant que le nb de coups entrés dans la barre ''' ''' d'outil n'est pas atteint ou que l'utilisateur ne clique pas sur ''' ''' le bouton stop ''' def runPolitiqueNbCoups(self): # Lit le nb d'itération à effectuer nb_iterations = int(self.nb_coups_simules.text()) self.stopAction.setEnabled(True) if(self.apprentissage_termine==False): if (self.lecture_en_cours==False): if(self.nb_coups_en_suivant<nb_iterations): self.deplacement_en_cours = True # Effectue la politique choisie self.runPolitiqueChoisie() self.nb_coups_en_suivant +=1 QTimer.singleShot(int(1000/self.vitesse), self.runPolitiqueNbCoups) else: self.deplacement_en_cours = False self.nb_coups_en_suivant = 0 nb_iterations = 0 else: self.apprentissage_fini.emit() self.deplacement_en_cours = False # Met à jour les QMAX self.triggerMaxQ() # Met à jour la barre de status self.changeStatus() ''' La politique 1 effectue une exploration pure. Les cases explorées sont choisies aléatoirement. ''' def politique1(self): print "nbcoups",self.nb_coups # if(self.lecture_en_cours==False and self.deplacement_en_cours==False): if(self.nb_coups==self.nb_coups_max-1): self.apprentissage_termine=True self.moyenne_renforcement[0] = self.qlearning.somme_recompenses/self.nb_coups_max print "Moyenne renforcement = ",self.moyenne_renforcement[0] else: case_precedente = self.case_perso self.case_perso = self.qlearning.exploration_pure(self.case_perso) self.nb_coups = self.nb_coups + 1 self.deplacerPerso(case_precedente.position[0],case_precedente.position[1]) ''' La politique 2 effectue une exploration exigente. L'exploration \"exigente\" défavorise un retour sur la dernière case explorée. ''' def politique2(self): print "nbcoups",self.nb_coups # if(self.lecture_en_cours==False and self.deplacement_en_cours==False): if(self.nb_coups==self.nb_coups_max-1): self.apprentissage_termine=True self.moyenne_renforcement[1] = self.qlearning.somme_recompenses/self.nb_coups_max print "Moyenne renforcement = ",self.moyenne_renforcement[1] else: case_precedente = self.case_perso self.case_perso,self.last_move = self.qlearning.exploration_exigente(self.case_perso,self.last_move) self.nb_coups = self.nb_coups + 1 self.deplacerPerso(case_precedente.position[0],case_precedente.position[1]) ''' La politique 3 effectue une exploration infaillible. L'exploration \"infaillible\" interdit un retour sur la ''' ''' dernière case explorée (sauf cul-de-sac). ''' def politique3(self): print "nbcoups",self.nb_coups if(self.nb_coups==self.nb_coups_max-1): self.apprentissage_termine=True self.moyenne_renforcement[2] = self.qlearning.somme_recompenses/self.nb_coups_max print "Moyenne renforcement = ",self.moyenne_renforcement[2] else: case_precedente = self.case_perso self.case_perso,self.last_move = self.qlearning.exploration_infaillible(self.case_perso,self.last_move) self.nb_coups = self.nb_coups + 1 self.deplacerPerso(case_precedente.position[0],case_precedente.position[1]) ''' La politique 4 effectue la totalité des passes en exploration pure puis recommence avec des exploitations. ''' ''' L'exploration pure choisie les cases aléatoirement. ''' def politique4(self): print "nbcoups",self.nb_coups case_precedente = self.case_perso if(self.toggleAlgo==False): self.case_perso = self.qlearning.exploration_pure(self.case_perso) self.nb_coups = self.nb_coups + 1 if(self.nb_coups==self.nb_coups_max): self.toggleAlgo = True self.nb_coups = 0 self.case_perso = self.case_init else: self.case_perso = self.qlearning.exploitation(self.case_perso) self.nb_coups = self.nb_coups + 1 if(self.nb_coups==self.nb_coups_max-1): self.apprentissage_termine=True self.moyenne_renforcement[3] = self.qlearning.somme_recompenses/(self.nb_coups_max*2) print "Moyenne renforcement = ",self.moyenne_renforcement[3] self.deplacerPerso(case_precedente.position[0],case_precedente.position[1]) if(self.nb_coups==self.nb_coups_max and self.toggleAlgo==True): self.apprentissage_fini.emit() ''' La politique 5 effectue la totalité des passes en exploration exigente puis recommence avec des exploitations. ''' ''' L'exploration \"exigente\" défavorise un retour sur la dernière case explorée. ''' def politique5(self): print "nbcoups",self.nb_coups case_precedente = self.case_perso if(self.toggleAlgo==False): self.case_perso,self.last_move = self.qlearning.exploration_exigente(self.case_perso,self.last_move) self.nb_coups = self.nb_coups + 1 if(self.nb_coups==self.nb_coups_max): self.toggleAlgo = True self.nb_coups = 0 self.case_perso = self.case_init else: self.case_perso = self.qlearning.exploitation(self.case_perso) self.nb_coups = self.nb_coups + 1 if(self.nb_coups==self.nb_coups_max-1): self.apprentissage_termine=True self.moyenne_renforcement[4] = self.qlearning.somme_recompenses/(self.nb_coups_max*2) print "Moyenne renforcement = ",self.moyenne_renforcement[4] self.deplacerPerso(case_precedente.position[0],case_precedente.position[1]) ''' La politique 6 effectue la totalité des passes en exploration infaillible puis recommence avec des exploitations. ''' ''' L'exploration \"infaillible\" interdit un retour sur la dernière case explorée (sauf cul-de-sac). ''' def politique6(self): print "nbcoups",self.nb_coups case_precedente = self.case_perso if(self.toggleAlgo==False): self.case_perso,self.last_move = self.qlearning.exploration_infaillible(self.case_perso,self.last_move) self.nb_coups = self.nb_coups + 1 if(self.nb_coups==self.nb_coups_max): self.toggleAlgo = True self.nb_coups = 0 self.case_perso = self.case_init else: self.case_perso = self.qlearning.exploitation(self.case_perso) self.nb_coups = self.nb_coups + 1 if(self.nb_coups==self.nb_coups_max-1): self.apprentissage_termine=True self.moyenne_renforcement[5] = self.qlearning.somme_recompenses/(self.nb_coups_max*2) print "Moyenne renforcement = ",self.moyenne_renforcement[5] self.deplacerPerso(case_precedente.position[0],case_precedente.position[1]) ''' Réinitialise les données d'apprentissage lors d'un click sur stop ou à la fin de l'apprentissage ''' def reinitialiserApprentissage(self): # Remet les compteurs à 0 self.nb_coups_en_suivant=0 self.nb_coups=0 # Réinitialise l'affichage des boutons de controle de lecture self.apprentissage_termine=False self.lecture_en_cours = False self.toggleAlgo = False self.playAction.setIcon(QIcon('Icones/play.png')) self.nb_coups_simules.setEnabled(False) self.nextAction.setEnabled(False) self.playAction.setEnabled(False) self.stopAction.setEnabled(False) # Efface le personnage self.effacerPerso() self.case_perso = None # Signale à l'utilisateur que l'apprentissage est terminé msg_warning = QMessageBox() msg_warning.setStandardButtons(QMessageBox.Ok | QMessageBox.No) msg_warning.setDefaultButton(QMessageBox.Ok) msg_warning.setIcon(QMessageBox.Information) msg_warning.setText(u"Apprentissage terminé !\nVoulez-vous effacer les données d'apprentissage (table des q) ?") res = msg_warning.exec_() if(res==QMessageBox.Ok): # Reinitialise qlearning self.chargerParametresQLearning() # Autorise l'utilisateur à mofifier les parametres, à créer ou d'ouvrir un labyrinthe self.newAction.setEnabled(True) self.openAction.setEnabled(True) self.settingsAction.setEnabled(True)
self.table_q[state.position][1]=val elif(move==HAUT): self.table_q[state.position][2]=val elif(move==BAS): self.table_q[state.position][3]=val ''' Affiche la table des q ''' def showQTable(self): for l in self.table_q.values(): print l ''' Teste les différentes fonctions de la classe ''' if __name__ == "__main__": lab1 = Labyrinthe() lab1.loadMaze("./Exemples/lab1") learn = QLearning(lab1,10,1.5,-5,50,lab1.grille[0][1]) print "Exploration 1" # learn.exploration_pure(lab1.grille[0][1]) a = learn.exploration_exigente(lab1.grille[0][1]) print "Exploration 2" learn.exploration_exigente(a) print "Exploitation" b = learn.exploitation(lab1.grille[0][1]) learn.exploitation(b) lab1.show() # learn.showQTable()
from Carte import Carte from Labyrinthe import Labyrinthe #si le joueur souhaite faire plusieur partie à la fois while 1: partieEnCours = False nbCarte = 0 choix = " " aGagner = False # On charge les cartes existantes cartes = utils.getMapFromDir("cartes") nbCarte = len(cartes) # on affiche le menu partieEnCour, index = utils.displayMenuMap(cartes) # on demande a l'utilisateur de choisir index = utils.getIndexFromChoice(nbCarte, partieEnCour, index) lab = Labyrinthe(cartes[index].labyrinthe) chemin = os.path.join("cartes", "last_save.txt") #une fois que le joueur a choisi sa carte, #on peut commencer a jouer while aGagner == False: #on affiche la carte print(lab) #on demande au joueur les actions a faire choix = utils.getChoice() #si le jouer ne souhaite pas quitter alors on la continue if choix[:1].lower() not in "q": #si le joueur a entrer un direction + une valeur if len(choix) > 1: #on separe la direction et le nb de deplacement a faire
from Labyrinthe import Labyrinthe from Labyrinthe.Pathfinder import Pathfinder from Labyrinthe.Traducteur import Traducteur from sys import argv if __name__ == "__main__": if len(argv) == 1: lab1 = Labyrinthe(10, 10) lab1.generate(False) else: if argv[1] == "-h": print("help: python3 Labyrinthe.py [-h] | [-x (number) -y (number)] | [-step] | [-solve]") exit(0) if "-x" in argv: try: tailleX = int(argv[argv.index("-x") + 1]) except ValueError: tailleX = 10 else: tailleX = 10 if "-y" in argv: try: tailleY = int(argv[argv.index("-y") + 1]) except ValueError: tailleY = 10 else: tailleY = 10
""" import os import fonctions import pickle import sys from fonctions import calc_deplac , sauvegarde_partie from carte import Carte from Labyrinthe import Labyrinthe # On charge les cartes existantes cartes = [] noms = [] laby = Labyrinthe(0,0,1) for nom_fichier in os.listdir("cartes"): if nom_fichier.endswith(".txt"): chemin = os.path.join("cartes", nom_fichier) nom_carte = nom_fichier[:-4].lower() if nom_carte[0:5] == 'save_': print('Voulez vous rejouer la partie précédente ?') check = input('[y/n]') if check == 'y': with open(chemin, 'r') as fichier: contenu = fichier.read() carte = Carte(nom_carte, contenu) laby = carte.labyrinthe chemin_carte_ouverte = nom_carte[5:-4] os.remove(chemin) else:
if y == ENNEMIE: self.screen.create_oval(posX + LARGEUR / 3, posY + HAUTEUR / 3, posX + 2 * LARGEUR / 3, posY + 2 * HAUTEUR / 3, fill="black") posX += LARGEUR posX = 0 posY += HAUTEUR def run(self): self.main.mainloop() if __name__ == "__main__": lab = Labyrinthe(10, 30) lab.generate(False) trad = Traducteur(lab, lab.getDepart(), lab.getArrive()) mot = Moteur(trad.getLabTrad()) trad.addObserver(mot) trad.traduire() pathfinder = Pathfinder(trad.getDepart(), trad.getArrivee(), trad) pathfinder.findGoodPath() pathfinder.bindPath() mot.run()