diff --git a/Units/__pycache__/knight.cpython-311.pyc b/Units/__pycache__/knight.cpython-311.pyc index 68c4f91..b4b4b08 100644 Binary files a/Units/__pycache__/knight.cpython-311.pyc and b/Units/__pycache__/knight.cpython-311.pyc differ diff --git a/Units/knight.py b/Units/knight.py index d018eb9..a45491d 100644 --- a/Units/knight.py +++ b/Units/knight.py @@ -21,6 +21,11 @@ class Knight: self.direction = 2 self.visited = [self.position] self.starting_position = (position) + self.already_tried = [] + + def move(self, target): + pass + def ai(self): screen_x, screen_y = self.engine.iso_transform(*self.position) @@ -33,66 +38,15 @@ class Knight: screen_y += (screen_y_dest - screen_y) * self.partial_move else: screen_x, screen_y = self.engine.iso_transform(*self.destination) - neighbors_list = self.engine.find_neighbors(self.destination) # Get the neighbors of the destination cell - # Remove any neighbors that are not walkable neighbors_list = [cell for cell in neighbors_list if self.engine.battlefield[cell[1]][cell[0]].walkable] - - old_distance_from_target = self.engine.get_distance(self.destination,self.target) - old_distance_from_start = self.engine.get_distance(self.destination,self.starting_position) - - for cell_visited in self.visited: - if cell_visited in neighbors_list: - neighbors_list.remove(cell_visited) - - #self.visited = self.visited[-2:] + # Update position and visited list self.position = self.destination + self.destination = None self.visited.append(self.position) - - for cell in neighbors_list: - self.engine.effects.append(OrderClick(self.engine.iso_transform(*cell),color="lightblue")) - for cell in self.visited: - self.engine.effects.append(OrderClick(self.engine.iso_transform(*cell),color="red")) - - if not neighbors_list: - print("No neighbors") - #neighbors_list.append(self.visited) - #self.target = self.position - self.destination = None - - else: - self.destination = self.engine.get_closest_neighbor(neighbors_list,self.target) - new_distance_from_target = self.engine.get_distance(self.destination,self.target) - new_distance_from_start = self.engine.get_distance(self.destination,self.starting_position) - if new_distance_from_target >= old_distance_from_target or new_distance_from_start < old_distance_from_start: - print(f"{time.time()} - No progress") - new_neighbors_list = [] - for neighbor in neighbors_list: - neighbor_neighbors_list = self.engine.find_neighbors(neighbor) - for neighbor_neighbor in neighbor_neighbors_list: - # consider only the neighbors of the neighbors that are walkable - if not self.engine.battlefield[neighbor_neighbor[1]][neighbor_neighbor[0]].walkable: - if neighbor_neighbor not in self.visited: - # if the neighbor of the neighbor is not walkable and has not been visited, add it to the list of visited cells - new_neighbors_list.append(neighbor) - break - # scegli uhn vicino casualmente come destinaziione - - self.destination = new_neighbors_list[random.randint(0,len(new_neighbors_list)-1)] - - if self.destination: - self.engine.effects.append(OrderClick(self.engine.iso_transform(*self.destination),color="purple")) - self.partial_move = 0 - if self.position != self.target: - self.direction = self.engine.get_direction(self.position,self.destination) - else: - print("No destination") - self.visited = [self.position] - self.destination = self.position - #self.target = self.position - self.engine.effects.append(OrderClick(self.engine.iso_transform(*self.destination),color="brown")) - + self.destination = self.engine.get_closest_neighbor(neighbors_list,self.target) + self.partial_move = 0 else: self.visited = [self.target] self.position = self.target @@ -101,4 +55,8 @@ class Knight: self.state = "Idle" self.partial_move = 1 gif = self.animation.get(f'Knight_{self.state}_dir{self.direction}.gif') - return gif, screen_x, screen_y \ No newline at end of file + return gif, screen_x, screen_y + + def move_to(self, target): + self.target = target + self.state = "Walk" diff --git a/main.py b/main.py index 48ac36c..3fa6f13 100644 --- a/main.py +++ b/main.py @@ -7,6 +7,7 @@ import json from Units.knight import Knight from Effects.order_click import OrderClick from tkinter import Menu +from collections import deque @@ -141,7 +142,40 @@ class IsometricGame: x1, y1 = position1 x2, y2 = position2 return abs(((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5) - + def get_distance_components(self, position1, position2): + x1, y1 = position1 + x2, y2 = position2 + return abs(x2 - x1), abs(y2 - y1) + #function to check if a cell is near a wall + def near_wall(self, position): + x, y = position + neighbors = self.find_neighbors(position) + for neighbor in neighbors: + if not self.battlefield[neighbor[1]][neighbor[0]].walkable: + return True + def min_steps_to_target(self, start, target): + grid = [[0 for _ in range(self.width)] for _ in range(self.height)] + rows, cols = len(grid), len(grid[0]) + dx = [0, 1, 0, -1] + dy = [1, 0, -1, 0] + queue = deque([start]) + visited = set([start]) + + steps = 0 + while queue: + for _ in range(len(queue)): + x, y = queue.popleft() + if (x, y) == target: + return steps + + for i in range(4): + nx, ny = x + dx[i], y + dy[i] + if 0 <= nx < rows and 0 <= ny < cols and (nx, ny) not in visited: + queue.append((nx, ny)) + visited.add((nx, ny)) + steps += 1 + + return -1 def draw_battlefield(self): self.canvas.delete("cell") # Pulisce le celle precedenti prima di ridisegnare self.canvas.delete("cell-label") @@ -235,6 +269,7 @@ class IsometricGame: # calculate the clicked cell's coordinates cell_x, cell_y = self.inv_iso_transform(event.x, event.y) self.battlefield[cell_y][cell_x].walkable ^= True + self.battlefield[cell_y][cell_x].tile = self.tiles["landscapeTiles_067"] if self.battlefield[cell_y][cell_x].walkable else self.tiles["landscapeTiles_066"] self.draw_battlefield() self.draw_units() @@ -260,10 +295,8 @@ class IsometricGame: return if 0 <= cell_x < self.width and 0 <= cell_y < self.height: - self.knight.starting_position = self.knight.position - self.knight.target = (cell_x,cell_y) - self.knight.state = "Walk" - + self.knight.move_to((cell_x,cell_y)) + def run(self): self.draw_battlefield() self.update() @@ -288,6 +321,17 @@ class Cell: if __name__ == "__main__": with open('maze.json', 'r') as file: data = json.load(file) + # Creare una matrice 10x10 piena di False + room = [[True for _ in range(10)] for _ in range(10)] + + # Cambiare i valori interni della matrice in True + for i in range(1, 9): + for j in range(1, 8): + room[i][j] = False + + # Creare un'apertura di un'unità verso l'esterno + room[0][4] = True # Cambia questo valore per spostare l'apertura + data =room # data is a boolean matrix, find dmensions width = len(data[0]) height = len(data) diff --git a/solver.py b/solver.py index 37c1f1e..421ab77 100644 --- a/solver.py +++ b/solver.py @@ -70,5 +70,6 @@ class MazeSolver: self.window.mainloop() # Create and run the maze solver + #Breadth-First Search, BFS solver = MazeSolver('maze.json') solver.run() \ No newline at end of file