Trash Truck with BFS

This commit is contained in:
HelQ 2022-06-03 02:50:23 +02:00
commit 21b2510a4f
12 changed files with 412 additions and 0 deletions

BIN
images/grass.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
images/rock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
images/truck.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 861 B

BIN
images/truck_d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 894 B

BIN
images/truck_l.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 880 B

BIN
images/truck_u.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 897 B

BIN
images/water.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

69
main.py Normal file
View File

@ -0,0 +1,69 @@
from collections import deque
from path_algorithms.bfs import bfs
from truck import Truck
from surface import *
RESOLUTION = 900
SIZE = 60
# matrix for display
matrix = [[1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 3, 1, 2, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1],
[3, 3, 3, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]
pygame.init()
screen = pygame.display.set_mode([RESOLUTION, RESOLUTION])
truck = Truck(screen)
surface_list = []
# x and y are swapped on display in pygame
for i in range(15):
for j in range(15):
if matrix[i][j] == 1:
surface_list.append(Grass(screen, j * 60, i * 60, 1))
if matrix[i][j] == 2:
surface_list.append(Rock(screen, j * 60, i * 60, 2))
if matrix[i][j] == 3:
surface_list.append(Water(screen, j * 60, i * 60, 3))
run = 1
path = []
while True:
pygame.time.delay(500)
for i in surface_list:
i.draw_surface()
truck.draw_truck()
if run == 1:
start = truck.state
direction = truck.direction
endpoint = (0, 5)
path = bfs(surface_list, endpoint).tree_search(deque(), start, direction)
print(path)
run = 0
if path:
action = path.pop(0)
if action == 'M':
truck.move()
else:
truck.change_direction(action)
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()

112
path_algorithms/a_star.py Normal file
View File

@ -0,0 +1,112 @@
def get_path(cond):
path = []
while cond.parent:
path.append(cond.action)
cond = cond.parent
return list(reversed(path))
class bfs:
def __init__(self, surface_list, endpoint):
self.surface_list = surface_list
self.endpoint = endpoint
def goal_achieved(self, state):
return state == self.endpoint
def limitation_check(self, x, y):
for surface in self.surface_list:
if (surface.weight == 1) and (surface.y/60 == x) and (surface.x/60 == y):
return True
return False
def add_all_possibilities(self, current):
states = []
if current.direction == 'L':
# when you look left and turn left
new_condition = condition(current.state, 'D')
new_condition.action = 'L'
states.append(new_condition)
# when you turn right
new_condition = condition(current.state, 'U')
new_condition.action = 'R'
states.append(new_condition)
# when you move
if self.limitation_check(current.state[0], current.state[1] - 1):
new_condition = condition((current.state[0], current.state[1] - 1), current.direction)
new_condition.action = 'M'
states.append(new_condition)
if current.direction == 'U':
# when you look up and turn left
new_condition = condition(current.state, 'L')
new_condition.action = 'L'
states.append(new_condition)
# when you turn right
new_condition = condition(current.state, 'R')
new_condition.action = 'R'
states.append(new_condition)
# when you move
if self.limitation_check(current.state[0] - 1, current.state[1]):
new_condition = condition((current.state[0] - 1, current.state[1]), current.direction)
new_condition.action = 'M'
states.append(new_condition)
if current.direction == 'R':
# when you look right and turn left
new_condition = condition(current.state, 'U')
new_condition.action = 'L'
states.append(new_condition)
# when you turn right
new_condition = condition(current.state, 'D')
new_condition.action = 'R'
states.append(new_condition)
# when you move
if self.limitation_check(current.state[0], current.state[1] + 1):
new_condition = condition((current.state[0], current.state[1] + 1), current.direction)
new_condition.action = 'M'
states.append(new_condition)
if current.direction == 'D':
# when you look down and turn left
new_condition = condition(current.state, 'R')
new_condition.action = 'L'
states.append(new_condition)
# when you turn right
new_condition = condition(current.state, 'L')
new_condition.action = 'R'
states.append(new_condition)
# when you move
if self.limitation_check(current.state[0] + 1, current.state[1]):
new_condition = condition((current.state[0] + 1, current.state[1]), current.direction)
new_condition.action = 'M'
states.append(new_condition)
return states
def tree_search(self, queue, start, direction):
queue.append(condition(start, direction))
while queue:
elem = queue.popleft()
if self.goal_achieved(elem.state):
return get_path(elem)
for state in self.add_all_possibilities(elem):
if state not in queue:
state.parent = elem
queue.append(state)
class condition:
def __init__(self, state, direction):
self.state = state
self.parent = None
self.action = None
self.direction = direction
self.cost = 0
def __eq__(self, other):
if isinstance(other, condition):
return (self.state == other.state and
self.action == other.action and
self.direction == other.direction)

111
path_algorithms/bfs.py Normal file
View File

@ -0,0 +1,111 @@
def get_path(cond):
path = []
while cond.parent:
path.append(cond.action)
cond = cond.parent
return list(reversed(path))
class bfs:
def __init__(self, surface_list, endpoint):
self.surface_list = surface_list
self.endpoint = endpoint
def goal_achieved(self, state):
return state == self.endpoint
def limitation_check(self, x, y):
for surface in self.surface_list:
if (surface.weight == 1) and (surface.y/60 == x) and (surface.x/60 == y):
return True
return False
def add_all_possibilities(self, current):
states = []
if current.direction == 'L':
# when you look left and turn left
new_condition = condition(current.state, 'D')
new_condition.action = 'L'
states.append(new_condition)
# when you turn right
new_condition = condition(current.state, 'U')
new_condition.action = 'R'
states.append(new_condition)
# when you move
if self.limitation_check(current.state[0], current.state[1] - 1):
new_condition = condition((current.state[0], current.state[1] - 1), current.direction)
new_condition.action = 'M'
states.append(new_condition)
if current.direction == 'U':
# when you look up and turn left
new_condition = condition(current.state, 'L')
new_condition.action = 'L'
states.append(new_condition)
# when you turn right
new_condition = condition(current.state, 'R')
new_condition.action = 'R'
states.append(new_condition)
# when you move
if self.limitation_check(current.state[0] - 1, current.state[1]):
new_condition = condition((current.state[0] - 1, current.state[1]), current.direction)
new_condition.action = 'M'
states.append(new_condition)
if current.direction == 'R':
# when you look right and turn left
new_condition = condition(current.state, 'U')
new_condition.action = 'L'
states.append(new_condition)
# when you turn right
new_condition = condition(current.state, 'D')
new_condition.action = 'R'
states.append(new_condition)
# when you move
if self.limitation_check(current.state[0], current.state[1] + 1):
new_condition = condition((current.state[0], current.state[1] + 1), current.direction)
new_condition.action = 'M'
states.append(new_condition)
if current.direction == 'D':
# when you look down and turn left
new_condition = condition(current.state, 'R')
new_condition.action = 'L'
states.append(new_condition)
# when you turn right
new_condition = condition(current.state, 'L')
new_condition.action = 'R'
states.append(new_condition)
# when you move
if self.limitation_check(current.state[0] + 1, current.state[1]):
new_condition = condition((current.state[0] + 1, current.state[1]), current.direction)
new_condition.action = 'M'
states.append(new_condition)
return states
def tree_search(self, queue, start, direction):
queue.append(condition(start, direction))
while queue:
elem = queue.popleft()
if self.goal_achieved(elem.state):
return get_path(elem)
for state in self.add_all_possibilities(elem):
if state not in queue:
state.parent = elem
queue.append(state)
class condition:
def __init__(self, state, direction):
self.state = state
self.parent = None
self.action = None
self.direction = direction
def __eq__(self, other):
if isinstance(other, condition):
return (self.state == other.state and
self.action == other.action and
self.direction == other.direction)

38
surface.py Normal file
View File

@ -0,0 +1,38 @@
import pygame
class Surface:
def __init__(self, screen, x, y, weight):
self.state = (x, y)
self.x = x
self.y = y
self.weight = weight
self.screen = screen
self.image = pygame.image.load('images/grass.png')
self.surface_rect = self.image.get_rect()
self.surface_rect.center = (self.x + 30, self.y + 30)
def draw_surface(self):
self.screen.blit(self.image, self.surface_rect)
class Grass(Surface):
def __init__(self, screen, x, y, weight):
super().__init__(screen, x, y, weight)
self.image = pygame.image.load('images/grass.png')
class Rock(Surface):
def __init__(self, screen, x, y, weight):
super().__init__(screen, x, y, weight)
self.image = pygame.image.load('images/rock.png')
class Water(Surface):
def __init__(self, screen, x, y, weight):
super().__init__(screen, x, y, weight)
self.image = pygame.image.load('images/water.png')

82
truck.py Normal file
View File

@ -0,0 +1,82 @@
import pygame
class Truck:
def __init__(self, screen):
self.x = 0
self.y = 0
self.state = (self.x, self.y)
self.direction = 'R'
self.screen = screen
self.image = pygame.image.load('images/truck.png')
self.truck_rect = self.image.get_rect()
self.truck_rect.center = (self.x + 30, self.y + 30)
def draw_truck(self):
self.screen.blit(self.image, self.truck_rect)
def change_image(self):
if self.direction == 'R':
self.image = pygame.image.load('images/truck.png')
self.truck_rect = self.image.get_rect()
self.truck_rect.center = (self.x + 30, self.y + 30)
if self.direction == 'L':
self.image = pygame.image.load('images/truck_l.png')
self.truck_rect = self.image.get_rect()
self.truck_rect.center = (self.x + 30, self.y + 30)
if self.direction == 'U':
self.image = pygame.image.load('images/truck_u.png')
self.truck_rect = self.image.get_rect()
self.truck_rect.center = (self.x + 30, self.y + 30)
if self.direction == 'D':
self.image = pygame.image.load('images/truck_d.png')
self.truck_rect = self.image.get_rect()
self.truck_rect.center = (self.x + 30, self.y + 30)
def change_direction(self, turn):
if turn == 'L':
if self.direction == 'R':
self.direction = 'U'
elif self.direction == 'U':
self.direction = 'L'
elif self.direction == 'L':
self.direction = 'D'
elif self.direction == 'D':
self.direction = 'R'
if turn == 'R':
if self.direction == 'R':
self.direction = 'D'
elif self.direction == 'U':
self.direction = 'R'
elif self.direction == 'L':
self.direction = 'U'
elif self.direction == 'D':
self.direction = 'L'
self.change_image()
def move(self):
if self.direction == 'R':
self.move_right()
if self.direction == 'U':
self.move_up()
if self.direction == 'L':
self.move_left()
if self.direction == 'D':
self.move_down()
def move_right(self):
self.x += 60
self.truck_rect.center = (self.x + 30, self.y + 30)
def move_left(self):
self.x -= 60
self.truck_rect.center = (self.x + 30, self.y + 30)
def move_up(self):
self.y -= 60
self.truck_rect.center = (self.x + 30, self.y + 30)
def move_down(self):
self.y += 60
self.truck_rect.center = (self.x + 30, self.y + 30)