mirror of
https://github.com/kuhyx/WUT_Computer_Science.git
synced 2026-07-06 13:03:16 +02:00
update code to get 10/10 from pylint
This commit is contained in:
parent
6c55a51756
commit
1cdca282a4
89
main.py
89
main.py
@ -8,27 +8,26 @@ as simple as possible (but of course it does not have to). Example solution:
|
|||||||
https://angeluriot.com/maze_solver/.
|
https://angeluriot.com/maze_solver/.
|
||||||
Test multiple heuristics (at least two) h(n) and discuss the differences be-
|
Test multiple heuristics (at least two) h(n) and discuss the differences be-
|
||||||
tween the obtained results.
|
tween the obtained results.
|
||||||
"""
|
|
||||||
""" Technical requirements:
|
Technical requirements:
|
||||||
- implemented in Python.
|
- implemented in Python.
|
||||||
- adheres to basic standards of lean coding in accordance to PEP8
|
- adheres to basic standards of lean coding in accordance to PEP8
|
||||||
- comments in the crucial parts to help with readability and understanding.
|
- comments in the crucial parts to help with readability and understanding.
|
||||||
- The clear instruction how to run and test the code should be included.
|
- The clear instruction how to run and test the code should be included.
|
||||||
"""
|
|
||||||
"""
|
|
||||||
Thinks that do not work:
|
Thinks that do not work:
|
||||||
Does not work if no Start (Should print out NO START FOUND)
|
Does not work if no Start (Should print out NO START FOUND)
|
||||||
Does not work if no End (Should print out NO END FOUND)
|
Does not work if no End (Should print out NO END FOUND)
|
||||||
Does not work if no path (Should print out NO PATH FOUND)
|
Does not work if no path (Should print out NO PATH FOUND)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import heapq
|
import heapq
|
||||||
class MazeSolver:
|
|
||||||
|
|
||||||
|
|
||||||
|
class MazeSolver:
|
||||||
|
'''Maze Solver'''
|
||||||
# self corresponds to "this" in js, it refers to object of MazeSolver class
|
# self corresponds to "this" in js, it refers to object of MazeSolver class
|
||||||
|
|
||||||
def __init__(self, maze):
|
def __init__(self, maze):
|
||||||
# assign readed maze 2D array to parameter from class MazeSolver
|
# assign readed maze 2D array to parameter from class MazeSolver
|
||||||
self.maze = maze
|
self.maze = maze
|
||||||
@ -38,16 +37,19 @@ class MazeSolver:
|
|||||||
# Start/End character
|
# Start/End character
|
||||||
|
|
||||||
def find_start_and_end(self):
|
def find_start_and_end(self):
|
||||||
|
'''Finds start and end points in the maze'''
|
||||||
start = end = None
|
start = end = None
|
||||||
for row in range(len(self.maze)):
|
|
||||||
for col in range(len(self.maze[row])):
|
for row_i, row in enumerate(self.maze):
|
||||||
if self.maze[row][col] == 'S':
|
for col_i, cell in enumerate(row):
|
||||||
start = (row, col)
|
if cell == 'S':
|
||||||
elif self.maze[row][col] == 'E':
|
start = (row_i, col_i)
|
||||||
end = (row, col)
|
elif cell == 'E':
|
||||||
|
end = (row_i, col_i)
|
||||||
if start is not None and end is not None:
|
if start is not None and end is not None:
|
||||||
return start, end
|
return start, end
|
||||||
print(f"DID NOT FOUND START OR END, Start: {start}, End: {end}")
|
print(f"DID NOT FOUND START OR END, Start: {start}, End: {end}")
|
||||||
|
return start, end
|
||||||
|
|
||||||
# Go through each neighboor
|
# Go through each neighboor
|
||||||
# N
|
# N
|
||||||
@ -56,6 +58,7 @@ class MazeSolver:
|
|||||||
# If it is not a "wall" (#) add its position to list of neighbors
|
# If it is not a "wall" (#) add its position to list of neighbors
|
||||||
|
|
||||||
def get_neighbors(self, position):
|
def get_neighbors(self, position):
|
||||||
|
'''Finds point's neighbours'''
|
||||||
row, col = position
|
row, col = position
|
||||||
neighbors = []
|
neighbors = []
|
||||||
if row > 0 and self.maze[row - 1][col] != '#':
|
if row > 0 and self.maze[row - 1][col] != '#':
|
||||||
@ -71,6 +74,7 @@ class MazeSolver:
|
|||||||
# find path through maze
|
# find path through maze
|
||||||
|
|
||||||
def solve(self):
|
def solve(self):
|
||||||
|
'''Solves the maze'''
|
||||||
queue = []
|
queue = []
|
||||||
# set means that values inside can not repeat
|
# set means that values inside can not repeat
|
||||||
visited = set()
|
visited = set()
|
||||||
@ -79,15 +83,17 @@ class MazeSolver:
|
|||||||
# we use heapq so the element with lowest heurisitc value will always
|
# we use heapq so the element with lowest heurisitc value will always
|
||||||
# be at the top of heap
|
# be at the top of heap
|
||||||
heapq.heappush(
|
heapq.heappush(
|
||||||
queue, (self.heuristicEuclidean(
|
queue, (self.heuristic_euclidean(
|
||||||
self.start), self.start, [
|
self.start), self.start, [
|
||||||
self.start]))
|
self.start]))
|
||||||
|
|
||||||
# go through queue until it's empty
|
# Go through queue until it's empty
|
||||||
# find neighbour (which is not wall) closests to END point (based on heuristic)
|
# Find neighbour (which is not wall) closests to the
|
||||||
# go there and repeat
|
# END point (based on heuristic)
|
||||||
|
# Go there and repeat
|
||||||
# if cannot find path it starts over but skips the path that lead it to
|
# if cannot find path it starts over but skips the path that lead it to
|
||||||
# dead end
|
# dead end
|
||||||
|
path = None
|
||||||
while queue:
|
while queue:
|
||||||
# pop first element of heap
|
# pop first element of heap
|
||||||
# first value is skipped and we only save current position and path
|
# first value is skipped and we only save current position and path
|
||||||
@ -96,61 +102,68 @@ class MazeSolver:
|
|||||||
# if we already visited current skip code and go to next iteration
|
# if we already visited current skip code and go to next iteration
|
||||||
if current in visited:
|
if current in visited:
|
||||||
continue
|
continue
|
||||||
# if we found the end return path
|
# if we found the end return path
|
||||||
if current == self.end:
|
if current == self.end:
|
||||||
return path
|
break
|
||||||
visited.add(current)
|
visited.add(current)
|
||||||
for neighbor in self.get_neighbors(current):
|
for neighbor in self.get_neighbors(current):
|
||||||
if neighbor not in visited:
|
if neighbor not in visited:
|
||||||
new_path = path + [neighbor]
|
new_path = path + [neighbor]
|
||||||
heapq.heappush(
|
heapq.heappush(
|
||||||
queue, (self.heuristicEuclidean(neighbor), neighbor, new_path))
|
queue, (self.heuristic_euclidean(neighbor), neighbor, new_path))
|
||||||
print_maze(self.maze, new_path)
|
print_maze(self.maze, new_path)
|
||||||
print()
|
print()
|
||||||
|
return path
|
||||||
|
|
||||||
# This heuristic returns the Manhatan distance between the given position
|
# This heuristic returns the Manhatan distance between the given position
|
||||||
# and the maze's end
|
# and the maze's end
|
||||||
def heuristicManhatan(self, position):
|
def heuristic_manhatan(self, position):
|
||||||
|
'''Heuristic function that uses Manhatan distance'''
|
||||||
return abs(position[0] - self.end[0]) + abs(position[1] - self.end[1])
|
return abs(position[0] - self.end[0]) + abs(position[1] - self.end[1])
|
||||||
|
|
||||||
# This heuristic returns the Euclidean distance between the given position
|
# This heuristic returns the Euclidean distance between the given position
|
||||||
# and the maze's end
|
# and the maze's end
|
||||||
def heuristicEuclidean(self, position):
|
def heuristic_euclidean(self, position):
|
||||||
|
'''Heuristic function that uses Euclidean distance'''
|
||||||
return (abs(position[0] - self.end[0])**2 +
|
return (abs(position[0] - self.end[0])**2 +
|
||||||
abs(position[1] - self.end[1])**2)**0.5
|
abs(position[1] - self.end[1])**2)**0.5
|
||||||
|
|
||||||
|
|
||||||
# Open and load text file to array
|
# Open and load text file to array
|
||||||
def load_maze(filename):
|
def load_maze(filename):
|
||||||
|
'''Loads a maze from the specified file'''
|
||||||
# Open for reading only and save to fileContents
|
# Open for reading only and save to fileContents
|
||||||
fileContents = open(filename, 'r')
|
with open(filename, 'r', encoding='utf8') as file_contents:
|
||||||
# strip() removes extra white spaces from the beginning and the end of a string
|
# strip() removes extra white spaces from the beginning and the end of
|
||||||
# list() changes string to array of chars
|
# a string
|
||||||
# Inside of square brackets we will have an array of characters for each line of file
|
# list() changes string to array of chars
|
||||||
# after going through every line in a file we will have 2D array of arrays
|
# Inside of square brackets we will have an array of characters for
|
||||||
# of characters of every line
|
# each line of file
|
||||||
maze = [list(line.strip()) for line in fileContents]
|
# After going through every line in a file we will have 2D array of arrays
|
||||||
|
# of characters of every line
|
||||||
|
maze = [list(line.strip()) for line in file_contents]
|
||||||
return maze
|
return maze
|
||||||
|
|
||||||
|
|
||||||
def print_maze(maze, path=None):
|
def print_maze(maze, path=None):
|
||||||
|
'''Prints the maze'''
|
||||||
if path is None:
|
if path is None:
|
||||||
path = []
|
path = []
|
||||||
for row in range(len(maze)):
|
for row_i, row in enumerate(maze):
|
||||||
for col in range(len(maze[row])):
|
for col_i, cell in enumerate(row):
|
||||||
if (row, col) in path:
|
if (row_i, col_i) in path:
|
||||||
print('*', end='')
|
print('*', end='')
|
||||||
else:
|
else:
|
||||||
print(maze[row][col], end='')
|
print(cell, end='')
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
|
||||||
# Ran first in the code
|
# Ran first in the code
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Open and load text file to array
|
# Open and load text file to array
|
||||||
maze = load_maze('mazes/mazeDeadEnd.txt')
|
loadedMaze = load_maze('mazes/mazeDeadEnd.txt')
|
||||||
# Initialize MazeSolver object with maze as paramater
|
# Initialize MazeSolver object with maze as paramater
|
||||||
solver = MazeSolver(maze)
|
solver = MazeSolver(loadedMaze)
|
||||||
# Find path using MazeSolver solve method
|
# Find path using MazeSolver solve method
|
||||||
path = solver.solve()
|
solvedPath = solver.solve()
|
||||||
print_maze(maze, path)
|
print_maze(loadedMaze, solvedPath)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user