def __init__(self, config): self.intelligence = Intelligence(self, config) self.x = 10 self.y = 10 self.newX = self.x self.newY = self.y self.dirAngle = pi / 4 ## Current text describing state of ProcessArea, used to show best info about its state in GUI. self.paText = ' ' ## Fields of view for normal atomic action self.viewConesNormal = [] self.viewConesNormal.append(ViewCone(0.1, pi * 0.9, 5)) self.viewConesNormal.append(ViewCone(0.3, pi / 2, 20)) self.viewConesNormal.append(ViewCone(0.3, pi / 4, 30)) self.viewConesNormal.append(ViewCone(0.3, pi / 8, 50)) ## Fields of view for Explore atomic action self.viewConesForExplore = [] self.viewConesForExplore.append(ViewCone(0.4, pi, 10)) self.viewConesForExplore.append(ViewCone(0.4, pi, 20)) self.viewConesForExplore.append(ViewCone(0.4, pi, 30)) self.viewCones = self.viewConesNormal self.viewConeNormalMaxDist = 0 for vc in self.viewConesNormal: self.viewConeNormalMaxDist = max(self.viewConeNormalMaxDist, vc.distance) self.viewConeForExploreMaxDist = 0 for vc in self.viewConesForExplore: self.viewConeForExploreMaxDist = max( self.viewConeForExploreMaxDist, vc.distance) self.viewConeMaxDist = self.viewConeNormalMaxDist
def initialize(self): self.data = Data(self.parent) self.window = Window(self.parent) self.intelligence = Intelligence(self.parent) ## Initialisation des variables ## self.data.set_control(self) # Définition de l'afficheur du niveau self.window.set_control(self) self.intelligence.set_control(self) self.data.set_window(self.window) self.data.set_level(self.level) self.intelligence.set_data(self.data) ## Zone de jeu ## self.game_window = self.window.get_window() ## Image de fond ## self.background_img = Image.open("./fond.jpg") self.background_img = self.background_img.resize((2000,1200),Image.ANTIALIAS) self.background_img = ImageTk.PhotoImage(self.background_img) self.background = self.game_window.create_image(0,0,image = self.background_img) self.game_window.create_image(0, 0, image = self.background_img) ## Image du personnage ## self.perso_img = Image.open("./yoshi.gif") # Image du personnage self.perso_img_sym = Image.open("./yoshi_sym.gif") # Image du personnage perso_width = PERSO_WIDTH # Taille du personnage perso_height = PERSO_HEIGHT self.perso_img = ImageTk.PhotoImage(self.perso_img) # Création d'images utilisables par le Canvas self.perso_img_sym = ImageTk.PhotoImage(self.perso_img_sym) # Idem symétrique self.mario = self.game_window.create_image(self.data.player_pos[0],self.data.player_pos[1], image = self.perso_img) # Mise en place de l'image self.mario_sym = self.game_window.create_image(-50,-50, image = self.perso_img_sym) # Idem symétrique self.level_position = self.data.player_pos[0] -GAME_WIDTH*0.2 # positionnement initial du niveau ## Image du sol ## self.ground_img = Image.open("./ground.gif") self.ground_img = self.ground_img.resize((50,50)) self.ground_img = ImageTk.PhotoImage(self.ground_img) ## Image des passerelles ## self.passerelle_img = Image.open("./passerelle.gif") self.passerelle_img = self.passerelle_img.resize((50,10)) self.passerelle_img = ImageTk.PhotoImage(self.passerelle_img) self.draw(self.data) # Affichage du niveau dans la zone self.doing = 0 # Mario occupé à l'état initial self.game_window.mainloop()
class Agent: def __init__(self, config): self.intelligence = Intelligence(self, config) self.x = 10 self.y = 10 self.newX = self.x self.newY = self.y self.dirAngle = pi / 4 ## Current text describing state of ProcessArea, used to show best info about its state in GUI. self.paText = ' ' ## Fields of view for normal atomic action self.viewConesNormal = [] self.viewConesNormal.append(ViewCone(0.1, pi * 0.9, 5)) self.viewConesNormal.append(ViewCone(0.3, pi / 2, 20)) self.viewConesNormal.append(ViewCone(0.3, pi / 4, 30)) self.viewConesNormal.append(ViewCone(0.3, pi / 8, 50)) ## Fields of view for Explore atomic action self.viewConesForExplore = [] self.viewConesForExplore.append(ViewCone(0.4, pi, 10)) self.viewConesForExplore.append(ViewCone(0.4, pi, 20)) self.viewConesForExplore.append(ViewCone(0.4, pi, 30)) self.viewCones = self.viewConesNormal self.viewConeNormalMaxDist = 0 for vc in self.viewConesNormal: self.viewConeNormalMaxDist = max(self.viewConeNormalMaxDist, vc.distance) self.viewConeForExploreMaxDist = 0 for vc in self.viewConesForExplore: self.viewConeForExploreMaxDist = max( self.viewConeForExploreMaxDist, vc.distance) self.viewConeMaxDist = self.viewConeNormalMaxDist ## One step of agent if it is out of the world. # # Does nothing in virtual world - no movement, perception etc. # Only update its SpaceMap. def StepOut(self): action = self.intelligence.actionSelector.GetOutAction() action.duration = 10 self.intelligence.memoryArea.Update(action) self.paText = 'out' Global.Time.AddSeconds(action.duration) self.intelligence.spaceMap.StepUpdate(action) ## One step in agent life. # # 1. get atomic action from ActionSelector # 2. executes atomic action # 3. perceive visible objects around # 4. updates PerceptionField, MemoryArea # 5. updates ProcessArea via call to ActionSelector.ActionDone() # 6. updates SpaceMap def Step(self): action = self.intelligence.GetAction() map = Global.Map self.x = self.newX self.y = self.newY self.viewCones = self.viewConesNormal #fake else-than-Explore/LookForObject-action branch self.viewConeMaxDist = self.viewConeNormalMaxDist #execute action - world/agent-impacting part of atomic process if action.process.name == "ExecuteReal": action.sources = action.parent.parent.process.sources Global.Log("AGENT is doing " + action.data['process'].name + " for " + str(action.duration) + " seconds") self.intelligence.UseObjects(action.parent.parent) #map.UseObjects(self, action.parent) done in PF.UseObjects elif action.process.name == "Execute": pass #never happen - done as ExecuteReal or MoveTo(Partial) elif action.process.name == "SearchRandom": pass #never happens - done as MoveTo or Explore child process elif action.process.name == "LookUpInMemory": pass #never happens - done as Remember, MoveTo or LookForObject child process elif action.process.name == "Remember": action.duration = Global.Randint(1, 10) action.data["phantom"] = self.intelligence.RememberObjectsFor( action.data["affordance"]) if action.data["phantom"] != None: Global.Log("AGENT is remembering for " + action.data["affordance"].name + "(there should be " + action.data["phantom"].object.type.name + " at " + str(action.data["phantom"].object.x) + "," + str(action.data["phantom"].object.y) + ") for " + str(action.duration) + " seconds") else: Global.Log("AGENT is remembering for " + action.data["affordance"].name + "(nothing in SM/MA) for " + str(action.duration) + " seconds") elif action.process.name == "LookForObject": self.viewCones = self.viewConesForExplore self.viewConeMaxDist = self.viewConeForExploreMaxDist action.duration = Global.Randint(1, 5) action.data["object"] = self.intelligence.LookForObject( action.data["phantom"]) if action.data["object"] != None: Global.Log("AGENT is looking for " + action.data["phantom"].object.type.name + "(Found) for " + str(action.duration) + " seconds") else: Global.Log("AGENT is looking for " + action.data["phantom"].object.type.name + "(NotFound) for " + str(action.duration) + " seconds") elif action.process.name == "MoveTo": pass #never happens - done as MoveToPartial elif action.process.name == "MoveToPartial": dx = action.data['newx'] - self.newX dy = action.data['newy'] - self.newY angle = atan2(dx, dy) self.dirAngle = angle action.duration = map.MoveAgent(self, action.data['newx'], action.data['newy']) self.intelligence.UpdatePhantomsBecauseOfMove() Global.Log("AGENT is moving to " + str(action.data['newx']) + "," + str(action.data['newy']) + " for " + str(action.duration) + " seconds") elif action.process.name == "Explore": self.viewCones = self.viewConesForExplore self.viewConeMaxDist = self.viewConeForExploreMaxDist action.duration = Global.Randint(5, 20) action.sources = [action.data['affordance']] Global.Log("AGENT is exploring for " + action.data['affordance'].name + " for " + str(action.duration) + " seconds") else: Global.Log("AGENT is a bit CONFUSED doing " + action.process.name) #sees object around visibleObjects = map.GetVisibleObjects(self) self.intelligence.NoticeObjects(visibleObjects, action) self.intelligence.perceptionField.Update(action) self.intelligence.memoryArea.Update(action) self.paText = self.intelligence.processArea.GetText() Global.Time.AddSeconds(action.duration) self.intelligence.ActionDone() self.intelligence.spaceMap.StepUpdate(action) def ToString(self): return "Agent" ## Returns agent's history as was saved by EpisodicMemory. def TellTheStory(self, txt): self.intelligence.TellTheStory(txt)
class Control: level_position = 0 # position à la gauche du niveau à afficher. Lie à la position du joueur : aide d'écriture. drawn = [] # Liste des éléments du niveau affiché (pour affacage ultèrieur) doing = 1 # renseigne sur l'occupation du mario ## Variables renseignant sur les modules actifs ## active_ia = 0 # ia active en ce moment (= pause) ia_set = False learning_set = False prolog_set = False ## Variables renseignant sur l'etat du jeu ## dead = 0 victory = 0 ## Historique ## last_position =[0,0] last_action = 'walk' ## niveau courant ## level = 0 def __init__(self,parent): self.parent = parent self.initialize() ############################################################################################################################ # Initialise les données : ############################################################################################################################ def initialize(self): self.data = Data(self.parent) self.window = Window(self.parent) self.intelligence = Intelligence(self.parent) ## Initialisation des variables ## self.data.set_control(self) # Définition de l'afficheur du niveau self.window.set_control(self) self.intelligence.set_control(self) self.data.set_window(self.window) self.data.set_level(self.level) self.intelligence.set_data(self.data) ## Zone de jeu ## self.game_window = self.window.get_window() ## Image de fond ## self.background_img = Image.open("./fond.jpg") self.background_img = self.background_img.resize((2000,1200),Image.ANTIALIAS) self.background_img = ImageTk.PhotoImage(self.background_img) self.background = self.game_window.create_image(0,0,image = self.background_img) self.game_window.create_image(0, 0, image = self.background_img) ## Image du personnage ## self.perso_img = Image.open("./yoshi.gif") # Image du personnage self.perso_img_sym = Image.open("./yoshi_sym.gif") # Image du personnage perso_width = PERSO_WIDTH # Taille du personnage perso_height = PERSO_HEIGHT self.perso_img = ImageTk.PhotoImage(self.perso_img) # Création d'images utilisables par le Canvas self.perso_img_sym = ImageTk.PhotoImage(self.perso_img_sym) # Idem symétrique self.mario = self.game_window.create_image(self.data.player_pos[0],self.data.player_pos[1], image = self.perso_img) # Mise en place de l'image self.mario_sym = self.game_window.create_image(-50,-50, image = self.perso_img_sym) # Idem symétrique self.level_position = self.data.player_pos[0] -GAME_WIDTH*0.2 # positionnement initial du niveau ## Image du sol ## self.ground_img = Image.open("./ground.gif") self.ground_img = self.ground_img.resize((50,50)) self.ground_img = ImageTk.PhotoImage(self.ground_img) ## Image des passerelles ## self.passerelle_img = Image.open("./passerelle.gif") self.passerelle_img = self.passerelle_img.resize((50,10)) self.passerelle_img = ImageTk.PhotoImage(self.passerelle_img) self.draw(self.data) # Affichage du niveau dans la zone self.doing = 0 # Mario occupé à l'état initial self.game_window.mainloop() ############################################################################################################################ # Methodes d'appel de deplacement IA ############################################################################################################################ ## Demande d'action de l'ia ## def action(self, action): # Mise a jour de l'historique self.last_position = [self.data.player_pos[0],self.data.player_pos[1]] self.last_action = action if self.doing == 0: # Si le mario est libre self.doing = 1 if action == 'walk': self.data.walk() elif action == 'jump': self.data.jump() elif action == 'spin': self.data.back() elif action == 'forward': self.data.forward() elif action == 'back': self.data.back() else: print ("erreur de commande d'action") ## Demande d'action de l'utilisateur ## def ordered(self, action): self.intelligence.learning() self.action(action) ############################################################################################################################ # Appel du moteur de résolution Prolog ############################################################################################################################ ## Demande d'action au moteur Prolog ## def forbid(self, envs, action): print envs formated_environnement = "" # Mise en forme de la demande # Ajout des éléments a la demande for env in envs[0]: formated_environnement = formated_environnement + "["+env[0]+","+str(env[1])+","+str(env[2])+","+str(env[3])+"]," interdiction = "interdit(" + formated_environnement+action+")" prolog.assertz(interdiction) # assertion proprement dite self.window.update_assertz(interdiction) ## Demande si une action est autorisée ## def is_forbidden(self, envs): formated_environnement = "" # Mise en forme de la demande # Ajout des éléments a la demande # for env in envs: formated_environnement = formated_environnement + "["+env[0]+","+str(env[1])+","+str(env[2])+","+str(env[3])+"]," formated_environnement = "interdit("+formated_environnement+"Action)" result = list(prolog.query(formated_environnement)) formatted_res = [] # Mise en forme du resultat # Ajout des éléments au resultat for el in result: formatted_res.append(el['Action']) return formatted_res ## Renvoie le resultat d'une action. ## def result(self): # historique # action = self.last_action position = self.last_position # IA exceptionnelle if self.prolog_set: if (self.dead == 1): self.forbid(self.intelligence.situation_probabilities[self.intelligence.last_index],action) # IA didactique if self.learning_set: ## cas du saut ## if (self.intelligence.last_action == 'jump'): if (self.data.player_pos[1] > self.last_position[1]): self.intelligence.remember('success') elif (self.data.player_pos[0] > self.last_position[0]): self.intelligence.remember('neutral') else: self.intelligence.remember('failure') ## Marche ## elif (self.intelligence.last_action == 'walk'): if (self.data.player_pos[0] > self.last_position[0]): self.intelligence.remember('success') else: self.intelligence.remember('failure') ## IA decisionnelle : action suivante a effectuer ? ## # Les temps permettent de s'assurer que l'action précedente est terminee if self.active_ia == 1: if self.last_action == 'walk': self.window.after(20,self.intelligence.learning) else: self.window.after(100,self.intelligence.learning) ############################################################################################################################ # Activation des modules d'IA ############################################################################################################################ ## Active l'intelligence artificielle decisionnelle ## def swap_ia(self): self.ia_set = not(self.ia_set) if not(self.ia_set): self.active_ia = 0 else: self.active_ia = 1 self.intelligence.learning() # demarrage des decisions ## Active l'intelligence artificielle didactique ## def swap_learning(self): self.learning_set = not(self.learning_set) ## Active l'intelligence artificielle exceptionnelle ## def swap_prolog(self): self.prolog_set = not(self.prolog_set) ############################################################################################################################ # Affichage du jeu dans le canvas de la fenetre ############################################################################################################################ ## Affichage du niveau sur la zone ## def draw(self,Data): nb = 0 for traced in self.drawn: self.game_window.delete(traced) offset = self.level_position # Position de l'affichage dans le niveau beginning = self.data.get_index(offset) # Premier element graphique a afficher end = self.data.get_end_index(offset+GAME_WIDTH) # fin de la zone : dernier indice à afficher last_ground_X_Y = [0,600] # etat initial : homogeneisation etat = beginning while(etat<=end): if (Data.sol[etat][0] == 0): ## Deprecated : affichage simple (plus rapide) ## #print ("sol cree : "),Data.sol[etat][1], Data.sol[etat][2], Data.sol[etat][3] #self.drawn.append(self.game_window.create_line(Data.sol[etat][1]-offset, GAME_HEIGHT - Data.sol[etat][3], Data.sol[etat][2]-offset, GAME_HEIGHT - Data.sol[etat][3],width=5,fill='black')) # Affichage des composantes horizontales #self.drawn.append(self.game_window.create_line(Data.sol[etat][1]-offset, GAME_HEIGHT - Data.sol[etat][3], last_ground_X_Y[0]-offset, GAME_HEIGHT - last_ground_X_Y[1] ,width=5,fill='black')) # Affichage des composantes verticales ## affichage des textures de sol ## while nb * 50 < Data.sol[etat][2] - Data.sol[etat][1]: self.drawn.append(self.game_window.create_image(Data.sol[etat][1]-offset + 25 + nb*50, GAME_HEIGHT - Data.sol[etat][3] + 25, image = self.ground_img,)) nb = nb + 1 nb = 0 last_ground_X_Y = [Data.sol[etat][2],Data.sol[etat][3]] # Historique de l'élement crée # Texture de passerelle if(Data.sol[etat][0] == 2): ## Deprecated : affichage simple (plus rapide) ## #self.drawn.append(self.game_window.create_line(Data.sol[etat][1]-offset, GAME_HEIGHT - Data.sol[etat][3], Data.sol[etat][2]-offset, GAME_HEIGHT - Data.sol[etat][3],width=5,fill='red')) # Affichage des composantes horizontales ## affichage des textures de passerelle ## while nb * 50 < Data.sol[etat][2] - Data.sol[etat][1]: self.drawn.append(self.game_window.create_image(Data.sol[etat][1]-offset + 25 + nb*50, GAME_HEIGHT - Data.sol[etat][3] + 5, image = self.passerelle_img,)) nb = nb + 1 nb = 0 ## Deprecated : affichage simple (plus rapide) des vides ## #if(Data.sol[etat][0] == 1): ##self.drawn.append(self.game_window.create_line(Data.sol[etat][1]-offset, GAME_HEIGHT, last_ground_X_Y[0]-offset, GAME_HEIGHT - last_ground_X_Y[1] ,width=5,fill='black')) # Affichage des composantes verticales ##last_ground_X_Y = [Data.sol[etat][2],0] etat=etat+1 ## Repositionnement des éléments du niveau suite au deplacement ## def update(self): if (self.data.player_pos[0] - self.level_position > GAME_WIDTH*0.8): # Place le niveau autour du personnage : Il ne doit pas etre trop en avant (Droite) self.level_position = self.data.player_pos[0] - GAME_WIDTH*0.8 # Positionnement des éléments du niveau # while (self.drawn != []) : # Tant que tout l'ancient niveau n'a pas ete effacé self.game_window.delete(self.drawn.pop()) # Effacement des zones tracées du niveau self.draw(self.data) # Retracage correcte du niveu if (self.data.player_pos[0] - self.level_position < GAME_WIDTH*0.2): # Place le niveau autour du personnage : Il ne doit pas etre trop en arrière (Gauche) self.level_position = self.data.player_pos[0] - GAME_WIDTH*0.2 # Positionnement des éléments du niveau # while (self.drawn != []) : # Tant que tout l'ancient niveau n'a pas ete effacé self.game_window.delete(self.drawn.pop()) # Effacement des zones tracées du niveau self.draw(self.data) # Retracage correcte du niveu # Positionnement du personnage # if (self.data.player_direction > 0): # S'il avance self.game_window.coords(self.mario,self.data.player_pos[0]-self.level_position, GAME_HEIGHT - self.data.player_pos[1] - PERSO_HEIGHT/2) # Affichage de l'image normale self.game_window.coords(self.mario_sym,-40,-40) else: # S'il recule self.game_window.coords(self.mario_sym,self.data.player_pos[0]-self.level_position, GAME_HEIGHT - self.data.player_pos[1] - PERSO_HEIGHT/2) # Affichage de l'image symétrique self.game_window.coords(self.mario,-40,-40) ############################################################################################################################ # Fonctions tests d'affichage ############################################################################################################################ # test de Positionnement du personnage # def print_pos(self): print ("position :" + str(self.data.player_pos[0]) + ", " + str(self.data.player_pos[1])) # Deprecated : fonction test # def test(self, *args): print "entrée fonction test : " # actualisation de l'affichage des situations # def update_data(self): self.window.update_data() ############################################################################################################################ # méthodes générales ############################################################################################################################ ## Victoire du niveau ## def set_victory(self): # Stage complete # Pause self.doing = 1 self.victory = 1. self.active_ia = 0 # affichage victoire self.drawn.append(self.window.pop_text("victoire")) # Pise en compte par l'IA # self.intelligence.debrief('success') self.window.after(2000,self.restart) ## Echec du niveau ## def game_over(self): # Pause self.doing = 1 self.dead = 1 self.active_ia = 0 # affichage victoire self.drawn.append(self.window.pop_text("Game Over")) # Pise en compte par l'IA # self.intelligence.debrief('failure', 5) self.window.after(2000,self.restart) ## Redemarrage standard ## def restart(self): # Reinitialisation # self.dead = 0 self.victory = 0 self.data = Data(self.parent) self.data.set_window(self.window) self.data.set_control(self) self.data.set_level(self.level) self.level_position = self.data.player_pos[0] -GAME_WIDTH*0.2 # positionnement initial du niveau self.data = Data(self.parent) self.data.set_window(self.window) self.data.set_control(self) self.data.set_level(self.level) self.level_position = self.data.player_pos[0] -GAME_WIDTH*0.2 # positionnement initial du niveau self.intelligence.set_data(self.data) self.intelligence.archive = [] # Reaffichage # self.draw(self.data) self.update() # Rechargement des modules IA # if self.ia_set == True: self.active_ia = 1 # Fin de la pause # self.doing = 0 # Redemarrage : marche pour activer le cycle de mouvement# self.data.walk()