def aiUCT(self, grille): '''Déterminer la meilleure action en fonction des résultats de l'exploration UCT''' # recevoir une position p etat_initial = grille.getName() symbole_dont_c_est_le_tour = self.player # soit A l'arbre UCT vide à la racine près self.tree = Node(etat_initial) self.compteur_visite_etat = {} self.score_choix_action_dans_etat = {} self.compteur_choix_action_dans_etat = {} # boucle : plusieurs descentes dans l'arbre for i in range(self.num_descentes_dans_arbre): # soit p' une copie de p grille_copiee = Grille() grille_copiee.set(etat_initial) # soit N le noeud résultat d'une descente dans l'arbre (A, p') (N, symbole_dont_c_est_le_tour_pour_N) = self.TreeDown(grille_copiee, symbole_dont_c_est_le_tour) # soit R l'évaluation de p' grille_pour_N = N.name grille_simulee = Grille() grille_simulee.set(grille_pour_N) R = self.simulerMonteCarlo(grille_simulee, symbole_dont_c_est_le_tour_pour_N) # nous effectuons une remontée de l'arbre (A, N, R) self.TreeUp(N, R, symbole_dont_c_est_le_tour, symbole_dont_c_est_le_tour_pour_N) # renvoyer le coup fils (de la racine de A) qui a la meilleure valeur UCT meilleure_action = self.choisirActionUCT(grille) return meilleure_action
def changerEtatApresTransition(etat, action, joueur): '''Déterminer l'état obtenu lorsque le joueur effectue l'action dans l'état donné''' grille_copiee = Grille() grille_copiee.set(etat) grille_copiee.drop(joueur, action) nouvel_etat = grille_copiee.getName() return nouvel_etat
def TreeDown(self, position_courante, symbole_dont_c_est_le_tour): '''Descendre dans l'arbre UCT''' # soit N la racine de l'arbre N = self.tree joueur = symbole_dont_c_est_le_tour # boucle : fils non explorés de N grille = Grille() grille.set(N.name) mes_coups_possibles = grille.lookForAllowedSteps() while all([self.compteur_choix_action_dans_etat.has_key((N.name, i)) for i in mes_coups_possibles]): # soit F le fils de N ayant la plus grande valeur UCT if(len(mes_coups_possibles)>0): action = self.choisirActionUCT(grille) nouvel_etat = changerEtatApresTransition(N.name, action, joueur) F = Node(nouvel_etat, N) F.code = action N = F joueur = getOtherSymbol(joueur) grille.set(N.name) mes_coups_possibles = grille.lookForAllowedSteps() else: break # soir F un fils de N tiré au hasard parmi les fils non explorés grille.set(N.name) mes_coups_possibles = grille.lookForAllowedSteps() if(len(mes_coups_possibles)>0): actions_inexplorees = [i for i in mes_coups_possibles if not self.compteur_choix_action_dans_etat.has_key((N.name, i))] tirage = randint(0, len(actions_inexplorees)-1) action = actions_inexplorees[tirage] etat_inexplore = changerEtatApresTransition(N.name, action, joueur) F = Node(etat_inexplore, N) F.code = action joueur = getOtherSymbol(joueur) else: F = N return (F, joueur)