Browse Source

Refactor knight.py and main.py

master
Matteo Benedetto 2 years ago
parent
commit
34a22a054a
  1. BIN
      Units/__pycache__/knight.cpython-311.pyc
  2. 70
      Units/knight.py
  3. 54
      main.py
  4. 1
      solver.py

BIN
Units/__pycache__/knight.cpython-311.pyc

Binary file not shown.

70
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
return gif, screen_x, screen_y
def move_to(self, target):
self.target = target
self.state = "Walk"

54
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)

1
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()
Loading…
Cancel
Save