def esploratore(path,Nlim): command = mazeClient.Commands caselle_fatte = [] caselle_chiuse = [] # lista nera delle caselle k = 0 # ripetizione caselle fatte res = json.loads(mazeClient.send_command(command.MOVE_DOWN)) # inizializzo per avere il primo stato # x posizione attuale, x_p posizione precedente, x_s la successiva flag = 0 while(k<Nlim): # a tot caselle ripetute considero il labirinto esplorato x = [res['userX'],res['userY']] # sleep(0.3) print('-'*24) print(f'** posizione attuale: {x}') vicini = [] for i in res['Neighbors']: # elimino gli spostamenti impossibili ==> lista vicini x_s = [i['x'],i['y']] action = Assegnatrice_Comando(*x,*x_s,command) if(action): print('Ok, possibile') vicini.append([*x_s,i['val'],action]) else: print('rifiutato') random.shuffle(vicini) # per evitare loop (es 4 caselle) # controllo se ci sono caselle nuove for i in vicini: if [i[0],i[1],i[2]] not in caselle_fatte: print('Nuova casella!') action = i[3] caselle_fatte.append([i[0],i[1],i[2]]) flag = 1 k = 0 break # se non ci sono, controllo quindi se posso tornare su una vecchia che non sia nella lista chiusa o quella da dove vengo if(flag == 0): for i in vicini: if x_p != [i[0],i[1]] and [i[0],i[1]] not in caselle_chiuse: action = i[3] k = k+1 flag = 1 break # se non ci sono, torno quella da dove venivo e inserisco nella lista di caselle chiuse quella attuale if(flag == 0): print('Casella cieca') x_s = x_p caselle_chiuse.append([*x]) idx = [[row[0],row[1]] for row in vicini].index(x_s) action = vicini[idx][3] k = k+1 print(f'Movimento {x} ==> {x_s}') res = movimento(action,command) flag = 0 x_p = x mazeClient.send_command(command.EXIT) # Salvo il file with open(path,"w") as file_: file_.write(f'x;y;colore\n') for i in caselle_fatte: file_.write(f'{i[0]};{i[1]};{i[2]}\n') return caselle_fatte
def confronto(): bfs_search() mazeClient.send_command(command.EXIT) controls.del_seed() controls.open_maze() sleep(0.5) bfs_search(confronto=True) mazeClient.send_command(command.EXIT) plot_stats(confronto=True) # Stampa i grafici
def movimento(cella_attuale: Cella, vicini: list) -> bool: for neigh in vicini: # Controlla se c'è un vicino non visitato trovato = False for cell in visitate: if (neigh['x'] == cell.x and neigh['y'] == cell.y): trovato = True #---------------------------------------# if not trovato: if cella_attuale.y < neigh['y'] and cella_attuale.x == neigh['x']: mazeClient.send_command(command.MOVE_LEFT) cammino.append((command.MOVE_LEFT, command.MOVE_RIGHT)) elif cella_attuale.y > neigh['y'] and cella_attuale.x == neigh['x']: mazeClient.send_command(command.MOVE_RIGHT) cammino.append((command.MOVE_RIGHT, command.MOVE_LEFT)) elif cella_attuale.y == neigh['y'] and cella_attuale.x < neigh['x']: mazeClient.send_command(command.MOVE_UP) cammino.append((command.MOVE_UP, command.MOVE_DOWN)) elif cella_attuale.y == neigh['y'] and cella_attuale.x > neigh['x']: mazeClient.send_command(command.MOVE_DOWN) cammino.append((command.MOVE_DOWN, command.MOVE_UP)) return True # Si è mosso return False # Non ha trovato vicini validi, inizio traceback
def exploration(command): explored_maze = [] exit = False getch = G._Getch() while not exit: res = mazeClient.send_command(command.GET_STATE) pos = json.loads(res) print(pos) elm = {} elm["x"] = pos["userX"] elm["y"] = pos["userY"] elm["val"] = pos["userVal"] if is_in_maze(explored_maze, elm) == False: explored_maze.append(elm) for block in pos["Neighbors"]: if is_in_maze(explored_maze, block) == False: explored_maze.append(block) os.system("clear") print("") print_map(explored_maze, elm) print("") values = get_stats(explored_maze) print("Total: " + str(values["total"]) + ", red: " + str(values["red"]) + ", green: " + str(values["green"]) + ", blue: " + str(values["blue"]) + ", white: " + str(values["white"])) filter_neighbors(pos["Neighbors"], elm) print( "Select option:\nW) Up\nS) Down\nR) Right\nA) Left\nE) Exit\nP) Plot stats\n" ) sel = getch() if sel == "w" or sel == "W": mazeClient.send_command(command.MOVE_UP) elif sel == "s" or sel == "S": mazeClient.send_command(command.MOVE_DOWN) elif sel == "d" or sel == "D": mazeClient.send_command(command.MOVE_RIGHT) elif sel == "a" or sel == "A": mazeClient.send_command(command.MOVE_LEFT) elif sel == "e" or sel == "E": exit = True elif sel == "p" or sel == "P": frequency_distribution(explored_maze) else: print("Invalid")
def move(input: str) -> str: option = { "H": command.MOVE_UP, "P": command.MOVE_DOWN, "M": command.MOVE_RIGHT, "K": command.MOVE_LEFT } return mazeClient.send_command(option[input])
def exploration(command): explored_maze = [] _exit = False getch = G._Getch() while not _exit: res = mazeClient.send_command(command.GET_STATE) pos = json.loads(res) print(pos) elm = { 'x': pos["userX"], 'y': pos["userY"], 'val': pos["userVal"] } if is_in_maze(explored_maze, elm) is False: explored_maze.append(elm) for block in pos["Neighbors"]: if is_in_maze(explored_maze, block) is False: explored_maze.append(block) os.system("clear") print() print_map(explored_maze, elm) print() values = get_stats(explored_maze) print("Total: " + str(values["total"]) + ", red: " + str(values["red"]) + ", green: " + str( values["green"]) + ", blue: " + str(values["blue"]) + ", white: " + str(values["white"])) filter_neighbors(pos["Neighbors"], elm) print("Select option:\nW) Up\nS) Down\nR) Right\nA) Left\nE) Exit\nP) Plot stats\n") sel = getch() if sel in ["w", "W"]: mazeClient.send_command(command.MOVE_UP) elif sel in ["s", "S"]: mazeClient.send_command(command.MOVE_DOWN) elif sel in ["d", "D"]: mazeClient.send_command(command.MOVE_RIGHT) elif sel in ["a", "A"]: mazeClient.send_command(command.MOVE_LEFT) elif sel in ["e", "E"]: _exit = True elif sel in ["p", "P"]: frequency_distribution(explored_maze) else: print("Invalid")
def dfs_visit(self, v: dict, last_cmd: str): """ DFS Algorithm to explore the maze """ for u in self.get_reachable_neighbors(v): if u not in self.visited: # Visit the neighbor self.visit_node(u) # Move to neighbor cmd = self.get_command_from_pos(v, u) u = self.get_dict(send_command(cmd)) #sleep(0.5) # Visit from that neighbor self.dfs_visit(u, cmd) # Move back, no more valid neighbors send_command(self.get_inverse_command(last_cmd))
def bfs_search(confronto=False): inizio = True while len(cammino) != 0 or inizio: inizio = False obj_cell = json.loads(mazeClient.send_command(command.GET_STATE)) cell_attuale = Cella(obj_cell) # Controlla se la cella è già stata visitata, in caso la aggiunge alla coda visitate to_append = False for cell in visitate: if cell.x == cell_attuale.x and cell.y == cell_attuale.y: to_append = True if not to_append: visitate.append(cell_attuale) #-----------------------------------------------------------------------------------# # Se la cella non ha vicini da visitare inizia il traceback if not movimento(cell_attuale, remove_usless_neigh(cell_attuale, obj_cell['Neighbors'])): test = traceback() # Se il traceback ritorna True la cella ha vicini non visitati, quindi ricomincio ad esplorare if test: new_cell = json.loads(mazeClient.send_command(command.GET_STATE)) tmp = Cella(new_cell) # Se movimento ritorna False, non ci sono più celle da visitare if not movimento(tmp, remove_usless_neigh(tmp, new_cell['Neighbors'])): break # Creo i csv print("Esporto i dati in CSV ...") if confronto: create_csv("data2.csv") else: create_csv("data.csv") visitate.clear() cammino.clear() print("FATTO !\n")
def traceback() -> bool: while True: # Se 0 sono tornato alla cella di inizio if len(cammino) == 0: return False # Algoritmo finito cmd = cammino.pop() mazeClient.send_command(cmd[1]) me = json.loads(mazeClient.send_command(command.GET_STATE)) vicini = remove_usless_neigh(Cella(me), me['Neighbors']) for neigh in vicini: trovato = False # Controlla se c'è un vicino non visitato for cell in visitate: if (neigh['x'] == cell.x and neigh['y'] == cell.y): trovato = True if not trovato: return True # La cella dove sono tornato ha ancora vicini da visitare
def Navigatore(event): # chiamata da tastiera if event.keysym == 'Escape': root.destroy() mazeClient.send_command(command.EXIT) else: temp = event.keysym if temp == 'Up': action = command.MOVE_RIGHT elif temp == 'Right': action = command.MOVE_UP elif temp == 'Left': action = command.MOVE_DOWN elif temp == 'Down': action = command.MOVE_LEFT else: action = command.GET_STATE temp = 'Non valido' print(temp) res = json.loads(mazeClient.send_command(action)) Mappa_Colori = Assegnatrice_Colori(res, n) for i in range(n): for j in range(n): c.itemconfig(rect[i, j], fill=Mappa_Colori[i][j])
def main(): # Creazione del menu Help parser = argparse.ArgumentParser(description='Maze Navigation.') parser.add_argument( '--free_move', action='store_true', help= 'Permette di muovere il labirinto senza analizzarlo con le freccie direzionali e si può uscire dal programma digitando q.' ) parser.add_argument( '--move_map', action='store_true', help= 'Permette di muovere il labirinto dopo averlo analizzato ed avere la mappa stampata.' ) parser.add_argument( '--confront', action='store_true', help= 'Permette il confronto e la stampa sullo stesso istogramma delle frequenze dei colori RGB rispettivi agli assi di due labirinti differenti.' ) args = parser.parse_args() if len(sys.argv) > 2: print("Troppi argomenti !") return -1 # Controlla se il mazeEngine è in esecuzione, sennò lo avvia try: mazeClient.send_command(mazeClient.Commands().GET_STATE) except ConnectionRefusedError: print("Il Maze Client è chiuso... Lo apro!") controls.open_maze() sleep(0.5) if args.free_move: free_move() mazeClient.send_command(mazeClient.Commands().EXIT) return 0 if args.confront: confronto() return 0 bfs_search() plot_maze() plot_stats() if args.move_map: free_move() mazeClient.send_command(mazeClient.Commands().EXIT)
def movimento(flag: int, command): if flag == 1: action = command.MOVE_LEFT print('eseguito left') elif flag == 2: action = command.MOVE_RIGHT print('eseguito right') elif flag == 3: action = command.MOVE_DOWN print('eseguito down') elif flag == 4: action = command.MOVE_UP print('eseguito up') else: print('Errore!!!') return json.loads(mazeClient.send_command(action))
def on_press(key): """ Listen for input and move if any of 'WASD' is pressed Exit if any other key is pressed """ # Not a valid key pressed? if not hasattr(key, 'char'): return False if key.char not in keycode_map: return False # Map keycode to action and execute action action = keycode_map[key.char] res = send_command(action) # Just some print to let user have some feedback if action == command.GET_STATE: print(res) else: print(action)
def __init__(self): # Initialize variables used to collect data from maze # visited = map representation # colors_xy = distribution of colors on x,y axes # colors_count = count of each color present in the map self.visited = [] self.colors_x = {} self.colors_y = {} self.colors_count = {'red': 0, 'green': 0, 'blue': 0, 'white': 0} # Initialize map to better manage colors self.c_map = {82: 'red', 71: 'green', 66: 'blue', 32: 'white'} # Visit the root (starting position) curr_node = self.get_dict(send_command(command.GET_STATE)) self.visited.append({ 'x': curr_node['userX'], 'y': curr_node['userY'], 'val': curr_node['userVal'] }) # Explore the maze self.dfs_visit(curr_node, command.GET_STATE)
def on_press(key): """ Listen for input and move if a directional key or any of 'WASD' is pressed Exit if any other key is pressed """ key_repr = repr(key)[1:-1] if key == keyboard.Key.up or key_repr == 'w': action = command.MOVE_UP elif key == keyboard.Key.down or key_repr == 's': action = command.MOVE_DOWN elif key == keyboard.Key.left or key_repr == 'a': action = command.MOVE_LEFT elif key == keyboard.Key.right or key_repr == 'd': action = command.MOVE_RIGHT elif key_repr == 'e': action = command.GET_STATE else: return False res = send_command(action) if action == command.GET_STATE: print(res) else: print(action)
def Assegnatrice_Colori(res, n): """Funzioni per la definizione della mappa di colori""" x = [res['userX'], res['userY']] Colori = [['black', 'black', 'black'], ['black', 'black', 'black'], [ 'black', 'black', 'black']] # [['black']*n]*n Colori[1][1] = Conversione_Colori(res['userVal']) for i in res['Neighbors']: x_s = [i['x'], i['y']] temp = [-x[0]+x_s[0]+1, -x[1]+x_s[1]+1] # print({'x':temp,'c':i['val']}) Colori[temp[0]][temp[1]] = Conversione_Colori(i['val']) return Colori command = mazeClient.Commands res = json.loads(mazeClient.send_command(command.GET_STATE)) Mappa_Colori = Assegnatrice_Colori(res, 3) # Parte grafica ==> inizializzo root = tk.Tk() root.title("Maze Manuale") root.geometry('300x300') D = 300 n = 3 d = D/n rect = {} c = tk.Canvas(root, height=D, width=D) for i in range(n): for j in range(n): rect[i, j] = c.create_rectangle( i*d, j*d, (i+1)*d, (j+1)*d, fill=Mappa_Colori[i][j]) k = 0.2
def get_response(action: str) -> bytes: ''' Returns the engine response. ''' return send_command(action)